Skip to content

Commit c202a17

Browse files
authored
[clang][analyzer] Move checker alpha.unix.StdCLibraryFunctions out of alpha. (#66207)
1 parent 499d41c commit c202a17

37 files changed

+214
-211
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -662,6 +662,8 @@ Static Analyzer
662662
- Added a new checker ``core.BitwiseShift`` which reports situations where
663663
bitwise shift operators produce undefined behavior (because some operand is
664664
negative or too large).
665+
- Move checker ``alpha.unix.StdCLibraryFunctions`` out of the ``alpha`` package
666+
to ``unix.StdCLibraryFunctions``.
665667

666668
- Fix false positive in mutation check when using pointer to member function.
667669
(`#66204: <https://github.com/llvm/llvm-project/issues/66204>`_).

clang/docs/analyzer/checkers.rst

Lines changed: 97 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -1016,7 +1016,7 @@ Check the size argument passed into C string functions for common erroneous patt
10161016
.. _unix-cstring-NullArg:
10171017
10181018
unix.cstring.NullArg (C)
1019-
"""""""""""""""""""""""""
1019+
""""""""""""""""""""""""
10201020
Check for null pointers being passed as arguments to C string functions:
10211021
``strlen, strnlen, strcpy, strncpy, strcat, strncat, strcmp, strncmp, strcasecmp, strncasecmp, wcslen, wcsnlen``.
10221022
@@ -1026,6 +1026,99 @@ Check for null pointers being passed as arguments to C string functions:
10261026
return strlen(0); // warn
10271027
}
10281028
1029+
.. _unix-StdCLibraryFunctions:
1030+
1031+
unix.StdCLibraryFunctions (C)
1032+
"""""""""""""""""""""""""""""
1033+
Check for calls of standard library functions that violate predefined argument
1034+
constraints. For example, according to the C standard the behavior of function
1035+
``int isalnum(int ch)`` is undefined if the value of ``ch`` is not representable
1036+
as ``unsigned char`` and is not equal to ``EOF``.
1037+
1038+
You can think of this checker as defining restrictions (pre- and postconditions)
1039+
on standard library functions. Preconditions are checked, and when they are
1040+
violated, a warning is emitted. Postconditions are added to the analysis, e.g.
1041+
that the return value of a function is not greater than 255. Preconditions are
1042+
added to the analysis too, in the case when the affected values are not known
1043+
before the call.
1044+
1045+
For example, if an argument to a function must be in between 0 and 255, but the
1046+
value of the argument is unknown, the analyzer will assume that it is in this
1047+
interval. Similarly, if a function mustn't be called with a null pointer and the
1048+
analyzer cannot prove that it is null, then it will assume that it is non-null.
1049+
1050+
These are the possible checks on the values passed as function arguments:
1051+
- The argument has an allowed range (or multiple ranges) of values. The checker
1052+
can detect if a passed value is outside of the allowed range and show the
1053+
actual and allowed values.
1054+
- The argument has pointer type and is not allowed to be null pointer. Many
1055+
(but not all) standard functions can produce undefined behavior if a null
1056+
pointer is passed, these cases can be detected by the checker.
1057+
- The argument is a pointer to a memory block and the minimal size of this
1058+
buffer is determined by another argument to the function, or by
1059+
multiplication of two arguments (like at function ``fread``), or is a fixed
1060+
value (for example ``asctime_r`` requires at least a buffer of size 26). The
1061+
checker can detect if the buffer size is too small and in optimal case show
1062+
the size of the buffer and the values of the corresponding arguments.
1063+
1064+
.. code-block:: c
1065+
1066+
#define EOF -1
1067+
void test_alnum_concrete(int v) {
1068+
int ret = isalnum(256); // \
1069+
// warning: Function argument outside of allowed range
1070+
(void)ret;
1071+
}
1072+
1073+
void buffer_size_violation(FILE *file) {
1074+
enum { BUFFER_SIZE = 1024 };
1075+
wchar_t wbuf[BUFFER_SIZE];
1076+
1077+
const size_t size = sizeof(*wbuf); // 4
1078+
const size_t nitems = sizeof(wbuf); // 4096
1079+
1080+
// Below we receive a warning because the 3rd parameter should be the
1081+
// number of elements to read, not the size in bytes. This case is a known
1082+
// vulnerability described by the ARR38-C SEI-CERT rule.
1083+
fread(wbuf, size, nitems, file);
1084+
}
1085+
1086+
int test_alnum_symbolic(int x) {
1087+
int ret = isalnum(x);
1088+
// after the call, ret is assumed to be in the range [-1, 255]
1089+
1090+
if (ret > 255) // impossible (infeasible branch)
1091+
if (x == 0)
1092+
return ret / x; // division by zero is not reported
1093+
return ret;
1094+
}
1095+
1096+
Additionally to the argument and return value conditions, this checker also adds
1097+
state of the value ``errno`` if applicable to the analysis. Many system
1098+
functions set the ``errno`` value only if an error occurs (together with a
1099+
specific return value of the function), otherwise it becomes undefined. This
1100+
checker changes the analysis state to contain such information. This data is
1101+
used by other checkers, for example :ref:`alpha-unix-Errno`.
1102+
1103+
**Limitations**
1104+
1105+
The checker can not always provide notes about the values of the arguments.
1106+
Without this information it is hard to confirm if the constraint is indeed
1107+
violated. The argument values are shown if they are known constants or the value
1108+
is determined by previous (not too complicated) assumptions.
1109+
1110+
The checker can produce false positives in cases such as if the program has
1111+
invariants not known to the analyzer engine or the bug report path contains
1112+
calls to unknown functions. In these cases the analyzer fails to detect the real
1113+
range of the argument.
1114+
1115+
**Parameters**
1116+
1117+
The checker models functions (and emits diagnostics) from the C standard by
1118+
default. The ``ModelPOSIX`` option enables modeling (and emit diagnostics) of
1119+
additional functions that are defined in the POSIX standard. This option is
1120+
disabled by default.
1121+
10291122
.. _osx-checkers:
10301123
10311124
osx
@@ -2677,101 +2770,7 @@ For a more detailed description of configuration options, please see the
26772770
file. This causes potential true positive findings to be lost.
26782771
26792772
alpha.unix
2680-
^^^^^^^^^^^
2681-
2682-
.. _alpha-unix-StdCLibraryFunctions:
2683-
2684-
alpha.unix.StdCLibraryFunctions (C)
2685-
"""""""""""""""""""""""""""""""""""
2686-
Check for calls of standard library functions that violate predefined argument
2687-
constraints. For example, it is stated in the C standard that for the ``int
2688-
isalnum(int ch)`` function the behavior is undefined if the value of ``ch`` is
2689-
not representable as unsigned char and is not equal to ``EOF``.
2690-
2691-
.. code-block:: c
2692-
2693-
#define EOF -1
2694-
void test_alnum_concrete(int v) {
2695-
int ret = isalnum(256); // \
2696-
// warning: Function argument outside of allowed range
2697-
(void)ret;
2698-
}
2699-
2700-
void buffer_size_violation(FILE *file) {
2701-
enum { BUFFER_SIZE = 1024 };
2702-
wchar_t wbuf[BUFFER_SIZE];
2703-
2704-
const size_t size = sizeof(*wbuf); // 4
2705-
const size_t nitems = sizeof(wbuf); // 4096
2706-
2707-
// Below we receive a warning because the 3rd parameter should be the
2708-
// number of elements to read, not the size in bytes. This case is a known
2709-
// vulnerability described by the ARR38-C SEI-CERT rule.
2710-
fread(wbuf, size, nitems, file);
2711-
}
2712-
2713-
You can think of this checker as defining restrictions (pre- and postconditions)
2714-
on standard library functions. Preconditions are checked, and when they are
2715-
violated, a warning is emitted. Post conditions are added to the analysis, e.g.
2716-
that the return value must be no greater than 255.
2717-
2718-
For example if an argument to a function must be in between 0 and 255, but the
2719-
value of the argument is unknown, the analyzer will conservatively assume that
2720-
it is in this interval. Similarly, if a function mustn't be called with a null
2721-
pointer and the null value of the argument can not be proven, the analyzer will
2722-
assume that it is non-null.
2723-
2724-
These are the possible checks on the values passed as function arguments:
2725-
- The argument has an allowed range (or multiple ranges) of values. The checker
2726-
can detect if a passed value is outside of the allowed range and show the
2727-
actual and allowed values.
2728-
- The argument has pointer type and is not allowed to be null pointer. Many
2729-
(but not all) standard functions can produce undefined behavior if a null
2730-
pointer is passed, these cases can be detected by the checker.
2731-
- The argument is a pointer to a memory block and the minimal size of this
2732-
buffer is determined by another argument to the function, or by
2733-
multiplication of two arguments (like at function ``fread``), or is a fixed
2734-
value (for example ``asctime_r`` requires at least a buffer of size 26). The
2735-
checker can detect if the buffer size is too small and in optimal case show
2736-
the size of the buffer and the values of the corresponding arguments.
2737-
2738-
.. code-block:: c
2739-
2740-
int test_alnum_symbolic(int x) {
2741-
int ret = isalnum(x);
2742-
// after the call, ret is assumed to be in the range [-1, 255]
2743-
2744-
if (ret > 255) // impossible (infeasible branch)
2745-
if (x == 0)
2746-
return ret / x; // division by zero is not reported
2747-
return ret;
2748-
}
2749-
2750-
Additionally to the argument and return value conditions, this checker also adds
2751-
state of the value ``errno`` if applicable to the analysis. Many system
2752-
functions set the ``errno`` value only if an error occurs (together with a
2753-
specific return value of the function), otherwise it becomes undefined. This
2754-
checker changes the analysis state to contain such information. This data is
2755-
used by other checkers, for example :ref:`alpha-unix-Errno`.
2756-
2757-
**Limitations**
2758-
2759-
The checker can not always provide notes about the values of the arguments.
2760-
Without this information it is hard to confirm if the constraint is indeed
2761-
violated. The argument values are shown if they are known constants or the value
2762-
is determined by previous (not too complicated) assumptions.
2763-
2764-
The checker can produce false positives in cases such as if the program has
2765-
invariants not known to the analyzer engine or the bug report path contains
2766-
calls to unknown functions. In these cases the analyzer fails to detect the real
2767-
range of the argument.
2768-
2769-
**Parameters**
2770-
2771-
The checker models functions (and emits diagnostics) from the C standard by
2772-
default. The ``ModelPOSIX`` option enables modeling (and emit diagnostics) of
2773-
additional functions that are defined in the POSIX standard. This option is
2774-
disabled by default.
2773+
^^^^^^^^^^
27752774
27762775
.. _alpha-unix-BlockInCriticalSection:
27772776
@@ -2840,9 +2839,9 @@ pages of the functions and in the `POSIX standard <https://pubs.opengroup.org/on
28402839
return 1;
28412840
}
28422841
2843-
The checker :ref:`alpha-unix-StdCLibraryFunctions` must be turned on to get the
2842+
The checker :ref:`unix-StdCLibraryFunctions` must be turned on to get the
28442843
warnings from this checker. The supported functions are the same as by
2845-
:ref:`alpha-unix-StdCLibraryFunctions`. The ``ModelPOSIX`` option of that
2844+
:ref:`unix-StdCLibraryFunctions`. The ``ModelPOSIX`` option of that
28462845
checker affects the set of checked functions.
28472846
28482847
**Parameters**

clang/include/clang/StaticAnalyzer/Checkers/Checkers.td

Lines changed: 22 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -532,6 +532,27 @@ def MismatchedDeallocatorChecker : Checker<"MismatchedDeallocator">,
532532
Dependencies<[DynamicMemoryModeling]>,
533533
Documentation<HasDocumentation>;
534534

535+
def StdCLibraryFunctionsChecker : Checker<"StdCLibraryFunctions">,
536+
HelpText<"Check for invalid arguments of C standard library functions, "
537+
"and apply relations between arguments and return value">,
538+
CheckerOptions<[
539+
CmdLineOption<Boolean,
540+
"DisplayLoadedSummaries",
541+
"If set to true, the checker displays the found summaries "
542+
"for the given translation unit.",
543+
"false",
544+
Released,
545+
Hide>,
546+
CmdLineOption<Boolean,
547+
"ModelPOSIX",
548+
"If set to true, the checker models additional functions "
549+
"from the POSIX standard.",
550+
"false",
551+
InAlpha>
552+
]>,
553+
WeakDependencies<[CallAndMessageChecker, NonNullParamChecker]>,
554+
Documentation<HasDocumentation>;
555+
535556
def VforkChecker : Checker<"Vfork">,
536557
HelpText<"Check for proper usage of vfork">,
537558
Documentation<HasDocumentation>;
@@ -574,27 +595,6 @@ def BlockInCriticalSectionChecker : Checker<"BlockInCriticalSection">,
574595
HelpText<"Check for calls to blocking functions inside a critical section">,
575596
Documentation<HasDocumentation>;
576597

577-
def StdCLibraryFunctionsChecker : Checker<"StdCLibraryFunctions">,
578-
HelpText<"Check for invalid arguments of C standard library functions, "
579-
"and apply relations between arguments and return value">,
580-
CheckerOptions<[
581-
CmdLineOption<Boolean,
582-
"DisplayLoadedSummaries",
583-
"If set to true, the checker displays the found summaries "
584-
"for the given translation unit.",
585-
"false",
586-
Released,
587-
Hide>,
588-
CmdLineOption<Boolean,
589-
"ModelPOSIX",
590-
"If set to true, the checker models additional functions "
591-
"from the POSIX standard.",
592-
"false",
593-
InAlpha>
594-
]>,
595-
WeakDependencies<[CallAndMessageChecker, NonNullParamChecker, StreamChecker]>,
596-
Documentation<HasDocumentation>;
597-
598598
} // end "alpha.unix"
599599

600600
//===----------------------------------------------------------------------===//
@@ -1627,6 +1627,7 @@ def DebugIteratorModeling : Checker<"DebugIteratorModeling">,
16271627
def StdCLibraryFunctionsTesterChecker : Checker<"StdCLibraryFunctionsTester">,
16281628
HelpText<"Add test functions to the summary map, so testing of individual "
16291629
"summary constituents becomes possible.">,
1630+
WeakDependencies<[StdCLibraryFunctionsChecker]>,
16301631
Documentation<NotDocumented>;
16311632

16321633
} // end "debug"

clang/test/Analysis/PR49642.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// RUN: %clang_analyze_cc1 -Wno-implicit-function-declaration -Wno-implicit-int -w -verify %s \
22
// RUN: -analyzer-checker=core \
3-
// RUN: -analyzer-checker=alpha.unix.StdCLibraryFunctions
3+
// RUN: -analyzer-checker=unix.StdCLibraryFunctions
44

55
// expected-no-diagnostics
66

clang/test/Analysis/analyzer-config.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,6 @@
1313
// CHECK-NEXT: alpha.security.MmapWriteExec:MmapProtRead = 0x01
1414
// CHECK-NEXT: alpha.security.taint.TaintPropagation:Config = ""
1515
// CHECK-NEXT: alpha.unix.Errno:AllowErrnoReadOutsideConditionExpressions = true
16-
// CHECK-NEXT: alpha.unix.StdCLibraryFunctions:DisplayLoadedSummaries = false
17-
// CHECK-NEXT: alpha.unix.StdCLibraryFunctions:ModelPOSIX = false
1816
// CHECK-NEXT: apply-fixits = false
1917
// CHECK-NEXT: assume-controlled-environment = false
2018
// CHECK-NEXT: avoid-suppressing-null-argument-paths = false
@@ -129,6 +127,8 @@
129127
// CHECK-NEXT: track-conditions-debug = false
130128
// CHECK-NEXT: unix.DynamicMemoryModeling:AddNoOwnershipChangeNotes = true
131129
// CHECK-NEXT: unix.DynamicMemoryModeling:Optimistic = false
130+
// CHECK-NEXT: unix.StdCLibraryFunctions:DisplayLoadedSummaries = false
131+
// CHECK-NEXT: unix.StdCLibraryFunctions:ModelPOSIX = false
132132
// CHECK-NEXT: unroll-loops = false
133133
// CHECK-NEXT: verbose-report-filename = false
134134
// CHECK-NEXT: widen-loops = false

clang/test/Analysis/analyzer-enabled-checkers.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
// CHECK-NEXT: unix.Malloc
4848
// CHECK-NEXT: unix.MallocSizeof
4949
// CHECK-NEXT: unix.MismatchedDeallocator
50+
// CHECK-NEXT: unix.StdCLibraryFunctions
5051
// CHECK-NEXT: unix.Vfork
5152
// CHECK-NEXT: unix.cstring.BadSizeArg
5253
// CHECK-NEXT: unix.cstring.NullArg

clang/test/Analysis/conversion.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// RUN: %clang_analyze_cc1 %s \
22
// RUN: -Wno-conversion -Wno-tautological-constant-compare \
3-
// RUN: -analyzer-checker=core,apiModeling,alpha.unix.StdCLibraryFunctions,alpha.core.Conversion \
3+
// RUN: -analyzer-checker=core,apiModeling,unix.StdCLibraryFunctions,alpha.core.Conversion \
44
// RUN: -verify
55

66
unsigned char U8;
@@ -187,7 +187,7 @@ char dontwarn10(long long x) {
187187
}
188188

189189

190-
// C library functions, handled via alpha.unix.StdCLibraryFunctions
190+
// C library functions, handled via unix.StdCLibraryFunctions
191191

192192
int isascii(int c);
193193
void libraryFunction1(void) {

clang/test/Analysis/errno-stdlibraryfunctions-notes.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
// RUN: %clang_analyze_cc1 -verify -analyzer-output text %s \
22
// RUN: -analyzer-checker=core \
33
// RUN: -analyzer-checker=debug.ExprInspection \
4-
// RUN: -analyzer-checker=alpha.unix.StdCLibraryFunctions \
4+
// RUN: -analyzer-checker=unix.StdCLibraryFunctions \
55
// RUN: -analyzer-checker=apiModeling.Errno \
66
// RUN: -analyzer-checker=alpha.unix.Errno \
7-
// RUN: -analyzer-config alpha.unix.StdCLibraryFunctions:ModelPOSIX=true
7+
// RUN: -analyzer-config unix.StdCLibraryFunctions:ModelPOSIX=true
88

99
#include "Inputs/errno_var.h"
1010

clang/test/Analysis/errno-stdlibraryfunctions.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
// RUN: %clang_analyze_cc1 -verify %s \
22
// RUN: -analyzer-checker=core \
33
// RUN: -analyzer-checker=debug.ExprInspection \
4-
// RUN: -analyzer-checker=alpha.unix.StdCLibraryFunctions \
4+
// RUN: -analyzer-checker=unix.StdCLibraryFunctions \
55
// RUN: -analyzer-checker=apiModeling.Errno \
66
// RUN: -analyzer-checker=alpha.unix.Errno \
7-
// RUN: -analyzer-config alpha.unix.StdCLibraryFunctions:ModelPOSIX=true
7+
// RUN: -analyzer-config unix.StdCLibraryFunctions:ModelPOSIX=true
88

99
#include "Inputs/errno_var.h"
1010

clang/test/Analysis/std-c-library-functions-POSIX-lookup.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
// RUN: %clang_analyze_cc1 %s \
22
// RUN: -analyzer-checker=core \
3-
// RUN: -analyzer-checker=alpha.unix.StdCLibraryFunctions \
4-
// RUN: -analyzer-config alpha.unix.StdCLibraryFunctions:ModelPOSIX=true \
5-
// RUN: -analyzer-config alpha.unix.StdCLibraryFunctions:DisplayLoadedSummaries=true \
3+
// RUN: -analyzer-checker=unix.StdCLibraryFunctions \
4+
// RUN: -analyzer-config unix.StdCLibraryFunctions:ModelPOSIX=true \
5+
// RUN: -analyzer-config unix.StdCLibraryFunctions:DisplayLoadedSummaries=true \
66
// RUN: -analyzer-checker=debug.ExprInspection \
77
// RUN: -analyzer-config eagerly-assume=false \
88
// RUN: -triple i686-unknown-linux 2>&1 | FileCheck %s --allow-empty

clang/test/Analysis/std-c-library-functions-POSIX-socket-sockaddr.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
// RUN: %clang_analyze_cc1 %s \
22
// RUN: -analyzer-checker=core \
3-
// RUN: -analyzer-checker=alpha.unix.StdCLibraryFunctions \
4-
// RUN: -analyzer-config alpha.unix.StdCLibraryFunctions:ModelPOSIX=true \
5-
// RUN: -analyzer-config alpha.unix.StdCLibraryFunctions:DisplayLoadedSummaries=true \
3+
// RUN: -analyzer-checker=unix.StdCLibraryFunctions \
4+
// RUN: -analyzer-config unix.StdCLibraryFunctions:ModelPOSIX=true \
5+
// RUN: -analyzer-config unix.StdCLibraryFunctions:DisplayLoadedSummaries=true \
66
// RUN: -analyzer-checker=debug.ExprInspection \
77
// RUN: -analyzer-config eagerly-assume=false \
88
// RUN: -triple i686-unknown-linux 2>&1 | FileCheck %s

0 commit comments

Comments
 (0)