xref: /linux/scripts/coccinelle/null/deref_null.cocci (revision 765532c8aaac624b5f8687af6d319c6a1138a257)
1///
2/// A variable is dereference under a NULL test.
3/// Even though it is know to be NULL.
4///
5// Confidence: Moderate
6// Copyright: (C) 2010 Nicolas Palix, DIKU.  GPLv2.
7// Copyright: (C) 2010 Julia Lawall, DIKU.  GPLv2.
8// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6.  GPLv2.
9// URL: http://coccinelle.lip6.fr/
10// Comments: -I ... -all_includes can give more complete results
11// Options:
12
13virtual context
14virtual patch
15virtual org
16virtual report
17
18@initialize:python depends on !context && patch && !org && !report@
19
20import sys
21print >> sys.stderr, "This semantic patch does not support the 'patch' mode."
22
23@depends on patch@
24@@
25
26this_rule_should_never_matches();
27
28@ifm depends on !patch@
29expression *E;
30statement S1,S2;
31position p1;
32@@
33
34if@p1 ((E == NULL && ...) || ...) S1 else S2
35
36// The following two rules are separate, because both can match a single
37// expression in different ways
38@pr1 depends on !patch expression@
39expression *ifm.E;
40identifier f;
41position p1;
42@@
43
44 (E != NULL && ...) ? <+...E->f@p1...+> : ...
45
46@pr2 depends on !patch expression@
47expression *ifm.E;
48identifier f;
49position p2;
50@@
51
52(
53  (E != NULL) && ... && <+...E->f@p2...+>
54|
55  (E == NULL) || ... || <+...E->f@p2...+>
56|
57 sizeof(<+...E->f@p2...+>)
58)
59
60// For org and report modes
61
62@r depends on !context && !patch && (org || report) exists@
63expression subE <= ifm.E;
64expression *ifm.E;
65expression E1,E2;
66identifier f;
67statement S1,S2,S3,S4;
68iterator iter;
69position p!={pr1.p1,pr2.p2};
70position ifm.p1;
71@@
72
73if@p1 ((E == NULL && ...) || ...)
74{
75  ... when != if (...) S1 else S2
76(
77 iter(subE,...) S4 // no use
78|
79 list_remove_head(E2,subE,...)
80|
81 subE = E1
82|
83 for(subE = E1;...;...) S4
84|
85 subE++
86|
87 ++subE
88|
89 --subE
90|
91 subE--
92|
93 &subE
94|
95 E->f@p // bad use
96)
97  ... when any
98  return ...;
99}
100else S3
101
102@script:python depends on !context && !patch && !org && report@
103p << r.p;
104p1 << ifm.p1;
105x << ifm.E;
106@@
107
108msg="ERROR: %s is NULL but dereferenced." % (x)
109coccilib.report.print_report(p[0], msg)
110cocci.include_match(False)
111
112@script:python depends on !context && !patch && org && !report@
113p << r.p;
114p1 << ifm.p1;
115x << ifm.E;
116@@
117
118msg="ERROR: %s is NULL but dereferenced." % (x)
119msg_safe=msg.replace("[","@(").replace("]",")")
120cocci.print_main(msg_safe,p)
121cocci.include_match(False)
122
123@s depends on !context && !patch && (org || report) exists@
124expression subE <= ifm.E;
125expression *ifm.E;
126expression E1,E2;
127identifier f;
128statement S1,S2,S3,S4;
129iterator iter;
130position p!={pr1.p1,pr2.p2};
131position ifm.p1;
132@@
133
134if@p1 ((E == NULL && ...) || ...)
135{
136  ... when != if (...) S1 else S2
137(
138 iter(subE,...) S4 // no use
139|
140 list_remove_head(E2,subE,...)
141|
142 subE = E1
143|
144 for(subE = E1;...;...) S4
145|
146 subE++
147|
148 ++subE
149|
150 --subE
151|
152 subE--
153|
154 &subE
155|
156 E->f@p // bad use
157)
158  ... when any
159}
160else S3
161
162@script:python depends on !context && !patch && !org && report@
163p << s.p;
164p1 << ifm.p1;
165x << ifm.E;
166@@
167
168msg="ERROR: %s is NULL but dereferenced." % (x)
169coccilib.report.print_report(p[0], msg)
170
171@script:python depends on !context && !patch && org && !report@
172p << s.p;
173p1 << ifm.p1;
174x << ifm.E;
175@@
176
177msg="ERROR: %s is NULL but dereferenced." % (x)
178msg_safe=msg.replace("[","@(").replace("]",")")
179cocci.print_main(msg_safe,p)
180
181// For context mode
182
183@depends on context && !patch && !org && !report exists@
184expression subE <= ifm.E;
185expression *ifm.E;
186expression E1,E2;
187identifier f;
188statement S1,S2,S3,S4;
189iterator iter;
190position p!={pr1.p1,pr2.p2};
191position ifm.p1;
192@@
193
194if@p1 ((E == NULL && ...) || ...)
195{
196  ... when != if (...) S1 else S2
197(
198 iter(subE,...) S4 // no use
199|
200 list_remove_head(E2,subE,...)
201|
202 subE = E1
203|
204 for(subE = E1;...;...) S4
205|
206 subE++
207|
208 ++subE
209|
210 --subE
211|
212 subE--
213|
214 &subE
215|
216* E->f@p // bad use
217)
218  ... when any
219  return ...;
220}
221else S3
222
223// The following three rules are duplicates of ifm, pr1 and pr2 respectively.
224// It is need because the previous rule as already made a "change".
225
226@ifm1 depends on !patch@
227expression *E;
228statement S1,S2;
229position p1;
230@@
231
232if@p1 ((E == NULL && ...) || ...) S1 else S2
233
234@pr11 depends on !patch expression@
235expression *ifm1.E;
236identifier f;
237position p1;
238@@
239
240 (E != NULL && ...) ? <+...E->f@p1...+> : ...
241
242@pr12 depends on !patch expression@
243expression *ifm1.E;
244identifier f;
245position p2;
246@@
247
248(
249  (E != NULL) && ... && <+...E->f@p2...+>
250|
251  (E == NULL) || ... || <+...E->f@p2...+>
252|
253 sizeof(<+...E->f@p2...+>)
254)
255
256@depends on context && !patch && !org && !report exists@
257expression subE <= ifm1.E;
258expression *ifm1.E;
259expression E1,E2;
260identifier f;
261statement S1,S2,S3,S4;
262iterator iter;
263position p!={pr11.p1,pr12.p2};
264position ifm1.p1;
265@@
266
267if@p1 ((E == NULL && ...) || ...)
268{
269  ... when != if (...) S1 else S2
270(
271 iter(subE,...) S4 // no use
272|
273 list_remove_head(E2,subE,...)
274|
275 subE = E1
276|
277 for(subE = E1;...;...) S4
278|
279 subE++
280|
281 ++subE
282|
283 --subE
284|
285 subE--
286|
287 &subE
288|
289* E->f@p // bad use
290)
291  ... when any
292}
293else S3
294