[clang] [analyzer] New optin.taint.TaintAlloc checker for catching unbounded memory allocation calls (PR #92420)

2024-06-05 Thread Daniel Krupp via cfe-commits

https://github.com/dkrupp updated 
https://github.com/llvm/llvm-project/pull/92420

>From f6fdd544a90b865e5e0e530930db87cad405216e Mon Sep 17 00:00:00 2001
From: Daniel Krupp 
Date: Tue, 30 Apr 2024 15:20:52 +0200
Subject: [PATCH 1/7] [analyzer] Adding taint analysis capability to
 unix.Malloc checker

unix.Malloc checker will warn if a memory allocation function
(malloc, calloc, realloc, alloca) is called with a tainted
(attacker controlled) size parameter.
A large, maliciously set size value can trigger memory exhaustion.
To get this warning, the alpha.security.taint.TaintPropagation checker
also needs to be switched on.

The warning will only be emitted, if the analyzer cannot prove
that the size is below reasonable bounds (https://wiki.sei.cmu.edu/confluence/display/c/INT04-C.+Enforce+limits+on+integer+values+originating+from+tainted+sources>`_.
+
+You can silence this warning either by bound checking the ``size`` parameter, 
or
+by explicitly marking the ``size`` parameter as sanitized. See the
+:ref:`alpha-security-taint-TaintPropagation` checker for more details.
+
+.. code-block:: c
+
+  void t1(void) {
+size_t size;
+scanf("%zu", );
+int *p = malloc(size); // warn: malloc is called with a tainted 
(potentially attacker controlled) value
+free(p);
+  }
+
+  void t3(void) {
+size_t size;
+scanf("%zu", );
+if (1024 BT_MismatchedDealloc;
   mutable std::unique_ptr BT_OffsetFree[CK_NumCheckKinds];
   mutable std::unique_ptr BT_UseZerroAllocated[CK_NumCheckKinds];
+  mutable std::unique_ptr BT_TaintedAlloc[CK_NumCheckKinds];
 
 #define CHECK_FN(NAME) 
\
   void NAME(const CallEvent , CheckerContext ) const;
@@ -462,6 +464,13 @@ class MallocChecker
   };
 
   bool isMemCall(const CallEvent ) const;
+  void reportTaintBug(StringRef Msg, ProgramStateRef State, CheckerContext ,
+  llvm::ArrayRef TaintedSyms,
+  AllocationFamily Family, const Expr *SizeEx) const;
+
+  void CheckTaintedness(CheckerContext , const CallEvent ,
+const SVal SizeSVal, ProgramStateRef State,
+AllocationFamily Family) const;
 
   // TODO: Remove mutable by moving the initializtaion to the registry 
function.
   mutable std::optional KernelZeroFlagVal;
@@ -521,9 +530,9 @@ class MallocChecker
   /// malloc leaves it undefined.
   /// \param [in] State The \c ProgramState right before allocation.
   /// \returns The ProgramState right after allocation.
-  [[nodiscard]] static ProgramStateRef
+  [[nodiscard]] ProgramStateRef
   MallocMemAux(CheckerContext , const CallEvent , const Expr *SizeEx,
-   SVal Init, ProgramStateRef State, AllocationFamily Family);
+   SVal Init, ProgramStateRef State, AllocationFamily Family) 
const;
 
   /// Models memory allocation.
   ///
@@ -534,9 +543,10 @@ class MallocChecker
   /// malloc leaves it undefined.
   /// \param [in] State The \c ProgramState right before allocation.
   /// \returns The ProgramState right after allocation.
-  [[nodiscard]] static ProgramStateRef
-  MallocMemAux(CheckerContext , const CallEvent , SVal Size, SVal Init,
-   ProgramStateRef State, AllocationFamily Family);
+  [[nodiscard]] ProgramStateRef MallocMemAux(CheckerContext ,
+ const CallEvent , SVal Size,
+ SVal Init, ProgramStateRef State,
+ AllocationFamily Family) const;
 
   // Check if this malloc() for special flags. At present that means M_ZERO or
   // __GFP_ZERO (in which case, treat it like calloc).
@@ -649,8 +659,9 @@ class MallocChecker
   /// \param [in] Call The expression that reallocated memory
   /// \param [in] State The \c ProgramState right before reallocation.
   /// \returns The ProgramState right after allocation.
-  [[nodiscard]] static ProgramStateRef
-  CallocMem(CheckerContext , const CallEvent , ProgramStateRef State);
+  [[nodiscard]] ProgramStateRef CallocMem(CheckerContext ,
+  const CallEvent ,
+  ProgramStateRef State) const;
 
   /// See if deallocation happens in a suspicious context. If so, escape the
   /// pointers that otherwise would have been deallocated and return true.
@@ -1779,7 +1790,7 @@ ProgramStateRef 
MallocChecker::MallocMemAux(CheckerContext ,
 const CallEvent ,
 const Expr *SizeEx, SVal Init,
 ProgramStateRef State,
-AllocationFamily Family) {
+AllocationFamily Family) const {
   if (!State)
 return nullptr;
 
@@ -1787,10 +1798,71 @@ ProgramStateRef 
MallocChecker::MallocMemAux(CheckerContext ,
   return MallocMemAux(C, Call, 

[clang] [analyzer] New optin.taint.TaintAlloc checker for catching unbounded memory allocation calls (PR #92420)

2024-06-03 Thread Donát Nagy via cfe-commits

https://github.com/NagyDonat approved this pull request.

The change LGTM. I agree with @steakhal that `TaintedAlloc` would be a slightly 
better name, but the current one is also acceptable.

https://github.com/llvm/llvm-project/pull/92420
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [analyzer] New optin.taint.TaintAlloc checker for catching unbounded memory allocation calls (PR #92420)

2024-06-03 Thread Daniel Krupp via cfe-commits

dkrupp wrote:

In the latest commit I fixed all remaining review comments.

GenericTaintchecker should be a dependency as mentioned in the FIXME, but it 
cannot be one until the checker is not a modeling checker. This separation will 
be done in a later follow-up patch. Until then, the documentation indicates the 
that alpha.security.taint.TaintPropagation checker should be switched on for 
this checker to work.


https://github.com/llvm/llvm-project/pull/92420
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [analyzer] New optin.taint.TaintAlloc checker for catching unbounded memory allocation calls (PR #92420)

2024-06-03 Thread Daniel Krupp via cfe-commits

https://github.com/dkrupp updated 
https://github.com/llvm/llvm-project/pull/92420

>From f6fdd544a90b865e5e0e530930db87cad405216e Mon Sep 17 00:00:00 2001
From: Daniel Krupp 
Date: Tue, 30 Apr 2024 15:20:52 +0200
Subject: [PATCH 1/6] [analyzer] Adding taint analysis capability to
 unix.Malloc checker

unix.Malloc checker will warn if a memory allocation function
(malloc, calloc, realloc, alloca) is called with a tainted
(attacker controlled) size parameter.
A large, maliciously set size value can trigger memory exhaustion.
To get this warning, the alpha.security.taint.TaintPropagation checker
also needs to be switched on.

The warning will only be emitted, if the analyzer cannot prove
that the size is below reasonable bounds (https://wiki.sei.cmu.edu/confluence/display/c/INT04-C.+Enforce+limits+on+integer+values+originating+from+tainted+sources>`_.
+
+You can silence this warning either by bound checking the ``size`` parameter, 
or
+by explicitly marking the ``size`` parameter as sanitized. See the
+:ref:`alpha-security-taint-TaintPropagation` checker for more details.
+
+.. code-block:: c
+
+  void t1(void) {
+size_t size;
+scanf("%zu", );
+int *p = malloc(size); // warn: malloc is called with a tainted 
(potentially attacker controlled) value
+free(p);
+  }
+
+  void t3(void) {
+size_t size;
+scanf("%zu", );
+if (1024 BT_MismatchedDealloc;
   mutable std::unique_ptr BT_OffsetFree[CK_NumCheckKinds];
   mutable std::unique_ptr BT_UseZerroAllocated[CK_NumCheckKinds];
+  mutable std::unique_ptr BT_TaintedAlloc[CK_NumCheckKinds];
 
 #define CHECK_FN(NAME) 
\
   void NAME(const CallEvent , CheckerContext ) const;
@@ -462,6 +464,13 @@ class MallocChecker
   };
 
   bool isMemCall(const CallEvent ) const;
+  void reportTaintBug(StringRef Msg, ProgramStateRef State, CheckerContext ,
+  llvm::ArrayRef TaintedSyms,
+  AllocationFamily Family, const Expr *SizeEx) const;
+
+  void CheckTaintedness(CheckerContext , const CallEvent ,
+const SVal SizeSVal, ProgramStateRef State,
+AllocationFamily Family) const;
 
   // TODO: Remove mutable by moving the initializtaion to the registry 
function.
   mutable std::optional KernelZeroFlagVal;
@@ -521,9 +530,9 @@ class MallocChecker
   /// malloc leaves it undefined.
   /// \param [in] State The \c ProgramState right before allocation.
   /// \returns The ProgramState right after allocation.
-  [[nodiscard]] static ProgramStateRef
+  [[nodiscard]] ProgramStateRef
   MallocMemAux(CheckerContext , const CallEvent , const Expr *SizeEx,
-   SVal Init, ProgramStateRef State, AllocationFamily Family);
+   SVal Init, ProgramStateRef State, AllocationFamily Family) 
const;
 
   /// Models memory allocation.
   ///
@@ -534,9 +543,10 @@ class MallocChecker
   /// malloc leaves it undefined.
   /// \param [in] State The \c ProgramState right before allocation.
   /// \returns The ProgramState right after allocation.
-  [[nodiscard]] static ProgramStateRef
-  MallocMemAux(CheckerContext , const CallEvent , SVal Size, SVal Init,
-   ProgramStateRef State, AllocationFamily Family);
+  [[nodiscard]] ProgramStateRef MallocMemAux(CheckerContext ,
+ const CallEvent , SVal Size,
+ SVal Init, ProgramStateRef State,
+ AllocationFamily Family) const;
 
   // Check if this malloc() for special flags. At present that means M_ZERO or
   // __GFP_ZERO (in which case, treat it like calloc).
@@ -649,8 +659,9 @@ class MallocChecker
   /// \param [in] Call The expression that reallocated memory
   /// \param [in] State The \c ProgramState right before reallocation.
   /// \returns The ProgramState right after allocation.
-  [[nodiscard]] static ProgramStateRef
-  CallocMem(CheckerContext , const CallEvent , ProgramStateRef State);
+  [[nodiscard]] ProgramStateRef CallocMem(CheckerContext ,
+  const CallEvent ,
+  ProgramStateRef State) const;
 
   /// See if deallocation happens in a suspicious context. If so, escape the
   /// pointers that otherwise would have been deallocated and return true.
@@ -1779,7 +1790,7 @@ ProgramStateRef 
MallocChecker::MallocMemAux(CheckerContext ,
 const CallEvent ,
 const Expr *SizeEx, SVal Init,
 ProgramStateRef State,
-AllocationFamily Family) {
+AllocationFamily Family) const {
   if (!State)
 return nullptr;
 
@@ -1787,10 +1798,71 @@ ProgramStateRef 
MallocChecker::MallocMemAux(CheckerContext ,
   return MallocMemAux(C, Call, 

[clang] [analyzer] New optin.taint.TaintAlloc checker for catching unbounded memory allocation calls (PR #92420)

2024-06-03 Thread Daniel Krupp via cfe-commits

https://github.com/dkrupp edited https://github.com/llvm/llvm-project/pull/92420
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [analyzer] New optin.taint.TaintAlloc checker for catching unbounded memory allocation calls (PR #92420)

2024-06-03 Thread Daniel Krupp via cfe-commits


@@ -1730,6 +1721,21 @@ def UnixAPIPortabilityChecker : Checker<"UnixAPI">,
 
 } // end optin.portability
 
+
+//===--===//
+// Taint checkers.
+//===--===//
+
+let ParentPackage = TaintOptIn in {
+
+def TaintMallocChecker: Checker<"TaintMalloc">,
+  HelpText<"Check for memory allocations, where the size parameter "
+   "might be a tainted (attacker controlled) value.">,
+  Dependencies<[DynamicMemoryModeling]>,

dkrupp wrote:

I added the GenerictaintChecker as a dependency too. I think it makes sense to 
add it now so that we dont forget it later.

https://github.com/llvm/llvm-project/pull/92420
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [analyzer] New optin.taint.TaintAlloc checker for catching unbounded memory allocation calls (PR #92420)

2024-05-30 Thread Balazs Benics via cfe-commits


@@ -938,6 +938,53 @@ optin.portability.UnixAPI
 "
 Finds implementation-defined behavior in UNIX/Posix functions.
 
+.. _optin-taint-TaintAlloc:
+
+optin.taint.TaintAlloc (C, C++)
+"""
+
+This checker warns for cases when the ``size`` parameter of the ``malloc`` ,
+``calloc``, ``realloc``, ``alloca`` or the size parameter of the
+array new C++ operator is tainted (potentially attacker controlled).
+If an attacker can inject a large value as the size parameter, memory 
exhaustion
+denial of service attack can be carried out.
+
+The ``alpha.security.taint.TaintPropagation`` checker also needs to be enabled 
for
+this checker to give warnings.
+
+The analyzer emits warning only if it cannot prove that the size parameter is
+within reasonable bounds (``<= SIZE_MAX/4``). This functionality partially
+covers the SEI Cert coding standard rule `INT04-C
+`_.
+
+You can silence this warning either by bound checking the ``size`` parameter, 
or
+by explicitly marking the ``size`` parameter as sanitized. See the
+:ref:`alpha-security-taint-TaintPropagation` checker for more details.
+
+.. code-block:: c
+
+  void vulnerable(void) {
+size_t size;

steakhal wrote:

```suggestion
size_t size = 0;
```
Let's initialize the value to be similar to the other cases.

https://github.com/llvm/llvm-project/pull/92420
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [analyzer] New optin.taint.TaintAlloc checker for catching unbounded memory allocation calls (PR #92420)

2024-05-30 Thread Balazs Benics via cfe-commits


@@ -1695,6 +1707,12 @@ MallocChecker::processNewAllocation(const 
CXXAllocatorCall ,
   // MallocUpdateRefState() instead of MallocMemAux() which breaks the
   // existing binding.
   SVal Target = Call.getObjectUnderConstruction();
+  if (Call.getOriginExpr()->isArray()) {
+std::optional SizeEx = NE->getArraySize();
+if (SizeEx)

steakhal wrote:

```suggestion
if (auto SizeEx = NE->getArraySize())
```

https://github.com/llvm/llvm-project/pull/92420
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [analyzer] New optin.taint.TaintAlloc checker for catching unbounded memory allocation calls (PR #92420)

2024-05-30 Thread Balazs Benics via cfe-commits


@@ -938,6 +938,53 @@ optin.portability.UnixAPI
 "
 Finds implementation-defined behavior in UNIX/Posix functions.
 
+.. _optin-taint-TaintAlloc:
+
+optin.taint.TaintAlloc (C, C++)

steakhal wrote:

I was thinking of suggesting `TaintedAlloc` (same in past tense), as it sounds 
better to me. I have no strong opinion on this though.

https://github.com/llvm/llvm-project/pull/92420
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [analyzer] New optin.taint.TaintAlloc checker for catching unbounded memory allocation calls (PR #92420)

2024-05-30 Thread Balazs Benics via cfe-commits


@@ -1730,6 +1721,21 @@ def UnixAPIPortabilityChecker : Checker<"UnixAPI">,
 
 } // end optin.portability
 
+
+//===--===//
+// Taint checkers.
+//===--===//
+
+let ParentPackage = TaintOptIn in {
+
+def TaintMallocChecker: Checker<"TaintMalloc">,
+  HelpText<"Check for memory allocations, where the size parameter "
+   "might be a tainted (attacker controlled) value.">,
+  Dependencies<[DynamicMemoryModeling]>,

steakhal wrote:

Why can't we make it a dependency now? (I don't have a strong opinion, I'm more 
just curious)

https://github.com/llvm/llvm-project/pull/92420
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [analyzer] New optin.taint.TaintAlloc checker for catching unbounded memory allocation calls (PR #92420)

2024-05-30 Thread Balazs Benics via cfe-commits

https://github.com/steakhal edited 
https://github.com/llvm/llvm-project/pull/92420
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [analyzer] New optin.taint.TaintAlloc checker for catching unbounded memory allocation calls (PR #92420)

2024-05-30 Thread Balazs Benics via cfe-commits

https://github.com/steakhal approved this pull request.

I join Donát, and I agree that this looks good as it is.
I had a handful of final remarks but I have no strong opinion on any of the 
raised points.
Merge this, once you considered them and took action if you agreed.

https://github.com/llvm/llvm-project/pull/92420
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [analyzer] New optin.taint.TaintAlloc checker for catching unbounded memory allocation calls (PR #92420)

2024-05-29 Thread Donát Nagy via cfe-commits

https://github.com/NagyDonat approved this pull request.

LGTM, thanks for the update!

https://github.com/llvm/llvm-project/pull/92420
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [analyzer] New optin.taint.TaintAlloc checker for catching unbounded memory allocation calls (PR #92420)

2024-05-29 Thread Daniel Krupp via cfe-commits

https://github.com/dkrupp updated 
https://github.com/llvm/llvm-project/pull/92420

>From f6fdd544a90b865e5e0e530930db87cad405216e Mon Sep 17 00:00:00 2001
From: Daniel Krupp 
Date: Tue, 30 Apr 2024 15:20:52 +0200
Subject: [PATCH 1/5] [analyzer] Adding taint analysis capability to
 unix.Malloc checker

unix.Malloc checker will warn if a memory allocation function
(malloc, calloc, realloc, alloca) is called with a tainted
(attacker controlled) size parameter.
A large, maliciously set size value can trigger memory exhaustion.
To get this warning, the alpha.security.taint.TaintPropagation checker
also needs to be switched on.

The warning will only be emitted, if the analyzer cannot prove
that the size is below reasonable bounds (https://wiki.sei.cmu.edu/confluence/display/c/INT04-C.+Enforce+limits+on+integer+values+originating+from+tainted+sources>`_.
+
+You can silence this warning either by bound checking the ``size`` parameter, 
or
+by explicitly marking the ``size`` parameter as sanitized. See the
+:ref:`alpha-security-taint-TaintPropagation` checker for more details.
+
+.. code-block:: c
+
+  void t1(void) {
+size_t size;
+scanf("%zu", );
+int *p = malloc(size); // warn: malloc is called with a tainted 
(potentially attacker controlled) value
+free(p);
+  }
+
+  void t3(void) {
+size_t size;
+scanf("%zu", );
+if (1024 BT_MismatchedDealloc;
   mutable std::unique_ptr BT_OffsetFree[CK_NumCheckKinds];
   mutable std::unique_ptr BT_UseZerroAllocated[CK_NumCheckKinds];
+  mutable std::unique_ptr BT_TaintedAlloc[CK_NumCheckKinds];
 
 #define CHECK_FN(NAME) 
\
   void NAME(const CallEvent , CheckerContext ) const;
@@ -462,6 +464,13 @@ class MallocChecker
   };
 
   bool isMemCall(const CallEvent ) const;
+  void reportTaintBug(StringRef Msg, ProgramStateRef State, CheckerContext ,
+  llvm::ArrayRef TaintedSyms,
+  AllocationFamily Family, const Expr *SizeEx) const;
+
+  void CheckTaintedness(CheckerContext , const CallEvent ,
+const SVal SizeSVal, ProgramStateRef State,
+AllocationFamily Family) const;
 
   // TODO: Remove mutable by moving the initializtaion to the registry 
function.
   mutable std::optional KernelZeroFlagVal;
@@ -521,9 +530,9 @@ class MallocChecker
   /// malloc leaves it undefined.
   /// \param [in] State The \c ProgramState right before allocation.
   /// \returns The ProgramState right after allocation.
-  [[nodiscard]] static ProgramStateRef
+  [[nodiscard]] ProgramStateRef
   MallocMemAux(CheckerContext , const CallEvent , const Expr *SizeEx,
-   SVal Init, ProgramStateRef State, AllocationFamily Family);
+   SVal Init, ProgramStateRef State, AllocationFamily Family) 
const;
 
   /// Models memory allocation.
   ///
@@ -534,9 +543,10 @@ class MallocChecker
   /// malloc leaves it undefined.
   /// \param [in] State The \c ProgramState right before allocation.
   /// \returns The ProgramState right after allocation.
-  [[nodiscard]] static ProgramStateRef
-  MallocMemAux(CheckerContext , const CallEvent , SVal Size, SVal Init,
-   ProgramStateRef State, AllocationFamily Family);
+  [[nodiscard]] ProgramStateRef MallocMemAux(CheckerContext ,
+ const CallEvent , SVal Size,
+ SVal Init, ProgramStateRef State,
+ AllocationFamily Family) const;
 
   // Check if this malloc() for special flags. At present that means M_ZERO or
   // __GFP_ZERO (in which case, treat it like calloc).
@@ -649,8 +659,9 @@ class MallocChecker
   /// \param [in] Call The expression that reallocated memory
   /// \param [in] State The \c ProgramState right before reallocation.
   /// \returns The ProgramState right after allocation.
-  [[nodiscard]] static ProgramStateRef
-  CallocMem(CheckerContext , const CallEvent , ProgramStateRef State);
+  [[nodiscard]] ProgramStateRef CallocMem(CheckerContext ,
+  const CallEvent ,
+  ProgramStateRef State) const;
 
   /// See if deallocation happens in a suspicious context. If so, escape the
   /// pointers that otherwise would have been deallocated and return true.
@@ -1779,7 +1790,7 @@ ProgramStateRef 
MallocChecker::MallocMemAux(CheckerContext ,
 const CallEvent ,
 const Expr *SizeEx, SVal Init,
 ProgramStateRef State,
-AllocationFamily Family) {
+AllocationFamily Family) const {
   if (!State)
 return nullptr;
 
@@ -1787,10 +1798,71 @@ ProgramStateRef 
MallocChecker::MallocMemAux(CheckerContext ,
   return MallocMemAux(C, Call, 

[clang] [analyzer] New optin.taint.TaintAlloc checker for catching unbounded memory allocation calls (PR #92420)

2024-05-29 Thread Donát Nagy via cfe-commits


@@ -1779,18 +1797,76 @@ ProgramStateRef 
MallocChecker::MallocMemAux(CheckerContext ,
 const CallEvent ,
 const Expr *SizeEx, SVal Init,
 ProgramStateRef State,
-AllocationFamily Family) {
+AllocationFamily Family) const {
   if (!State)
 return nullptr;
 
   assert(SizeEx);
   return MallocMemAux(C, Call, C.getSVal(SizeEx), Init, State, Family);
 }
 
+void MallocChecker::reportTaintBug(StringRef Msg, ProgramStateRef State,
+   CheckerContext ,
+   llvm::ArrayRef TaintedSyms,
+   AllocationFamily Family) const {
+
+  if (!ChecksEnabled[CK_TaintAllocChecker])
+return;
+
+  if (ExplodedNode *N = C.generateNonFatalErrorNode(State, this)) {
+if (!BT_TaintedAlloc)
+  BT_TaintedAlloc.reset(new BugType(CheckNames[CK_TaintAllocChecker],
+"Tainted Memory Allocation",
+categories::TaintedData));
+auto R = std::make_unique(*BT_TaintedAlloc, Msg, 
N);
+for (auto TaintedSym : TaintedSyms) {
+  R->markInteresting(TaintedSym);
+}
+C.emitReport(std::move(R));
+  }
+}
+
+void MallocChecker::CheckTaintedness(CheckerContext , const CallEvent ,

NagyDonat wrote:

Rename this to `checkTaintedness` with a lowercase 'c' to follow the global 
coding guidelines. I know that MallocChecker has lots of functions whose name 
start with an uppercase letter, but I think it's better to introduce new 
functions with conforming names and eventually switch to the standard naming 
scheme when there is a refactoring that already touches many functions.

(This is how I standardized the variable names in ArrayBoundV2.)

https://github.com/llvm/llvm-project/pull/92420
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [analyzer] New optin.taint.TaintAlloc checker for catching unbounded memory allocation calls (PR #92420)

2024-05-29 Thread Donát Nagy via cfe-commits


@@ -1779,18 +1797,76 @@ ProgramStateRef 
MallocChecker::MallocMemAux(CheckerContext ,
 const CallEvent ,
 const Expr *SizeEx, SVal Init,
 ProgramStateRef State,
-AllocationFamily Family) {
+AllocationFamily Family) const {
   if (!State)
 return nullptr;
 
   assert(SizeEx);
   return MallocMemAux(C, Call, C.getSVal(SizeEx), Init, State, Family);
 }
 
+void MallocChecker::reportTaintBug(StringRef Msg, ProgramStateRef State,
+   CheckerContext ,
+   llvm::ArrayRef TaintedSyms,
+   AllocationFamily Family) const {
+
+  if (!ChecksEnabled[CK_TaintAllocChecker])
+return;

NagyDonat wrote:

Move this check to `CheckTaintedness` -- there is no reason to calculate taint 
information if it won't be reported.

https://github.com/llvm/llvm-project/pull/92420
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [analyzer] New optin.taint.TaintAlloc checker for catching unbounded memory allocation calls (PR #92420)

2024-05-29 Thread Donát Nagy via cfe-commits


@@ -1779,18 +1797,76 @@ ProgramStateRef 
MallocChecker::MallocMemAux(CheckerContext ,
 const CallEvent ,
 const Expr *SizeEx, SVal Init,
 ProgramStateRef State,
-AllocationFamily Family) {
+AllocationFamily Family) const {
   if (!State)
 return nullptr;
 
   assert(SizeEx);
   return MallocMemAux(C, Call, C.getSVal(SizeEx), Init, State, Family);
 }
 
+void MallocChecker::reportTaintBug(StringRef Msg, ProgramStateRef State,
+   CheckerContext ,
+   llvm::ArrayRef TaintedSyms,
+   AllocationFamily Family) const {
+
+  if (!ChecksEnabled[CK_TaintAllocChecker])
+return;
+
+  if (ExplodedNode *N = C.generateNonFatalErrorNode(State, this)) {
+if (!BT_TaintedAlloc)
+  BT_TaintedAlloc.reset(new BugType(CheckNames[CK_TaintAllocChecker],
+"Tainted Memory Allocation",
+categories::TaintedData));
+auto R = std::make_unique(*BT_TaintedAlloc, Msg, 
N);
+for (auto TaintedSym : TaintedSyms) {
+  R->markInteresting(TaintedSym);
+}
+C.emitReport(std::move(R));
+  }
+}
+
+void MallocChecker::CheckTaintedness(CheckerContext , const CallEvent ,
+ const SVal SizeSVal, ProgramStateRef 
State,
+ AllocationFamily Family) const {
+  std::vector TaintedSyms =
+  taint::getTaintedSymbols(State, SizeSVal);
+  if (TaintedSyms.empty())
+return;
+
+  SValBuilder  = C.getSValBuilder();
+  QualType SizeTy = SVB.getContext().getSizeType();
+  QualType CmpTy = SVB.getConditionType();
+  // In case the symbol is tainted, we give a warning if the
+  // size is larger than SIZE_MAX/4
+  BasicValueFactory  = SVB.getBasicValueFactory();
+  const llvm::APSInt MaxValInt = BVF.getMaxValue(SizeTy);
+  NonLoc MaxLength =
+  SVB.makeIntVal(MaxValInt / APSIntType(MaxValInt).getValue(4));
+  std::optional SizeNL = SizeSVal.getAs();
+  auto Cmp = SVB.evalBinOpNN(State, BO_GE, *SizeNL, MaxLength, CmpTy)
+ .getAs();
+  if (!Cmp)
+return;
+  auto [StateTooLarge, StateNotTooLarge] = State->assume(*Cmp);
+  if (!StateTooLarge && StateNotTooLarge) {
+// we can prove that size is not too large so ok.

NagyDonat wrote:

```suggestion
// We can prove that size is not too large, so there is no issue."
```

https://github.com/llvm/llvm-project/pull/92420
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [analyzer] New optin.taint.TaintAlloc checker for catching unbounded memory allocation calls (PR #92420)

2024-05-29 Thread Donát Nagy via cfe-commits


@@ -938,6 +938,53 @@ optin.portability.UnixAPI
 "
 Finds implementation-defined behavior in UNIX/Posix functions.
 
+.. _optin-taint-TaintAlloc:
+
+optin.taint.TaintAlloc (C, C++)
+"""
+
+This checker warns for cases when the ``size`` parameter of the ``malloc`` ,
+``calloc``, ``realloc``, ``alloca`` or the size parameter of the
+array new C++ operator is tainted (potentially attacker controlled).
+If an attacker can inject a large value as the size parameter, memory 
exhaustion
+denial of service attack can be carried out.
+
+The ``alpha.security.taint.TaintPropagation`` checker also needs to be enabled 
for
+this checker to give warnings.
+
+The analyzer emits warning only if it cannot prove that the size parameter is
+within reasonable bounds (``<= SIZE_MAX/4``). This functionality partially
+covers the SEI Cert coding standard rule `INT04-C
+`_.
+
+You can silence this warning either by bound checking the ``size`` parameter, 
or
+by explicitly marking the ``size`` parameter as sanitized. See the
+:ref:`alpha-security-taint-TaintPropagation` checker for more details.
+
+.. code-block:: c
+
+  void t1(void) {
+size_t size;
+scanf("%zu", );
+int *p = malloc(size); // warn: malloc is called with a tainted 
(potentially attacker controlled) value
+free(p);
+  }
+
+  void t3(void) {
+size_t size = 0;
+scanf("%zu", );
+if (1024 < size)
+  return;
+int *p = malloc(size); // No warning expected as the the user input is 
bound
+free(p);
+  }
+
+  void tcpp(void) {

NagyDonat wrote:

```suggestion
  void vulnerable_cpp(void) {
```

https://github.com/llvm/llvm-project/pull/92420
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [analyzer] New optin.taint.TaintAlloc checker for catching unbounded memory allocation calls (PR #92420)

2024-05-29 Thread Donát Nagy via cfe-commits


@@ -938,6 +938,53 @@ optin.portability.UnixAPI
 "
 Finds implementation-defined behavior in UNIX/Posix functions.
 
+.. _optin-taint-TaintAlloc:
+
+optin.taint.TaintAlloc (C, C++)
+"""
+
+This checker warns for cases when the ``size`` parameter of the ``malloc`` ,
+``calloc``, ``realloc``, ``alloca`` or the size parameter of the
+array new C++ operator is tainted (potentially attacker controlled).
+If an attacker can inject a large value as the size parameter, memory 
exhaustion
+denial of service attack can be carried out.
+
+The ``alpha.security.taint.TaintPropagation`` checker also needs to be enabled 
for
+this checker to give warnings.
+
+The analyzer emits warning only if it cannot prove that the size parameter is
+within reasonable bounds (``<= SIZE_MAX/4``). This functionality partially
+covers the SEI Cert coding standard rule `INT04-C
+`_.
+
+You can silence this warning either by bound checking the ``size`` parameter, 
or
+by explicitly marking the ``size`` parameter as sanitized. See the
+:ref:`alpha-security-taint-TaintPropagation` checker for more details.
+
+.. code-block:: c
+
+  void t1(void) {
+size_t size;
+scanf("%zu", );
+int *p = malloc(size); // warn: malloc is called with a tainted 
(potentially attacker controlled) value
+free(p);
+  }
+
+  void t3(void) {

NagyDonat wrote:

```suggestion
  void bounds_checked(void) {
```

https://github.com/llvm/llvm-project/pull/92420
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [analyzer] New optin.taint.TaintAlloc checker for catching unbounded memory allocation calls (PR #92420)

2024-05-29 Thread Donát Nagy via cfe-commits


@@ -938,6 +938,53 @@ optin.portability.UnixAPI
 "
 Finds implementation-defined behavior in UNIX/Posix functions.
 
+.. _optin-taint-TaintAlloc:
+
+optin.taint.TaintAlloc (C, C++)
+"""
+
+This checker warns for cases when the ``size`` parameter of the ``malloc`` ,
+``calloc``, ``realloc``, ``alloca`` or the size parameter of the
+array new C++ operator is tainted (potentially attacker controlled).
+If an attacker can inject a large value as the size parameter, memory 
exhaustion
+denial of service attack can be carried out.
+
+The ``alpha.security.taint.TaintPropagation`` checker also needs to be enabled 
for
+this checker to give warnings.
+
+The analyzer emits warning only if it cannot prove that the size parameter is
+within reasonable bounds (``<= SIZE_MAX/4``). This functionality partially
+covers the SEI Cert coding standard rule `INT04-C
+`_.
+
+You can silence this warning either by bound checking the ``size`` parameter, 
or
+by explicitly marking the ``size`` parameter as sanitized. See the
+:ref:`alpha-security-taint-TaintPropagation` checker for more details.
+
+.. code-block:: c
+
+  void t1(void) {

NagyDonat wrote:

```suggestion
  void vulnerable(void) {
```

https://github.com/llvm/llvm-project/pull/92420
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [analyzer] New optin.taint.TaintAlloc checker for catching unbounded memory allocation calls (PR #92420)

2024-05-29 Thread Donát Nagy via cfe-commits

https://github.com/NagyDonat approved this pull request.

I'd say that the commit is acceptable as it is now, but I added several inline 
comments for minor prettification issues.

https://github.com/llvm/llvm-project/pull/92420
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [analyzer] New optin.taint.TaintAlloc checker for catching unbounded memory allocation calls (PR #92420)

2024-05-29 Thread Donát Nagy via cfe-commits

https://github.com/NagyDonat edited 
https://github.com/llvm/llvm-project/pull/92420
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [analyzer] New optin.taint.TaintAlloc checker for catching unbounded memory allocation calls (PR #92420)

2024-05-28 Thread Daniel Krupp via cfe-commits

dkrupp wrote:

- Handling of C++ operator new[] allocation was added to the checker with test 
cases
- The checker is renamed to optin.taint.TaintAlloc, as besides malloc it 
handles the c++ new array allocations too
- Test cases and documentation was updated

@NagyDonat , @steakhal  please check if any more update is needed. thanks.

https://github.com/llvm/llvm-project/pull/92420
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [analyzer] New optin.taint.TaintAlloc checker for catching unbounded memory allocation calls (PR #92420)

2024-05-28 Thread Daniel Krupp via cfe-commits

https://github.com/dkrupp edited https://github.com/llvm/llvm-project/pull/92420
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits