Skip to content

[clang][analyzer] Move PutenvStackArrayChecker out of alpha package #93980

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jun 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 35 additions & 35 deletions clang/docs/analyzer/checkers.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1179,6 +1179,41 @@ security.insecureAPI.DeprecatedOrUnsafeBufferHandling (C)
strncpy(buf, "a", 1); // warn
}

.. _security-putenv-stack-array:

security.PutenvStackArray (C)
"""""""""""""""""""""""""""""
Finds calls to the ``putenv`` function which pass a pointer to a stack-allocated
(automatic) array as the argument. Function ``putenv`` does not copy the passed
string, only a pointer to the data is stored and this data can be read even by
other threads. Content of a stack-allocated array is likely to be overwritten
after exiting from the function.

The problem can be solved by using a static array variable or dynamically
allocated memory. Even better is to avoid using ``putenv`` (it has other
problems related to memory leaks) and use ``setenv`` instead.

The check corresponds to CERT rule
`POS34-C. Do not call putenv() with a pointer to an automatic variable as the argument
<https://wiki.sei.cmu.edu/confluence/display/c/POS34-C.+Do+not+call+putenv%28%29+with+a+pointer+to+an+automatic+variable+as+the+argument>`_.

.. code-block:: c

int f() {
char env[] = "NAME=value";
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 (process is terminated on all execution paths).

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.

security.SetgidSetuidOrder (C)
""""""""""""""""""""""""""""""
When dropping user-level and group-level privileges in a program by using
Expand Down Expand Up @@ -2833,41 +2868,6 @@ Warn on mmap() calls that are both writable and executable.
// code
}

.. _alpha-security-putenv-stack-array:

alpha.security.PutenvStackArray (C)
"""""""""""""""""""""""""""""""""""
Finds calls to the ``putenv`` function which pass a pointer to a stack-allocated
(automatic) array as the argument. Function ``putenv`` does not copy the passed
string, only a pointer to the data is stored and this data can be read even by
other threads. Content of a stack-allocated array is likely to be overwritten
after returning from the parent function.

The problem can be solved by using a static array variable or dynamically
allocated memory. Even better is to avoid using ``putenv`` (it has other
problems related to memory leaks) and use ``setenv`` instead.

The check corresponds to CERT rule
`POS34-C. Do not call putenv() with a pointer to an automatic variable as the argument
<https://wiki.sei.cmu.edu/confluence/display/c/POS34-C.+Do+not+call+putenv%28%29+with+a+pointer+to+an+automatic+variable+as+the+argument>`_.

.. code-block:: c

int f() {
char env[] = "NAME=value";
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)
Expand Down
10 changes: 5 additions & 5 deletions clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
Original file line number Diff line number Diff line change
Expand Up @@ -1011,6 +1011,11 @@ def FloatLoopCounter : Checker<"FloatLoopCounter">,
Dependencies<[SecuritySyntaxChecker]>,
Documentation<HasDocumentation>;

def PutenvStackArray : Checker<"PutenvStackArray">,
HelpText<"Finds calls to the function 'putenv' which pass a pointer to "
"an automatic (stack-allocated) array as the argument.">,
Documentation<HasDocumentation>;

def SetgidSetuidOrderChecker : Checker<"SetgidSetuidOrder">,
HelpText<"Warn on possible reversed order of 'setgid(getgid()))' and "
"'setuid(getuid())' (CERT: POS36-C)">,
Expand Down Expand Up @@ -1065,11 +1070,6 @@ def MmapWriteExecChecker : Checker<"MmapWriteExec">,
]>,
Documentation<HasDocumentation>;

def PutenvStackArray : Checker<"PutenvStackArray">,
HelpText<"Finds calls to the function 'putenv' which pass a pointer to "
"an automatic (stack-allocated) array as the argument.">,
Documentation<HasDocumentation>;

def ReturnPointerRangeChecker : Checker<"ReturnPtrRange">,
HelpText<"Check for an out-of-bound pointer being returned to callers">,
Documentation<HasDocumentation>;
Expand Down
2 changes: 1 addition & 1 deletion clang/test/Analysis/putenv-stack-array.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// RUN: %clang_analyze_cc1 \
// RUN: -analyzer-checker=alpha.security.PutenvStackArray \
// RUN: -analyzer-checker=security.PutenvStackArray \
// RUN: -verify %s

#include "Inputs/system-header-simulator.h"
Expand Down
Loading