[clang] [analyzer] Fix false positive for stack-addr leak on simple param ptr (PR #107003)

via cfe-commits cfe-commits at lists.llvm.org
Mon Sep 2 08:35:08 PDT 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

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

Author: Arseniy Zaostrovnykh (necto)

<details>
<summary>Changes</summary>

Assigning to a pointer parameter does not leak the stack address because it stays within the function and is not shared with the caller.

Previous implementation reported any association of a pointer parameter with a local address, which is too broad.

This fix enforces that the pointer to a stack variable is related by at least one level of indirection.

CPP-5642

Fixes #<!-- -->106834

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


2 Files Affected:

- (modified) clang/lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp (+2) 
- (modified) clang/test/Analysis/stack-addr-ps.cpp (+27) 


``````````diff
diff --git a/clang/lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp
index ec577c36188e6c..5394c2257514dc 100644
--- a/clang/lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp
@@ -420,6 +420,8 @@ void StackAddrEscapeChecker::checkEndFunction(const ReturnStmt *RS,
         return true;
       }
       if (isa<StackArgumentsSpaceRegion>(ReferrerMemSpace) &&
+          // Not a simple ptr (int*) but something deeper, e.g. int**
+          isa<SymbolicRegion>(Referrer->getBaseRegion()) &&
           ReferrerStackSpace->getStackFrame() == PoppedFrame && TopFrame) {
         // Output parameter of a top-level function
         V.emplace_back(Referrer, Referred);
diff --git a/clang/test/Analysis/stack-addr-ps.cpp b/clang/test/Analysis/stack-addr-ps.cpp
index 88bf6512165201..3c922dfb0ed454 100644
--- a/clang/test/Analysis/stack-addr-ps.cpp
+++ b/clang/test/Analysis/stack-addr-ps.cpp
@@ -791,3 +791,30 @@ void global_ptr_to_ptr() {
   *global_pp = nullptr;
 }
 } // namespace leaking_via_indirect_global_invalidated
+
+namespace not_leaking_via_simple_ptr {
+void top(const char *p) {
+    char tmp;
+    p = &tmp;
+}
+
+extern void copy(char *output, const char *input, unsigned size);
+extern bool foo(const char *input);
+extern void bar(char *output, unsigned count);
+extern bool baz(char *output, const char *input);
+
+void repo(const char *input, char *output) {
+  char temp[64];
+  copy(temp, input, sizeof(temp));
+
+  char result[64];
+  input = temp;
+  if (foo(temp)) {
+    bar(result, sizeof(result));
+    input = result;
+  }
+  if (!baz(output, input)) {
+    copy(output, input, sizeof(result));
+  }
+}
+} // namespace not_leaking_via_simple_ptr

``````````

</details>


https://github.com/llvm/llvm-project/pull/107003


More information about the cfe-commits mailing list