[clang] 25bbe23 - [analyzer] StdLibraryFunctionsChecker: Add support for new functions

2020-08-12 Thread Zurab Tsinadze via cfe-commits

Author: Zurab Tsinadze
Date: 2020-08-12T16:20:00+02:00
New Revision: 25bbe234e4e73e6345f4f0b61e680abf5a90d59f

URL: 
https://github.com/llvm/llvm-project/commit/25bbe234e4e73e6345f4f0b61e680abf5a90d59f
DIFF: 
https://github.com/llvm/llvm-project/commit/25bbe234e4e73e6345f4f0b61e680abf5a90d59f.diff

LOG: [analyzer] StdLibraryFunctionsChecker: Add support for new functions

`toupper`, `tolower`, `toascii` functions were added to
StdLibraryFunctionsChecker to fully cover CERT STR37-C rule:
https://wiki.sei.cmu.edu/confluence/x/BNcxBQ

Differential Revision: https://reviews.llvm.org/D85093

Added: 


Modified: 
clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
clang/test/Analysis/std-c-library-functions-arg-constraints.c

Removed: 




diff  --git a/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp 
b/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
index e437c33bd81a..030f995739e3 100644
--- a/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
@@ -40,12 +40,12 @@
 //
 // The following standard C functions are currently supported:
 //
-//   fgetc  getline   isdigit   isupper
+//   fgetc  getline   isdigit   isupper toascii
 //   fread  isalnum   isgraph   isxdigit
 //   fwrite isalpha   islower   read
 //   getc   isascii   isprint   write
-//   getcharisblank   ispunct
-//   getdelim   iscntrl   isspace
+//   getcharisblank   ispunct   toupper
+//   getdelim   iscntrl   isspace   tolower
 //
 
//===--===//
 
@@ -147,9 +147,7 @@ class StdLibraryFunctionsChecker
 RangeConstraint(ArgNo ArgN, RangeKind Kind, const IntRangeVector &Args)
 : ValueConstraint(ArgN), Kind(Kind), Args(Args) {}
 
