Author: Balázs Kéri Date: 2024-05-27T09:55:10+02:00 New Revision: 76b9d38934572909ffc8c8ef4cd45407f22e6ea7
URL: https://github.com/llvm/llvm-project/commit/76b9d38934572909ffc8c8ef4cd45407f22e6ea7 DIFF: https://github.com/llvm/llvm-project/commit/76b9d38934572909ffc8c8ef4cd45407f22e6ea7.diff LOG: [clang][analyzer] PutenvStackArrayChecker: No warning from 'main' (#93299) Added: Modified: clang/docs/analyzer/checkers.rst clang/lib/StaticAnalyzer/Checkers/PutenvStackArrayChecker.cpp clang/test/Analysis/putenv-stack-array.c Removed: ################################################################################ diff --git a/clang/docs/analyzer/checkers.rst b/clang/docs/analyzer/checkers.rst index ac9f0b06f63ba..3a31708a1e9de 100644 --- a/clang/docs/analyzer/checkers.rst +++ b/clang/docs/analyzer/checkers.rst @@ -2858,6 +2858,16 @@ The check corresponds to CERT rule return putenv(env); // putenv function should not be called with stack-allocated string } +There is one case where the checker can report a false positive. This is when +the stack-allocated array is used at `putenv` in a function or code branch that +does not return (calls `fork` or `exec` like function). + +Another special case is if the `putenv` is called from function `main`. Here +the stack is deallocated at the end of the program and it should be no problem +to use the stack-allocated string (a multi-threaded program may require more +attention). The checker does not warn for cases when stack space of `main` is +used at the `putenv` call. + .. _alpha-security-ReturnPtrRange: alpha.security.ReturnPtrRange (C) diff --git a/clang/lib/StaticAnalyzer/Checkers/PutenvStackArrayChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/PutenvStackArrayChecker.cpp index d59cebf0aa5cb..bf81d57bf82fd 100644 --- a/clang/lib/StaticAnalyzer/Checkers/PutenvStackArrayChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/PutenvStackArrayChecker.cpp @@ -44,9 +44,14 @@ void PutenvStackArrayChecker::checkPostCall(const CallEvent &Call, SVal ArgV = Call.getArgSVal(0); const Expr *ArgExpr = Call.getArgExpr(0); - const MemSpaceRegion *MSR = ArgV.getAsRegion()->getMemorySpace(); - if (!isa<StackSpaceRegion>(MSR)) + const auto *SSR = + dyn_cast<StackSpaceRegion>(ArgV.getAsRegion()->getMemorySpace()); + if (!SSR) + return; + const auto *StackFrameFuncD = + dyn_cast_or_null<FunctionDecl>(SSR->getStackFrame()->getDecl()); + if (StackFrameFuncD && StackFrameFuncD->isMain()) return; StringRef ErrorMsg = "The 'putenv' function should not be called with " diff --git a/clang/test/Analysis/putenv-stack-array.c b/clang/test/Analysis/putenv-stack-array.c index fbbf93259ab85..f28aed73031d3 100644 --- a/clang/test/Analysis/putenv-stack-array.c +++ b/clang/test/Analysis/putenv-stack-array.c @@ -45,6 +45,15 @@ int test_auto_var_subarray() { return putenv(env + 100); // expected-warning{{The 'putenv' function should not be called with}} } +int f_test_auto_var_call(char *env) { + return putenv(env); // expected-warning{{The 'putenv' function should not be called with}} +} + +int test_auto_var_call() { + char env[1024]; + return f_test_auto_var_call(env); +} + int test_constant() { char *env = "TEST"; return putenv(env); // no-warning: data is not on the stack @@ -68,3 +77,14 @@ void test_auto_var_reset() { // become invalid. putenv((char *)"NAME=anothervalue"); } + +void f_main(char *env) { + putenv(env); // no warning: string allocated in stack of 'main' +} + +int main(int argc, char **argv) { + char env[] = "NAME=value"; + putenv(env); // no warning: string allocated in stack of 'main' + f_main(env); + return 0; +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits