llvmbot wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang-static-analyzer-1

Author: Endre Fülöp (gamesh411)

<details>
<summary>Changes</summary>

…ferHandling checker

The checker may report warnings for deprecated buffer handling functions 
(memcpy, memset, memmove, etc.) even when not compiling with C11 standard if 
the new option "AllowWithoutC11" is set to true.

These functions are deprecated in C11, but may still be problematic in earlier 
C standards.

---
Full diff: https://github.com/llvm/llvm-project/pull/168704.diff


6 Files Affected:

- (modified) clang/docs/analyzer/checkers.rst (+7) 
- (modified) clang/include/clang/StaticAnalyzer/Checkers/Checkers.td (+15-6) 
- (modified) clang/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp 
(+20-2) 
- (modified) clang/test/Analysis/Inputs/system-header-simulator.h (+1) 
- (modified) clang/test/Analysis/analyzer-config.c (+1) 
- (added) 
clang/test/Analysis/security-deprecated-buffer-handling-allow-without-c11.c 
(+48) 


``````````diff
diff --git a/clang/docs/analyzer/checkers.rst b/clang/docs/analyzer/checkers.rst
index fd0b304cba0df..8cb4f7ae285de 100644
--- a/clang/docs/analyzer/checkers.rst
+++ b/clang/docs/analyzer/checkers.rst
@@ -1768,6 +1768,13 @@ security.insecureAPI.DeprecatedOrUnsafeBufferHandling (C)
    strncpy(buf, "a", 1); // warn
  }
 
+The ``AllowWithoutC11`` option allows reporting warnings for these functions 
even when not compiling with C11 standard. These functions are deprecated in 
C11, but may still be problematic in earlier C standards.
+
+To enable this option, use:
+``-analyzer-config 
security.insecureAPI.DeprecatedOrUnsafeBufferHandling:AllowWithoutC11=true``.
+
+By default, this option is set to *false*.
+
 .. _security-MmapWriteExec:
 
 security.MmapWriteExec (C)
diff --git a/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td 
b/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
index ffae3b9310979..310dac5340a18 100644
--- a/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
+++ b/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
@@ -901,12 +901,21 @@ def UncheckedReturn : Checker<"UncheckedReturn">,
   Dependencies<[SecuritySyntaxChecker]>,
   Documentation<HasDocumentation>;
 
-def DeprecatedOrUnsafeBufferHandling :
-  Checker<"DeprecatedOrUnsafeBufferHandling">,
-  HelpText<"Warn on uses of unsecure or deprecated buffer manipulating "
-           "functions">,
-  Dependencies<[SecuritySyntaxChecker]>,
-  Documentation<HasDocumentation>;
+def DeprecatedOrUnsafeBufferHandling
+    : Checker<"DeprecatedOrUnsafeBufferHandling">,
+      HelpText<"Warn on uses of unsecure or deprecated buffer manipulating "
+               "functions">,
+      Dependencies<[SecuritySyntaxChecker]>,
+      CheckerOptions<
+          [CmdLineOption<
+               Boolean, "AllowWithoutC11",
+               "Allow reporting deprecated or unsafe buffer handling "
+               "functions even when not compiling with C11 standard. "
+               "These functions are deprecated in C11, but may still be "
+               "problematic in earlier C standards.",
+               "false", Released>,
+]>,
+      Documentation<HasDocumentation>;
 
 def decodeValueOfObjCType : Checker<"decodeValueOfObjCType">,
   HelpText<"Warn on uses of the '-decodeValueOfObjCType:at:' method">,