-const IntRangeVector &getRanges() const {
-  return Args;
-}
+const IntRangeVector &getRanges() const { return Args; }
 
   private:
 ProgramStateRef applyAsOutOfRange(ProgramStateRef State,
@@ -158,6 +156,7 @@ class StdLibraryFunctionsChecker
 ProgramStateRef applyAsWithinRange(ProgramStateRef State,
const CallEvent &Call,
const Summary &Summary) const;
+
   public:
 ProgramStateRef apply(ProgramStateRef State, const CallEvent &Call,
   const Summary &Summary,
@@ -408,7 +407,7 @@ class StdLibraryFunctionsChecker
   return *this;
 }
 
-Summary &Case(ConstraintSet&& CS) {
+Summary &Case(ConstraintSet &&CS) {
   CaseConstraints.push_back(std::move(CS));
   return *this;
 }
@@ -796,13 +795,13 @@ void StdLibraryFunctionsChecker::initFunctionSummaries(
   const QualType LongLongTy = ACtx.LongLongTy;
   const QualType SizeTy = ACtx.getSizeType();
 
-  const QualType VoidPtrTy = ACtx.VoidPtrTy; // void *
+  const QualType VoidPtrTy = ACtx.VoidPtrTy;// void *
   const QualType IntPtrTy = ACtx.getPointerType(IntTy); // int *
   const QualType UnsignedIntPtrTy =
   ACtx.getPointerType(UnsignedIntTy); // unsigned int *
   const QualType VoidPtrRestrictTy = getRestrictTy(VoidPtrTy);
   const QualType ConstVoidPtrTy =
-  ACtx.getPointerType(ACtx.VoidTy.withConst()); // const void *
+  ACtx.getPointerType(ACtx.VoidTy.withConst());// const void *
   const QualType CharPtrTy = ACtx.getPointerType(ACtx.CharTy); // char *
   const QualType CharPtrRestrictTy = getRestrictTy(CharPtrTy);
   const QualType ConstCharPtrTy =
@@ -1117,6 +1116,18 @@ void StdLibraryFunctionsChecker::initFunctionSummaries(
   .Case({ArgumentCondition(0U, OutOfRange,
{{'0', '9'}, {'A', 'F'}, {'a', 'f'}}),
  ReturnValueCondition(WithinRange, SingleValue(0))}));
+  addToFunctionSummaryMap(
+  "toupper", Summary(ArgTypes{IntTy}, RetType{IntTy}, EvalCallAsPure)
+ .ArgConstraint(ArgumentCondition(
+ 0U, WithinRange, {{EOFv, EOFv}, {0, 
UCharRangeMax}})));
+  addToFunctionSummaryMap(
+  "tolower", Summary(ArgTypes{IntTy}, RetType{IntTy}, EvalCallAsPure)
+ .ArgConstraint(ArgumentCondition(
+ 0U, WithinRange, {{EOFv, EOFv}, {0, 
UCharRangeMax}})));
+  addToFunctionSummaryMap(
+  "toascii", Summary(ArgTypes{IntTy}, RetType{IntTy}, EvalCallAsPure)
+ .ArgConstraint(ArgumentCondition(
+ 0U, WithinRange, {{EOFv, EOFv}, {0, 
UCharRangeMax}})));
 
   // The getc() family of functions that returns either a char or an EOF.
   if (FilePtrTy) {
@@ -2033,7 +2044,8 @@ void 
ento::registerStdCLibraryFunctionsChecker(CheckerManager &mgr) {
   mgr.getAnalyzerOptions().getCheckerBooleanOption(Checker, "ModelPOSIX");
 }
 
-bool ento::shouldRegisterStdCLibraryFunctionsC

[clang] 811b173 - [analyzer] Add InvalidPtrChecker

2021-10-04 Thread Zurab Tsinadze via cfe-commits

Author: Zurab Tsinadze
Date: 2021-10-04T17:08:34+02:00
New Revision: 811b1736d91b301f59fbaa148ff55c32f90a3947

URL: 
https://github.com/llvm/llvm-project/commit/811b1736d91b301f59fbaa148ff55c32f90a3947
DIFF: 
https://github.com/llvm/llvm-project/commit/811b1736d91b301f59fbaa148ff55c32f90a3947.diff

LOG: [analyzer] Add InvalidPtrChecker

This patch introduces a new checker: `alpha.security.cert.env.InvalidPtr`

Checker finds usage of invalidated pointers related to environment.

Based on the following SEI CERT Rules:
ENV34-C: https://wiki.sei.cmu.edu/confluence/x/8tYxBQ
ENV31-C: https://wiki.sei.cmu.edu/confluence/x/5NUxBQ

Reviewed By: martong

Differential Revision: https://reviews.llvm.org/D97699

Added: 
clang/lib/StaticAnalyzer/Checkers/cert/InvalidPtrChecker.cpp
clang/test/Analysis/cert/env31-c.c
clang/test/Analysis/cert/env34-c-cert-examples.c
clang/test/Analysis/cert/env34-c.c

Modified: 
clang/docs/analyzer/checkers.rst
clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt

Removed: 




diff  --git a/clang/docs/analyzer/checkers.rst 
b/clang/docs/analyzer/checkers.rst
index 89190b54e5a51..a0c207b974678 100644
--- a/clang/docs/analyzer/checkers.rst
+++ b/clang/docs/analyzer/checkers.rst
@@ -2075,10 +2075,63 @@ Finds calls to the ``putenv`` function which pass a 
pointer to an automatic vari
 if (retval < 0 || (size_t)retval >= sizeof(env)) {
 /* Handle error */
 }
- 
+
 return putenv(env); // putenv function should not be called with auto 
variables
   }
-  
+
+alpha.security.cert.env
+^^^
+
+SEI CERT checkers of `POSIX C coding rules 
`_.
+
+.. _alpha-security-cert-env-InvalidPtr:
+
+alpha.security.cert.env.InvalidPtr
+"""
+
+Corresponds to SEI CERT Rules ENV31-C and ENV34-C.
+
+ENV31-C:
+Rule is about the possible problem with `main` function's third argument, 
environment pointer,
+"envp". When enviornment array is modified using some modification function
+such as putenv, setenv or others, It may happen that memory is reallocated,
+however "envp" is not updated to reflect the changes and points to old memory
+region.
+
+ENV34-C:
+Some functions return a pointer to a statically allocated buffer.
+Consequently, subsequent call of these functions will invalidate previous
+pointer. These functions include: getenv, localeconv, asctime, setlocale, 
strerror
+
+.. code-block:: c
+
+  int main(int argc, const char *argv[], const char *envp[]) {
+if (setenv("MY_NEW_VAR", "new_value", 1) != 0) {
+  // setenv call may invalidate 'envp'
+  /* Handle error */
+}
+if (envp != NULL) {
+  for (size_t i = 0; envp[i] != NULL; ++i) {
+puts(envp[i]);
+// envp may no longer point to the current environment
+// this program has unanticipated behavior, since envp
+// does not reflect changes made by setenv function.
+  }
+}
+return 0;
+  }
+
+  void previous_call_invalidation() {
+char *p, *pp;
+
+p = getenv("VAR");
+pp = getenv("VAR2");
+// subsequent call to 'getenv' invalidated previous one
+
+*p;
+// dereferencing invalid pointer
+  }
+
 .. _alpha-security-ArrayBound:
 
 alpha.security.ArrayBound (C)

diff  --git a/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td 
b/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
index 86513a3e541be..aac111982b235 100644
--- a/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
+++ b/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
@@ -73,6 +73,7 @@ def Taint : Package<"taint">, ParentPackage;
 
 def CERT : Package<"cert">, ParentPackage;
 def POS : Package<"pos">, ParentPackage;
+def ENV : Package<"env">, ParentPackage;
 
 def Unix : Package<"unix">;
 def UnixAlpha : Package<"unix">, ParentPackage;
@@ -947,6 +948,14 @@ let ParentPackage = POS in {
 
 } // end "alpha.cert.pos"
 
+let ParentPackage = ENV in {
+
+  def InvalidPtrChecker : Checker<"InvalidPtr">,
+  HelpText<"Finds usages of possibly invalidated pointers">,
+  Documentation;
+
+} // end "alpha.cert.env"
+
 let ParentPackage = SecurityAlpha in {
 
 def ArrayBoundChecker : Checker<"ArrayBound">,

diff  --git a/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt 
b/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt
index eb4f301377325..e7d424ae91504 100644
--- a/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt
+++ b/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt
@@ -49,6 +49,7 @@ add_clang_library(clangStaticAnalyzerCheckers
   IdenticalExprChecker.cpp
   InnerPointerChecker.cpp
   InvalidatedIteratorChecker.cpp
+  cert/InvalidPtrChecker.cpp
   Iterator.cpp
   IteratorModeling.cpp
   IteratorRangeChecker.cpp

diff  --git a/clang/lib/StaticAnalyzer/Checkers/cert/InvalidPtrChecker.cpp 
b/clang/lib/StaticAnalyzer/Checkers/cert/InvalidPtrChec

[clang] a54d81f - [analyzer] CERT: POS34-C

2020-02-19 Thread Zurab Tsinadze via cfe-commits

Author: Zurab Tsinadze
Date: 2020-02-19T18:12:19+01:00
New Revision: a54d81f597963b8768ce2b94a8ef570f9eaaac25

URL: 
https://github.com/llvm/llvm-project/commit/a54d81f597963b8768ce2b94a8ef570f9eaaac25
DIFF: 
https://github.com/llvm/llvm-project/commit/a54d81f597963b8768ce2b94a8ef570f9eaaac25.diff

LOG: [analyzer] CERT: POS34-C

Summary:
This patch introduces a new checker:
`alpha.security.cert.pos.34c`

This checker is implemented based on the following rule:
https://wiki.sei.cmu.edu/confluence/x/6NYxBQ
The check warns if  `putenv` function is
called with automatic storage variable as an argument.

Differential Revision: https://reviews.llvm.org/D71433

Added: 
clang/lib/StaticAnalyzer/Checkers/cert/PutenvWithAutoChecker.cpp
clang/test/Analysis/cert/pos34-c-fp-suppression.cpp
clang/test/Analysis/cert/pos34-c.cpp

Modified: 
clang/docs/analyzer/checkers.rst
clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
clang/include/clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h
clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt
clang/lib/StaticAnalyzer/Core/CommonBugCategories.cpp

Removed: 




diff  --git a/clang/docs/analyzer/checkers.rst 
b/clang/docs/analyzer/checkers.rst
index f39bf1f7b2b8..b130cc34f685 100644
--- a/clang/docs/analyzer/checkers.rst
+++ b/clang/docs/analyzer/checkers.rst
@@ -1929,6 +1929,38 @@ Warns against using one vs. many plural pattern in code 
when generating localize
 
 alpha.security
 ^^
+
+
+alpha.security.cert
+^^^
+
+SEI CERT checkers which tries to find errors based on their `C coding 
rules`_.
+
+.. _alpha-security-cert-pos-checkers:
+
+alpha.security.cert.pos
+^^^
+
+SEI CERT checkers of POSIX `C coding 
rules`_.
+
+.. _alpha-security-cert-pos-34c:
+
+alpha.security.cert.pos.34c
+"""
+Finds calls to the ``putenv`` function which pass a pointer to an automatic 
variable as the argument.
+
+.. code-block:: c
+
+  int func(const char *var) {
+char env[1024];
+int retval = snprintf(env, sizeof(env),"TEST=%s", var);
+if (retval < 0 || (size_t)retval >= sizeof(env)) {
+/* Handle error */
+}
+ 
+return putenv(env); // putenv function should not be called with auto 
variables
+  }
+  
 .. _alpha-security-ArrayBound:
 
 alpha.security.ArrayBound (C)

diff  --git a/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td 
b/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
index 76cf92af9113..91c0fc88f6e7 100644
--- a/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
+++ b/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
@@ -71,6 +71,9 @@ def InsecureAPI : Package<"insecureAPI">, 
ParentPackage;
 def SecurityAlpha : Package<"security">, ParentPackage;
 def Taint : Package<"taint">, ParentPackage;
 
+def CERT : Package<"cert">, ParentPackage;
+def POS : Package<"pos">, ParentPackage;
+
 def Unix : Package<"unix">;
 def UnixAlpha : Package<"unix">, ParentPackage;
 def CString : Package<"cstring">, ParentPackage;
@@ -829,6 +832,15 @@ def FloatLoopCounter : Checker<"FloatLoopCounter">,
 
 } // end "security"
 
+let ParentPackage = POS in {
+
+  def PutenvWithAuto : Checker<"34c">,
+  HelpText<"Finds calls to the 'putenv' function which pass a pointer to "
+   "an automatic variable as the argument.">,
+  Documentation;
+
+} // end "alpha.cert.pos"
+
 let ParentPackage = SecurityAlpha in {
 
 def ArrayBoundChecker : Checker<"ArrayBound">,

diff  --git 
a/clang/include/clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h 
b/clang/include/clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h
index 22c1a7dd98cc..637b89fd9036 100644
--- a/clang/include/clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h
+++ b/clang/include/clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h
@@ -11,16 +11,16 @@
 
 // Common strings used for the "category" of many static analyzer issues.
 namespace clang {
-  namespace ento {
-namespace categories {
-  extern const char * const CoreFoundationObjectiveC;
-  extern const char * const LogicError;
-  extern const char * const MemoryRefCount;
-  extern const char * const MemoryError;
-  extern const char * const UnixAPI;
-  extern const char * const CXXObjectLifecycle;
-}
-  }
-}
+namespace ento {
+namespace categories {
+extern const char *const CoreFoundationObjectiveC;
+extern const char *const LogicError;
+extern const char *const MemoryRefCount;
+extern const char *const MemoryError;
+extern const char *const UnixAPI;
+extern const char *const CXXObjectLifecycle;
+extern const char *const SecurityError;
+} // namespace categories
+} // namespace ento
+} // namespace clang
 #endif
-

diff  --git a/clang/lib/StaticAnalyzer/Checke