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

Arseniy Zaostrovnykh via cfe-commits cfe-commits at lists.llvm.org
Mon Sep 2 08:34:37 PDT 2024


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

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

>From da5671efccd0ba56a0dd983b04d1f798c5c35d0d Mon Sep 17 00:00:00 2001
From: Arseniy Zaostrovnykh <necto.ne at gmail.com>
Date: Mon, 2 Sep 2024 17:13:14 +0200
Subject: [PATCH] [analyzer] Fix false positive for stack-addr leak on simple
 param ptr

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
---
 .../Checkers/StackAddrEscapeChecker.cpp       |  2 ++
 clang/test/Analysis/stack-addr-ps.cpp         | 27 +++++++++++++++++++
 2 files changed, 29 insertions(+)

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



More information about the cfe-commits mailing list