diff --git a/clang/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp 
b/clang/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp
index 5e75c1c4a3abd..e07c9dcbad9fe 100644
--- a/clang/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp
@@ -50,6 +50,8 @@ struct ChecksFilter {
   bool check_UncheckedReturn = false;
   bool check_decodeValueOfObjCType = false;
 
+  bool allowDeprecatedOrUnsafeBufferHandlingWithoutC11 = false;
+
   CheckerNameRef checkName_bcmp;
   CheckerNameRef checkName_bcopy;
   CheckerNameRef checkName_bzero;
@@ -754,7 +756,8 @@ void WalkAST::checkDeprecatedOrUnsafeBufferHandling(const 
CallExpr *CE,
   if (!filter.check_DeprecatedOrUnsafeBufferHandling)
     return;
 
-  if (!BR.getContext().getLangOpts().C11)
+  if (!(BR.getContext().getLangOpts().C11 ||
+        filter.allowDeprecatedOrUnsafeBufferHandlingWithoutC11))
     return;
 
   // Issue a warning. ArgIndex == -1: Deprecated but not unsafe (has size
@@ -1113,5 +1116,20 @@ REGISTER_CHECKER(rand)
 REGISTER_CHECKER(vfork)
 REGISTER_CHECKER(FloatLoopCounter)
 REGISTER_CHECKER(UncheckedReturn)
-REGISTER_CHECKER(DeprecatedOrUnsafeBufferHandling)
+
+void ento::registerDeprecatedOrUnsafeBufferHandling(CheckerManager &mgr) {
+  SecuritySyntaxChecker *checker = mgr.getChecker<SecuritySyntaxChecker>();
+  checker->filter.check_DeprecatedOrUnsafeBufferHandling = true;
+  checker->filter.checkName_DeprecatedOrUnsafeBufferHandling =
+      mgr.getCurrentCheckerName();
+  checker->filter.allowDeprecatedOrUnsafeBufferHandlingWithoutC11 =
+      mgr.getAnalyzerOptions().getCheckerBooleanOption(
+          mgr.getCurrentCheckerName(), "AllowWithoutC11");
+}
+
+bool ento::shouldRegisterDeprecatedOrUnsafeBufferHandling(
+    const CheckerManager &mgr) {
+  return true;
+}
+
 REGISTER_CHECKER(decodeValueOfObjCType)
diff --git a/clang/test/Analysis/Inputs/system-header-simulator.h 
b/clang/test/Analysis/Inputs/system-header-simulator.h
index fadc09f65d536..e048a6a892c48 100644
--- a/clang/test/Analysis/Inputs/system-header-simulator.h
+++ b/clang/test/Analysis/Inputs/system-header-simulator.h
@@ -82,6 +82,7 @@ char *strcpy(char *restrict, const char *restrict);
 char *strncpy(char *restrict dst, const char *restrict src, size_t n);
 char *strsep(char **restrict stringp, const char *restrict delim);
 void *memcpy(void *restrict dst, const void *restrict src, size_t n);
+void *memmove(void *dst, const void *src, size_t n);
 void *memset(void *s, int c, size_t n);
 
 typedef unsigned long __darwin_pthread_key_t;
diff --git a/clang/test/Analysis/analyzer-config.c 
b/clang/test/Analysis/analyzer-config.c
index 7936273415ad4..60ca162fb3f24 100644
--- a/clang/test/Analysis/analyzer-config.c
+++ b/clang/test/Analysis/analyzer-config.c
@@ -121,6 +121,7 @@
 // CHECK-NEXT: region-store-small-struct-limit = 2
 // CHECK-NEXT: report-in-main-source-file = false
 // CHECK-NEXT: security.cert.env.InvalidPtr:InvalidatingGetEnv = false
+// CHECK-NEXT: 
security.insecureAPI.DeprecatedOrUnsafeBufferHandling:AllowWithoutC11 = false
 // CHECK-NEXT: serialize-stats = false
 // CHECK-NEXT: silence-checkers = ""
 // CHECK-NEXT: stable-report-filename = false
diff --git 
a/clang/test/Analysis/security-deprecated-buffer-handling-allow-without-c11.c 
b/clang/test/Analysis/security-deprecated-buffer-handling-allow-without-c11.c
new file mode 100644
index 0000000000000..880e4bbf81302
--- /dev/null
+++ 
b/clang/test/Analysis/security-deprecated-buffer-handling-allow-without-c11.c
@@ -0,0 +1,48 @@
+// Test 1: Without C11 and without flag - should NOT warn
+// RUN: %clang_analyze_cc1 %s -verify -std=gnu99 \
+// RUN:   
-analyzer-checker=security.insecureAPI.DeprecatedOrUnsafeBufferHandling \
+// RUN:   -DEXPECT_NO_WARNINGS
+
+// Test 2: Without C11 but with flag enabled - should warn
+// RUN: %clang_analyze_cc1 %s -verify -std=gnu99 \
+// RUN:   
-analyzer-checker=security.insecureAPI.DeprecatedOrUnsafeBufferHandling \
+// RUN:   -analyzer-config 
security.insecureAPI.DeprecatedOrUnsafeBufferHandling:AllowWithoutC11=true \
+// RUN:   -DEXPECT_WARNINGS
+
+// Test 3: With C11 - should warn (existing behavior)
+// RUN: %clang_analyze_cc1 %s -verify -std=gnu11 \
+// RUN:   
-analyzer-checker=security.insecureAPI.DeprecatedOrUnsafeBufferHandling \
+// RUN:   -DEXPECT_WARNINGS
+
+#include "Inputs/system-header-simulator.h"
+
+extern char buf[128];
+extern char src[128];
+
+void test_memcpy(void) {
+  memcpy(buf, src, 10);
+#ifdef EXPECT_WARNINGS
+  // expected-warning@-2{{Call to function 'memcpy' is insecure as it does not 
provide security checks introduced in the C11 standard}}
+#else
+  // expected-no-diagnostics
+#endif
+}
+
+void test_memset(void) {
+  memset(buf, 0, 10);
+#ifdef EXPECT_WARNINGS
+  // expected-warning@-2{{Call to function 'memset' is insecure as it does not 
provide security checks introduced in the C11 standard}}
+#else
+  // expected-no-diagnostics
+#endif
+}
+
+void test_memmove(void) {
+  memmove(buf, src, 10);
+#ifdef EXPECT_WARNINGS
+  // expected-warning@-2{{Call to function 'memmove' is insecure as it does 
not provide security checks introduced in the C11 standard}}
+#else
+  // expected-no-diagnostics
+#endif
+}
+

``````````

</details>


https://github.com/llvm/llvm-project/pull/168704
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to