Skip to content

Commit 9d817d9

Browse files
ESS-ENNSakshis
authored andcommitted
Add static analysis rules for NULL pointer dereference detection (#132)
* removed missing-secure-java * null-library-function-c * null-library-function-cpp --------- Co-authored-by: Sakshis <[email protected]>
1 parent 4aec0d5 commit 9d817d9

File tree

7 files changed

+825
-1
lines changed

7 files changed

+825
-1
lines changed
Lines changed: 262 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,262 @@
1+
id: null-library-function-c
2+
language: C
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+
ast-grep-essentials: true
12+
13+
rule:
14+
all:
15+
- not:
16+
has:
17+
stopBy: end
18+
kind: ERROR
19+
- any:
20+
- kind: subscript_expression
21+
# any:
22+
# - pattern: $SOURCE($$$)[$$$]
23+
# - pattern: ($SOURCE($$$))[$$$]
24+
all:
25+
- has:
26+
stopBy: end
27+
kind: call_expression
28+
all:
29+
- has:
30+
stopBy: end
31+
kind: identifier
32+
pattern: $SOURCE
33+
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$
34+
- has:
35+
stopBy: neighbor
36+
kind: argument_list
37+
- has:
38+
stopBy: end
39+
any:
40+
- kind: number_literal
41+
- kind: identifier
42+
43+
- kind: call_expression
44+
all:
45+
- has:
46+
stopBy: neighbor
47+
kind: identifier
48+
pattern: $SINK
49+
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$
50+
- has:
51+
stopBy: neighbor
52+
kind: argument_list
53+
has:
54+
stopBy: neighbor
55+
kind: call_expression
56+
nthChild: 1
57+
all:
58+
- has:
59+
stopBy: neighbor
60+
kind: identifier
61+
pattern: $SOURCE
62+
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$
63+
- has:
64+
stopBy: neighbor
65+
kind: argument_list
66+
67+
- kind: call_expression
68+
all:
69+
- has:
70+
stopBy: neighbor
71+
kind: identifier
72+
pattern: $SINK
73+
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$
74+
- has:
75+
stopBy: neighbor
76+
kind: argument_list
77+
has:
78+
stopBy: neighbor
79+
kind: assignment_expression
80+
nthChild: 1
81+
all:
82+
- has:
83+
stopBy: neighbor
84+
kind: identifier
85+
pattern: $VAR
86+
- has:
87+
stopBy: neighbor
88+
kind: call_expression
89+
all:
90+
- has:
91+
stopBy: neighbor
92+
kind: identifier
93+
pattern: $SOURCE
94+
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$
95+
96+
- kind: call_expression
97+
all:
98+
- has:
99+
stopBy: neighbor
100+
kind: identifier
101+
pattern: $SINK
102+
- has:
103+
stopBy: neighbor
104+
kind: argument_list
105+
has:
106+
stopBy: neighbor
107+
kind: call_expression
108+
nthChild: 2
109+
all:
110+
- has:
111+
stopBy: neighbor
112+
kind: identifier
113+
pattern: $SOURCE
114+
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$
115+
- has:
116+
stopBy: neighbor
117+
kind: argument_list
118+
- not:
119+
inside:
120+
stopBy: end
121+
kind: call_expression
122+
has:
123+
stopBy: neighbor
124+
kind: identifier
125+
pattern: $SINK
126+
- not:
127+
has:
128+
stopBy: end
129+
kind: call_expression
130+
all:
131+
- has:
132+
stopBy: neighbor
133+
kind: identifier
134+
pattern: $SOURCE
135+
- has:
136+
stopBy: neighbor
137+
kind: argument_list
138+
has:
139+
stopBy: end
140+
kind: call_expression
141+
has:
142+
stopBy: neighbor
143+
kind: identifier
144+
pattern: $SOURCE
145+
146+
- kind: call_expression
147+
all:
148+
- has:
149+
stopBy: neighbor
150+
kind: identifier
151+
pattern: $SINK
152+
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$
153+
- has:
154+
stopBy: neighbor
155+
kind: argument_list
156+
has:
157+
stopBy: neighbor
158+
kind: assignment_expression
159+
pattern: $VAR = $SOURCE($$$)
160+
all:
161+
- has:
162+
stopBy: neighbor
163+
kind: identifier
164+
pattern: $VAR
165+
- has:
166+
stopBy: neighbor
167+
kind: call_expression
168+
all:
169+
- has:
170+
stopBy: neighbor
171+
kind: identifier
172+
pattern: $SOURCE
173+
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$
174+
175+
- kind: call_expression
176+
# any:
177+
# - pattern: $SINK($$$, $SOURCE($$$))
178+
# - pattern: $SINK($SOURCE($$$))
179+
all:
180+
- has:
181+
stopBy: neighbor
182+
kind: identifier
183+
pattern: $SINK
184+
regex: ^fwrite|::fwrite|std::fwrite$
185+
- has:
186+
stopBy: neighbor
187+
kind: argument_list
188+
has:
189+
stopBy: end
190+
kind: call_expression
191+
all:
192+
- has:
193+
stopBy: end
194+
kind: identifier
195+
pattern: $SOURCE
196+
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$
197+
- has:
198+
stopBy: neighbor
199+
kind: argument_list
200+
201+
- kind: call_expression
202+
any:
203+
- pattern: $SINK($$$, $VAR = $SOURCE($$$))
204+
- pattern: $SINK($VAR = $SOURCE($$$))
205+
all:
206+
- has:
207+
stopBy: neighbor
208+
kind: identifier
209+
pattern: $SINK
210+
regex: ^fwrite|::fwrite|std::fwrite$
211+
- has:
212+
stopBy: neighbor
213+
kind: argument_list
214+
has:
215+
stopBy: end
216+
kind: assignment_expression
217+
pattern: $VAR = $SOURCE($$$)
218+
all:
219+
- has:
220+
stopBy: neighbor
221+
kind: identifier
222+
- has:
223+
stopBy: neighbor
224+
kind: call_expression
225+
all:
226+
- has:
227+
stopBy: neighbor
228+
kind: identifier
229+
pattern: $SOURCE
230+
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$
231+
- has:
232+
stopBy: neighbor
233+
kind: argument_list
234+
235+
- kind: pointer_expression
236+
has:
237+
stopBy: neighbor
238+
kind: call_expression
239+
all:
240+
- has:
241+
stopBy: end
242+
kind: identifier
243+
pattern: $SOURCE
244+
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$
245+
- has:
246+
stopBy: neighbor
247+
kind: argument_list
248+
- not:
249+
inside:
250+
stopBy: end
251+
any:
252+
- kind: subscript_expression
253+
# - kind: call_expression
254+
- not:
255+
has:
256+
stopBy: end
257+
any:
258+
- kind: assignment_expression
259+
- inside:
260+
stopBy: end
261+
kind: return_statement
262+

0 commit comments

Comments
 (0)