https://github.com/necto updated https://github.com/llvm/llvm-project/pull/107003
>From da5671efccd0ba56a0dd983b04d1f798c5c35d0d Mon Sep 17 00:00:00 2001 From: Arseniy Zaostrovnykh <necto...@gmail.com> Date: Mon, 2 Sep 2024 17:13:14 +0200 Subject: [PATCH 1/2] [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 >From 8a9a76a3d1b19d8d2434e8c6de7fe41fe8cd8756 Mon Sep 17 00:00:00 2001 From: Arseniy Zaostrovnykh <necto...@gmail.com> Date: Tue, 3 Sep 2024 04:20:56 +0200 Subject: [PATCH 2/2] Add tests --- clang/test/Analysis/stack-addr-ps.cpp | 36 ++++++++++++++++++++++++--- 1 file changed, 32 insertions(+), 4 deletions(-) diff --git a/clang/test/Analysis/stack-addr-ps.cpp b/clang/test/Analysis/stack-addr-ps.cpp index 3c922dfb0ed454..35f38fbbfbefdc 100644 --- a/clang/test/Analysis/stack-addr-ps.cpp +++ b/clang/test/Analysis/stack-addr-ps.cpp @@ -137,7 +137,7 @@ namespace rdar13296133 { ConvertsToPointer obj; return obj; // no-warning } -} +} // namespace rdar13296133 void write_stack_address_to(char **q) { char local; @@ -793,9 +793,28 @@ void global_ptr_to_ptr() { } // namespace leaking_via_indirect_global_invalidated namespace not_leaking_via_simple_ptr { -void top(const char *p) { - char tmp; - p = &tmp; +void simple_ptr(const char *p) { + char tmp; + p = &tmp; // no-warning +} + +void ref_ptr(const char *&p) { + char tmp; + p = &tmp; // expected-warning{{variable 'tmp' is still referred to by the caller variable 'p'}} +} + +struct S { + const char *p; +}; + +void struct_ptr(S s) { + char tmp; + s.p = &tmp; // no-warning +} + +void array(const char arr[2]) { + char tmp; + arr = &tmp; // no-warning } extern void copy(char *output, const char *input, unsigned size); @@ -818,3 +837,12 @@ void repo(const char *input, char *output) { } } } // namespace not_leaking_via_simple_ptr + +namespace early_reclaim_dead_limitation { +void foo(); +void top(char **p) { + char local; + *p = &local; + foo(); // no-warning FIXME: p binding is reclaimed before the function end +} +} // namespace early_reclaim_dead_limitation _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits