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