[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