Skip to content

Commit da50d28

Browse files
committed
null-library-function-cpp
1 parent 46ee833 commit da50d28

File tree

3 files changed

+243
-0
lines changed

3 files changed

+243
-0
lines changed
Lines changed: 193 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
id: null-library-function-cpp
2+
language: Cpp
3+
severity: warning
4+
message: >-
5+
The `$SOURCE` function returns NULL on error and this line dereferences
6+
the return value without checking for NULL.
7+
note: >-
8+
[CWE-476] NULL Pointer Dereference.
9+
[REFERENCES]
10+
- https://wiki.sei.cmu.edu/confluence/display/c/EXP34-C.+Do+not+dereference+null+pointers
11+
utils:
12+
MATCH_PATTERN_ONE:
13+
kind: return_statement
14+
has:
15+
stopBy: neighbor
16+
kind: field_expression
17+
has:
18+
stopBy: neighbor
19+
kind: call_expression
20+
all:
21+
- has:
22+
stopBy: neighbor
23+
kind: identifier
24+
regex: "^fgets|::fgets|std::fgets|fopen|::fopen|std::fopen|getenv|::getenv|std::getenv|getgrent|::getgrent|std::getgrent|getgrgid|::getgrgid|std::getgrgid|getgrnam|::getgrnam|std::getgrnam|getlogin|::getlogin|std::getlogin|getpwent|::getpwent|std::getpwent|getpwnam|::getpwnam|std::getpwnam|getpwuid|::getpwuid|std::getpwuid|getpwuuid|::getpwuuid|std::getpwuuid|gets|::gets|std::gets|inet_ntop|::inet_ntop|std::inet_ntop|realpath|::realpath|std::realpath|tempnam|::tempnam|std::tempnam|tmpfile|::tmpfile|std::tmpfile|tmpnam|::tmpnam|std::tmpnam|memchr|::memchr|std::memchr|strcasestr_l|::strcasestr_l|std::strcasestr_l|strcasestr|::strcasestr|std::strcasestr|strchr|::strchr|std::strchr|strnstr|::strnstr|std::strnstr|strpbrk|::strpbrk|std::strpbrk|strrchr|::strrchr|std::strrchr|strstr|::strstr|std::strstr|strtok_r|::strtok_r|std::strtok_r|strtok|::strtok|std::strtok$"
25+
26+
MATCH_PATTERN_TWO:
27+
kind: subscript_expression
28+
all:
29+
- has:
30+
stopBy: neighbor
31+
kind: call_expression
32+
all:
33+
- has:
34+
stopBy: neighbor
35+
kind: identifier
36+
regex: "^fgets|::fgets|std::fgets|fopen|::fopen|std::fopen|getenv|::getenv|std::getenv|getgrent|::getgrent|std::getgrent|getgrgid|::getgrgid|std::getgrgid|getgrnam|::getgrnam|std::getgrnam|getlogin|::getlogin|std::getlogin|getpwent|::getpwent|std::getpwent|getpwnam|::getpwnam|std::getpwnam|getpwuid|::getpwuid|std::getpwuid|getpwuuid|::getpwuuid|std::getpwuuid|gets|::gets|std::gets|inet_ntop|::inet_ntop|std::inet_ntop|realpath|::realpath|std::realpath|tempnam|::tempnam|std::tempnam|tmpfile|::tmpfile|std::tmpfile|tmpnam|::tmpnam|std::tmpnam|memchr|::memchr|std::memchr|strcasestr_l|::strcasestr_l|std::strcasestr_l|strcasestr|::strcasestr|std::strcasestr|strchr|::strchr|std::strchr|strnstr|::strnstr|std::strnstr|strpbrk|::strpbrk|std::strpbrk|strrchr|::strrchr|std::strrchr|strstr|::strstr|std::strstr|strtok_r|::strtok_r|std::strtok_r|strtok|::strtok|std::strtok$"
37+
- has:
38+
stopBy: neighbor
39+
kind: argument_list
40+
has:
41+
stopBy: neighbor
42+
kind: string_literal
43+
has:
44+
stopBy: neighbor
45+
kind: string_content
46+
- has:
47+
stopBy: neighbor
48+
kind: subscript_argument_list
49+
has:
50+
stopBy: neighbor
51+
pattern: $$$
52+
53+
MATCH_PATTERN_THREE:
54+
kind: call_expression
55+
all:
56+
- has:
57+
stopBy: neighbor
58+
kind: identifier
59+
regex: "^atof|::atof|std::atof|atoi|::atoi|std::atoi|atol_l|::atol_l|std::atol_l|atol|::atol|std::atol|atoll_l|::atoll_l|std::atoll_l|atoll|::atoll|std::atoll|getc|::getc|std::getc|fprintf|::fprintf|std::fprintf|fgetpos|::fgetpos|std::fgetpos|fseek|::fseek|std::fseek|fseeko|::fseeko|std::fseeko|fsetpos|::fsetpos|std::fsetpos|ftell|::ftell|std::ftell|ftello|::ftello|std::ftello|rewind|::rewind|std::rewind|strlen|::strlen|std::strlen|strtoimax|::strtoimax|std::strtoimax|strtod|::strtod|std::strtod|strtol|::strtol|std::strtol|strtoul|::strtoul|std::strtoul|strtoll|::strtoll|std::strtoll|strtoq|::strtoq|std::strtoq$"
60+
- has:
61+
stopBy: neighbor
62+
kind: argument_list
63+
has:
64+
stopBy: neighbor
65+
kind: call_expression
66+
all:
67+
- has:
68+
stopBy: neighbor
69+
kind: identifier
70+
regex: "^fgets|::fgets|std::fgets|fopen|::fopen|std::fopen|getenv|::getenv|std::getenv|getgrent|::getgrent|std::getgrent|getgrgid|::getgrgid|std::getgrgid|getgrnam|::getgrnam|std::getgrnam|getlogin|::getlogin|std::getlogin|getpwent|::getpwent|std::getpwent|getpwnam|::getpwnam|std::getpwnam|getpwuid|::getpwuid|std::getpwuid|getpwuuid|::getpwuuid|std::getpwuuid|gets|::gets|std::gets|inet_ntop|::inet_ntop|std::inet_ntop|realpath|::realpath|std::realpath|tempnam|::tempnam|std::tempnam|tmpfile|::tmpfile|std::tmpfile|tmpnam|::tmpnam|std::tmpnam|memchr|::memchr|std::memchr|strcasestr_l|::strcasestr_l|std::strcasestr_l|strcasestr|::strcasestr|std::strcasestr|strchr|::strchr|std::strchr|strnstr|::strnstr|std::strnstr|strpbrk|::strpbrk|std::strpbrk|strrchr|::strrchr|std::strrchr|strstr|::strstr|std::strstr|strtok_r|::strtok_r|std::strtok_r|strtok|::strtok|std::strtok$"
71+
- has:
72+
stopBy: end
73+
kind: argument_list
74+
75+
MATCH_PATTERN_FOUR:
76+
kind: call_expression
77+
all:
78+
- has:
79+
stopBy: neighbor
80+
kind: identifier
81+
regex: "^atof|::atof|std::atof|atoi|::atoi|std::atoi|atol_l|::atol_l|std::atol_l|atol|::atol|std::atol|atoll_l|::atoll_l|std::atoll_l|atoll|::atoll|std::atoll|getc|::getc|std::getc|fprintf|::fprintf|std::fprintf|fgetpos|::fgetpos|std::fgetpos|fseek|::fseek|std::fseek|fseeko|::fseeko|std::fseeko|fsetpos|::fsetpos|std::fsetpos|ftell|::ftell|std::ftell|ftello|::ftello|std::ftello|rewind|::rewind|std::rewind|strlen|::strlen|std::strlen|strtoimax|::strtoimax|std::strtoimax|strtod|::strtod|std::strtod|strtol|::strtol|std::strtol|strtoul|::strtoul|std::strtoul|strtoll|::strtoll|std::strtoll|strtoq|::strtoq|std::strtoq$"
82+
- has:
83+
stopBy: neighbor
84+
kind: argument_list
85+
has:
86+
stopBy: neighbor
87+
kind: assignment_expression
88+
all:
89+
- has:
90+
stopBy: neighbor
91+
kind: identifier
92+
- has:
93+
stopBy: neighbor
94+
regex: "="
95+
- has:
96+
stopBy: neighbor
97+
kind: call_expression
98+
all:
99+
- has:
100+
stopBy: neighbor
101+
kind: identifier
102+
regex: "^fgets|::fgets|std::fgets|fopen|::fopen|std::fopen|getenv|::getenv|std::getenv|getgrent|::getgrent|std::getgrent|getgrgid|::getgrgid|std::getgrgid|getgrnam|::getgrnam|std::getgrnam|getlogin|::getlogin|std::getlogin|getpwent|::getpwent|std::getpwent|getpwnam|::getpwnam|std::getpwnam|getpwuid|::getpwuid|std::getpwuid|getpwuuid|::getpwuuid|std::getpwuuid|gets|::gets|std::gets|inet_ntop|::inet_ntop|std::inet_ntop|realpath|::realpath|std::realpath|tempnam|::tempnam|std::tempnam|tmpfile|::tmpfile|std::tmpfile|tmpnam|::tmpnam|std::tmpnam|memchr|::memchr|std::memchr|strcasestr_l|::strcasestr_l|std::strcasestr_l|strcasestr|::strcasestr|std::strcasestr|strchr|::strchr|std::strchr|strnstr|::strnstr|std::strnstr|strpbrk|::strpbrk|std::strpbrk|strrchr|::strrchr|std::strrchr|strstr|::strstr|std::strstr|strtok_r|::strtok_r|std::strtok_r|strtok|::strtok|std::strtok$"
103+
- has:
104+
stopBy: neighbor
105+
kind: argument_list
106+
107+
MATCH_PATTERN_FIVE:
108+
kind: call_expression
109+
all:
110+
- has:
111+
stopBy: neighbor
112+
kind: identifier
113+
regex: "^bcopy|::bcopy|std::bcopy|memccpy|::memccpy|std::memccpy|memcpy|::memcpy|std::memcpy|memmove|::memmove|std::memmove|stpncpy|::stpncpy|std::stpncpy|strcat|::strcat|std::strcat|strcpy|::strcpy|std::strcpy|strcpy|::strcpy|std::strcpy|strlcat|::strlcat|std::strlcat|strlcpy|::strlcpy|std::strlcpy|strncat|::strncat|std::strncat|strpcpy|::strpcpy|std::strpcpy|wcpcpy|::wcpcpy|std::wcpcpy|wcpncpy|::wcpncpy|std::wcpncpy$"
114+
- has:
115+
stopBy: neighbor
116+
kind: argument_list
117+
all:
118+
- has:
119+
stopBy: neighbor
120+
pattern: $$$
121+
- has:
122+
stopBy: neighbor
123+
kind: call_expression
124+
all:
125+
- has:
126+
stopBy: neighbor
127+
kind: identifier
128+
regex: "^fgets|::fgets|std::fgets|fopen|::fopen|std::fopen|getenv|::getenv|std::getenv|getgrent|::getgrent|std::getgrent|getgrgid|::getgrgid|std::getgrgid|getgrnam|::getgrnam|std::getgrnam|getlogin|::getlogin|std::getlogin|getpwent|::getpwent|std::getpwent|getpwnam|::getpwnam|std::getpwnam|getpwuid|::getpwuid|std::getpwuid|getpwuuid|::getpwuuid|std::getpwuuid|gets|::gets|std::gets|inet_ntop|::inet_ntop|std::inet_ntop|realpath|::realpath|std::realpath|tempnam|::tempnam|std::tempnam|tmpfile|::tmpfile|std::tmpfile|tmpnam|::tmpnam|std::tmpnam|memchr|::memchr|std::memchr|strcasestr_l|::strcasestr_l|std::strcasestr_l|strcasestr|::strcasestr|std::strcasestr|strchr|::strchr|std::strchr|strnstr|::strnstr|std::strnstr|strpbrk|::strpbrk|std::strpbrk|strrchr|::strrchr|std::strrchr|strstr|::strstr|std::strstr|strtok_r|::strtok_r|std::strtok_r|strtok|::strtok|std::strtok$"
129+
- has:
130+
stopBy: neighbor
131+
kind: argument_list
132+
has:
133+
stopBy: neighbor
134+
pattern: $$$
135+
136+
MATCH_PATTERN_SIX:
137+
kind: call_expression
138+
all:
139+
- has:
140+
stopBy: neighbor
141+
kind: identifier
142+
regex: "^fwrite|::fwrite|std::fwrite$"
143+
- has:
144+
stopBy: neighbor
145+
kind: argument_list
146+
has:
147+
stopBy: end
148+
kind: call_expression
149+
all:
150+
- has:
151+
stopBy: neighbor
152+
kind: identifier
153+
regex: "^fgets|::fgets|std::fgets|fopen|::fopen|std::fopen|getenv|::getenv|std::getenv|getgrent|::getgrent|std::getgrent|getgrgid|::getgrgid|std::getgrgid|getgrnam|::getgrnam|std::getgrnam|getlogin|::getlogin|std::getlogin|getpwent|::getpwent|std::getpwent|getpwnam|::getpwnam|std::getpwnam|getpwuid|::getpwuid|std::getpwuid|getpwuuid|::getpwuuid|std::getpwuuid|gets|::gets|std::gets|inet_ntop|::inet_ntop|std::inet_ntop|realpath|::realpath|std::realpath|tempnam|::tempnam|std::tempnam|tmpfile|::tmpfile|std::tmpfile|tmpnam|::tmpnam|std::tmpnam|memchr|::memchr|std::memchr|strcasestr_l|::strcasestr_l|std::strcasestr_l|strcasestr|::strcasestr|std::strcasestr|strchr|::strchr|std::strchr|strnstr|::strnstr|std::strnstr|strpbrk|::strpbrk|std::strpbrk|strrchr|::strrchr|std::strrchr|strstr|::strstr|std::strstr|strtok_r|::strtok_r|std::strtok_r|strtok|::strtok|std::strtok$"
154+
- has:
155+
stopBy: neighbor
156+
kind: argument_list
157+
158+
MATCH_PATTERN_SEVEN:
159+
kind: subscript_expression
160+
all:
161+
- has:
162+
stopBy: neighbor
163+
kind: parenthesized_expression
164+
has:
165+
stopBy: neighbor
166+
kind: call_expression
167+
all:
168+
- has:
169+
stopBy: neighbor
170+
kind: identifier
171+
regex: "^fgets|::fgets|std::fgets|fopen|::fopen|std::fopen|getenv|::getenv|std::getenv|getgrent|::getgrent|std::getgrent|getgrgid|::getgrgid|std::getgrgid|getgrnam|::getgrnam|std::getgrnam|getlogin|::getlogin|std::getlogin|getpwent|::getpwent|std::getpwent|getpwnam|::getpwnam|std::getpwnam|getpwuid|::getpwuid|std::getpwuid|getpwuuid|::getpwuuid|std::getpwuuid|gets|::gets|std::gets|inet_ntop|::inet_ntop|std::inet_ntop|realpath|::realpath|std::realpath|tempnam|::tempnam|std::tempnam|tmpfile|::tmpfile|std::tmpfile|tmpnam|::tmpnam|std::tmpnam|memchr|::memchr|std::memchr|strcasestr_l|::strcasestr_l|std::strcasestr_l|strcasestr|::strcasestr|std::strcasestr|strchr|::strchr|std::strchr|strnstr|::strnstr|std::strnstr|strpbrk|::strpbrk|std::strpbrk|strrchr|::strrchr|std::strrchr|strstr|::strstr|std::strstr|strtok_r|::strtok_r|std::strtok_r|strtok|::strtok|std::strtok$"
172+
- has:
173+
stopBy: neighbor
174+
kind: subscript_argument_list
175+
has:
176+
stopBy: neighbor
177+
pattern: $$$
178+
179+
rule:
180+
any:
181+
- kind: return_statement
182+
any:
183+
- matches: MATCH_PATTERN_ONE
184+
- kind: subscript_expression
185+
any:
186+
- matches: MATCH_PATTERN_TWO
187+
- matches: MATCH_PATTERN_SEVEN
188+
- kind: call_expression
189+
any:
190+
- matches: MATCH_PATTERN_THREE
191+
- matches: MATCH_PATTERN_FOUR
192+
- matches: MATCH_PATTERN_FIVE
193+
- matches: MATCH_PATTERN_SIX
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
id: null-library-function-cpp
2+
snapshots:
3+
? "gid_t f() {\nreturn getgrent()->gr_gid;\n}\nvoid f() {\nchar buf[128];\nstrcpy(buf, getenv(\"FOO\"));\n}\n{\nfwrite(\"foo\", 3, 1, fopen(\"foo.txt\", \"w\"));\n}\n{\nFILE *fptr;\nfwrite(\"foo\", 3, 1, fptr = fopen(\"foo.txt\", \"w\"));\n}\nvoid test_getc() {\nint c = getc(fopen(file_name, \"r\")); \nint c = getc(fptr = fopen(file_name, \"r\"));\n}\n"
4+
: labels:
5+
- source: return getgrent()->gr_gid;
6+
style: primary
7+
start: 12
8+
end: 38
9+
- source: getgrent
10+
style: secondary
11+
start: 19
12+
end: 27
13+
- source: getgrent()
14+
style: secondary
15+
start: 19
16+
end: 29
17+
- source: getgrent()->gr_gid
18+
style: secondary
19+
start: 19
20+
end: 37
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
id: null-library-function-cpp
2+
valid:
3+
- |
4+
errno = 0;
5+
fwrite(data, len, 1, f);
6+
if (errno) {
7+
ERRS("unable to write output file");
8+
goto out_flush;
9+
}
10+
11+
invalid:
12+
- |
13+
gid_t f() {
14+
return getgrent()->gr_gid;
15+
}
16+
void f() {
17+
char buf[128];
18+
strcpy(buf, getenv("FOO"));
19+
}
20+
{
21+
fwrite("foo", 3, 1, fopen("foo.txt", "w"));
22+
}
23+
{
24+
FILE *fptr;
25+
fwrite("foo", 3, 1, fptr = fopen("foo.txt", "w"));
26+
}
27+
void test_getc() {
28+
int c = getc(fopen(file_name, "r"));
29+
int c = getc(fptr = fopen(file_name, "r"));
30+
}

0 commit comments

Comments
 (0)