Skip to content

Commit 76b9d38

Browse files
authored
[clang][analyzer] PutenvStackArrayChecker: No warning from 'main' (llvm#93299)
1 parent 0f85b25 commit 76b9d38

File tree

3 files changed

+37
-2
lines changed

3 files changed

+37
-2
lines changed

clang/docs/analyzer/checkers.rst

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2858,6 +2858,16 @@ The check corresponds to CERT rule
28582858
return putenv(env); // putenv function should not be called with stack-allocated string
28592859
}
28602860
2861+
There is one case where the checker can report a false positive. This is when
2862+
the stack-allocated array is used at `putenv` in a function or code branch that
2863+
does not return (calls `fork` or `exec` like function).
2864+
2865+
Another special case is if the `putenv` is called from function `main`. Here
2866+
the stack is deallocated at the end of the program and it should be no problem
2867+
to use the stack-allocated string (a multi-threaded program may require more
2868+
attention). The checker does not warn for cases when stack space of `main` is
2869+
used at the `putenv` call.
2870+
28612871
.. _alpha-security-ReturnPtrRange:
28622872
28632873
alpha.security.ReturnPtrRange (C)

clang/lib/StaticAnalyzer/Checkers/PutenvStackArrayChecker.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,14 @@ void PutenvStackArrayChecker::checkPostCall(const CallEvent &Call,
4444

4545
SVal ArgV = Call.getArgSVal(0);
4646
const Expr *ArgExpr = Call.getArgExpr(0);
47-
const MemSpaceRegion *MSR = ArgV.getAsRegion()->getMemorySpace();
4847

49-
if (!isa<StackSpaceRegion>(MSR))
48+
const auto *SSR =
49+
dyn_cast<StackSpaceRegion>(ArgV.getAsRegion()->getMemorySpace());
50+
if (!SSR)
51+
return;
52+
const auto *StackFrameFuncD =
53+
dyn_cast_or_null<FunctionDecl>(SSR->getStackFrame()->getDecl());
54+
if (StackFrameFuncD && StackFrameFuncD->isMain())
5055
return;
5156

5257
StringRef ErrorMsg = "The 'putenv' function should not be called with "

clang/test/Analysis/putenv-stack-array.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,15 @@ int test_auto_var_subarray() {
4545
return putenv(env + 100); // expected-warning{{The 'putenv' function should not be called with}}
4646
}
4747

48+
int f_test_auto_var_call(char *env) {
49+
return putenv(env); // expected-warning{{The 'putenv' function should not be called with}}
50+
}
51+
52+
int test_auto_var_call() {
53+
char env[1024];
54+
return f_test_auto_var_call(env);
55+
}
56+
4857
int test_constant() {
4958
char *env = "TEST";
5059
return putenv(env); // no-warning: data is not on the stack
@@ -68,3 +77,14 @@ void test_auto_var_reset() {
6877
// become invalid.
6978
putenv((char *)"NAME=anothervalue");
7079
}
80+
81+
void f_main(char *env) {
82+
putenv(env); // no warning: string allocated in stack of 'main'
83+
}
84+
85+
int main(int argc, char **argv) {
86+
char env[] = "NAME=value";
87+
putenv(env); // no warning: string allocated in stack of 'main'
88+
f_main(env);
89+
return 0;
90+
}

0 commit comments

Comments
 (0)