aboutsummaryrefslogtreecommitdiffstats
path: root/scripts/coccinelle/api
diff options
context:
space:
mode:
authorWe-unite <3205135446@qq.com>2025-03-08 22:04:20 +0800
committerWe-unite <3205135446@qq.com>2025-03-08 22:04:20 +0800
commita07bb8fd1299070229f0e8f3dcb57ffd5ef9870a (patch)
tree84f21bd0bf7071bc5fc7dd989e77d7ceb5476682 /scripts/coccinelle/api
downloadohosKernel-a07bb8fd1299070229f0e8f3dcb57ffd5ef9870a.tar.gz
ohosKernel-a07bb8fd1299070229f0e8f3dcb57ffd5ef9870a.zip
Initial commit: OpenHarmony-v4.0-ReleaseOpenHarmony-v4.0-Release
Diffstat (limited to 'scripts/coccinelle/api')
-rw-r--r--scripts/coccinelle/api/alloc/alloc_cast.cocci123
-rw-r--r--scripts/coccinelle/api/alloc/pool_zalloc-simple.cocci85
-rw-r--r--scripts/coccinelle/api/alloc/zalloc-simple.cocci411
-rw-r--r--scripts/coccinelle/api/atomic_as_refcounter.cocci130
-rw-r--r--scripts/coccinelle/api/check_bq27xxx_data.cocci162
-rw-r--r--scripts/coccinelle/api/d_find_alias.cocci81
-rw-r--r--scripts/coccinelle/api/debugfs/debugfs_simple_attr.cocci68
-rw-r--r--scripts/coccinelle/api/device_attr_show.cocci55
-rw-r--r--scripts/coccinelle/api/err_cast.cocci57
-rw-r--r--scripts/coccinelle/api/kfree_mismatch.cocci228
-rw-r--r--scripts/coccinelle/api/kfree_sensitive.cocci100
-rw-r--r--scripts/coccinelle/api/kobj_to_dev.cocci45
-rw-r--r--scripts/coccinelle/api/kstrdup.cocci105
-rw-r--r--scripts/coccinelle/api/kvmalloc.cocci256
-rw-r--r--scripts/coccinelle/api/memdup.cocci66
-rw-r--r--scripts/coccinelle/api/memdup_user.cocci119
-rw-r--r--scripts/coccinelle/api/platform_get_irq.cocci102
-rw-r--r--scripts/coccinelle/api/platform_no_drv_owner.cocci180
-rw-r--r--scripts/coccinelle/api/pm_runtime.cocci114
-rw-r--r--scripts/coccinelle/api/ptr_ret.cocci97
-rw-r--r--scripts/coccinelle/api/resource_size.cocci94
-rw-r--r--scripts/coccinelle/api/simple_open.cocci71
-rw-r--r--scripts/coccinelle/api/stream_open.cocci370
-rw-r--r--scripts/coccinelle/api/vma_pages.cocci61
24 files changed, 3180 insertions, 0 deletions
diff --git a/scripts/coccinelle/api/alloc/alloc_cast.cocci b/scripts/coccinelle/api/alloc/alloc_cast.cocci
new file mode 100644
index 000000000..f6f0ccdb6
--- /dev/null
+++ b/scripts/coccinelle/api/alloc/alloc_cast.cocci
@@ -0,0 +1,123 @@
1// SPDX-License-Identifier: GPL-2.0-only
2/// Remove casting the values returned by memory allocation functions
3/// like kmalloc, kzalloc, kmem_cache_alloc, kmem_cache_zalloc etc.
4///
5//# This makes an effort to find cases of casting of values returned by
6//# kmalloc, kzalloc, kcalloc, kmem_cache_alloc, kmem_cache_zalloc,
7//# kmem_cache_alloc_node, kmalloc_node and kzalloc_node and removes
8//# the casting as it is not required. The result in the patch case may
9//# need some reformatting.
10//
11// Confidence: High
12// Copyright: (C) 2014 Himangi Saraogi
13// Copyright: (C) 2017 Himanshu Jha
14// Comments:
15// Options: --no-includes --include-headers
16//
17
18virtual context
19virtual patch
20virtual org
21virtual report
22
23@initialize:python@
24@@
25import re
26pattern = '__'
27m = re.compile(pattern)
28
29@r1 depends on context || patch@
30type T;
31@@
32
33 (T *)
34 \(kmalloc\|kzalloc\|kcalloc\|kmem_cache_alloc\|kmem_cache_zalloc\|
35 kmem_cache_alloc_node\|kmalloc_node\|kzalloc_node\|vmalloc\|vzalloc\|
36 dma_alloc_coherent\|devm_kmalloc\|devm_kzalloc\|
37 kvmalloc\|kvzalloc\|kvmalloc_node\|kvzalloc_node\|pci_alloc_consistent\|
38 pci_zalloc_consistent\|kmem_alloc\|kmem_zalloc\|kmem_zone_alloc\|
39 kmem_zone_zalloc\|vmalloc_node\|vzalloc_node\)(...)
40
41//----------------------------------------------------------
42// For context mode
43//----------------------------------------------------------
44
45@script:python depends on context@
46t << r1.T;
47@@
48
49if m.search(t) != None:
50 cocci.include_match(False)
51
52@depends on context && r1@
53type r1.T;
54@@
55
56* (T *)
57 \(kmalloc\|kzalloc\|kcalloc\|kmem_cache_alloc\|kmem_cache_zalloc\|
58 kmem_cache_alloc_node\|kmalloc_node\|kzalloc_node\|vmalloc\|vzalloc\|
59 dma_alloc_coherent\|devm_kmalloc\|devm_kzalloc\|
60 kvmalloc\|kvzalloc\|kvmalloc_node\|kvzalloc_node\|pci_alloc_consistent\|
61 pci_zalloc_consistent\|kmem_alloc\|kmem_zalloc\|kmem_zone_alloc\|
62 kmem_zone_zalloc\|vmalloc_node\|vzalloc_node\)(...)
63
64//----------------------------------------------------------
65// For patch mode
66//----------------------------------------------------------
67
68@script:python depends on patch@
69t << r1.T;
70@@
71
72if m.search(t) != None:
73 cocci.include_match(False)
74
75@depends on patch && r1@
76type r1.T;
77@@
78
79- (T *)
80 \(kmalloc\|kzalloc\|kcalloc\|kmem_cache_alloc\|kmem_cache_zalloc\|
81 kmem_cache_alloc_node\|kmalloc_node\|kzalloc_node\|vmalloc\|vzalloc\|
82 dma_alloc_coherent\|devm_kmalloc\|devm_kzalloc\|
83 kvmalloc\|kvzalloc\|kvmalloc_node\|kvzalloc_node\|pci_alloc_consistent\|
84 pci_zalloc_consistent\|kmem_alloc\|kmem_zalloc\|kmem_zone_alloc\|
85 kmem_zone_zalloc\|vmalloc_node\|vzalloc_node\)(...)
86
87//----------------------------------------------------------
88// For org and report mode
89//----------------------------------------------------------
90
91@r2 depends on org || report@
92type T;
93position p;
94@@
95
96 (T@p *)
97 \(kmalloc\|kzalloc\|kcalloc\|kmem_cache_alloc\|kmem_cache_zalloc\|
98 kmem_cache_alloc_node\|kmalloc_node\|kzalloc_node\|vmalloc\|vzalloc\|
99 dma_alloc_coherent\|devm_kmalloc\|devm_kzalloc\|
100 kvmalloc\|kvzalloc\|kvmalloc_node\|kvzalloc_node\|pci_alloc_consistent\|
101 pci_zalloc_consistent\|kmem_alloc\|kmem_zalloc\|kmem_zone_alloc\|
102 kmem_zone_zalloc\|vmalloc_node\|vzalloc_node\)(...)
103
104@script:python depends on org@
105p << r2.p;
106t << r2.T;
107@@
108
109if m.search(t) != None:
110 cocci.include_match(False)
111else:
112 coccilib.org.print_safe_todo(p[0], t)
113
114@script:python depends on report@
115p << r2.p;
116t << r2.T;
117@@
118
119if m.search(t) != None:
120 cocci.include_match(False)
121else:
122 msg="WARNING: casting value returned by memory allocation function to (%s *) is useless." % (t)
123 coccilib.report.print_report(p[0], msg)
diff --git a/scripts/coccinelle/api/alloc/pool_zalloc-simple.cocci b/scripts/coccinelle/api/alloc/pool_zalloc-simple.cocci
new file mode 100644
index 000000000..9c61a23b3
--- /dev/null
+++ b/scripts/coccinelle/api/alloc/pool_zalloc-simple.cocci
@@ -0,0 +1,85 @@
1// SPDX-License-Identifier: GPL-2.0-only
2///
3/// Use *_pool_zalloc rather than *_pool_alloc followed by memset with 0
4///
5// Copyright: (C) 2015 Intel Corp.
6// Options: --no-includes --include-headers
7//
8// Keywords: dma_pool_zalloc, pci_pool_zalloc
9//
10
11virtual context
12virtual patch
13virtual org
14virtual report
15
16//----------------------------------------------------------
17// For context mode
18//----------------------------------------------------------
19
20@depends on context@
21expression x;
22statement S;
23@@
24
25* x = \(dma_pool_alloc\|pci_pool_alloc\)(...);
26 if ((x==NULL) || ...) S
27* memset(x,0, ...);
28
29//----------------------------------------------------------
30// For patch mode
31//----------------------------------------------------------
32
33@depends on patch@
34expression x;
35expression a,b,c;
36statement S;
37@@
38
39- x = dma_pool_alloc(a,b,c);
40+ x = dma_pool_zalloc(a,b,c);
41 if ((x==NULL) || ...) S
42- memset(x,0,...);
43
44@depends on patch@
45expression x;
46expression a,b,c;
47statement S;
48@@
49
50- x = pci_pool_alloc(a,b,c);
51+ x = pci_pool_zalloc(a,b,c);
52 if ((x==NULL) || ...) S
53- memset(x,0,...);
54
55//----------------------------------------------------------
56// For org and report mode
57//----------------------------------------------------------
58
59@r depends on org || report@
60expression x;
61expression a,b,c;
62statement S;
63position p;
64@@
65
66 x = @p\(dma_pool_alloc\|pci_pool_alloc\)(a,b,c);
67 if ((x==NULL) || ...) S
68 memset(x,0, ...);
69
70@script:python depends on org@
71p << r.p;
72x << r.x;
73@@
74
75msg="%s" % (x)
76msg_safe=msg.replace("[","@(").replace("]",")")
77coccilib.org.print_todo(p[0], msg_safe)
78
79@script:python depends on report@
80p << r.p;
81x << r.x;
82@@
83
84msg="WARNING: *_pool_zalloc should be used for %s, instead of *_pool_alloc/memset" % (x)
85coccilib.report.print_report(p[0], msg)
diff --git a/scripts/coccinelle/api/alloc/zalloc-simple.cocci b/scripts/coccinelle/api/alloc/zalloc-simple.cocci
new file mode 100644
index 000000000..b3d0c3c23
--- /dev/null
+++ b/scripts/coccinelle/api/alloc/zalloc-simple.cocci
@@ -0,0 +1,411 @@
1// SPDX-License-Identifier: GPL-2.0-only
2///
3/// Use zeroing allocator rather than allocator followed by memset with 0
4///
5/// This considers some simple cases that are common and easy to validate
6/// Note in particular that there are no ...s in the rule, so all of the
7/// matched code has to be contiguous
8///
9// Confidence: High
10// Copyright: (C) 2009-2010 Julia Lawall, Nicolas Palix, DIKU.
11// Copyright: (C) 2009-2010 Gilles Muller, INRIA/LiP6.
12// Copyright: (C) 2017 Himanshu Jha
13// URL: http://coccinelle.lip6.fr/rules/kzalloc.html
14// Options: --no-includes --include-headers
15//
16// Keywords: kmalloc, kzalloc
17// Version min: < 2.6.12 kmalloc
18// Version min: 2.6.14 kzalloc
19//
20
21virtual context
22virtual patch
23virtual org
24virtual report
25
26//----------------------------------------------------------
27// For context mode
28//----------------------------------------------------------
29
30@depends on context@
31type T, T2;
32expression x;
33expression E1;
34statement S;
35@@
36
37* x = (T)\(kmalloc(E1, ...)\|vmalloc(E1)\|dma_alloc_coherent(...,E1,...)\|
38 kmalloc_node(E1, ...)\|kmem_cache_alloc(...)\|kmem_alloc(E1, ...)\|
39 devm_kmalloc(...,E1,...)\|kvmalloc(E1, ...)\|kvmalloc_node(E1,...)\);
40 if ((x==NULL) || ...) S
41* memset((T2)x,0,E1);
42
43//----------------------------------------------------------
44// For patch mode
45//----------------------------------------------------------
46
47@depends on patch@
48type T, T2;
49expression x;
50expression E1,E2,E3,E4;
51statement S;
52@@
53
54(
55- x = kmalloc(E1,E2);
56+ x = kzalloc(E1,E2);
57|
58- x = (T *)kmalloc(E1,E2);
59+ x = kzalloc(E1,E2);
60|
61- x = (T)kmalloc(E1,E2);
62+ x = (T)kzalloc(E1,E2);
63|
64- x = vmalloc(E1);
65+ x = vzalloc(E1);
66|
67- x = (T *)vmalloc(E1);
68+ x = vzalloc(E1);
69|
70- x = (T)vmalloc(E1);
71+ x = (T)vzalloc(E1);
72|
73- x = kmalloc_node(E1,E2,E3);
74+ x = kzalloc_node(E1,E2,E3);
75|
76- x = (T *)kmalloc_node(E1,E2,E3);
77+ x = kzalloc_node(E1,E2,E3);
78|
79- x = (T)kmalloc_node(E1,E2,E3);
80+ x = (T)kzalloc_node(E1,E2,E3);
81|
82- x = kmem_cache_alloc(E3,E4);
83+ x = kmem_cache_zalloc(E3,E4);
84|
85- x = (T *)kmem_cache_alloc(E3,E4);
86+ x = kmem_cache_zalloc(E3,E4);
87|
88- x = (T)kmem_cache_alloc(E3,E4);
89+ x = (T)kmem_cache_zalloc(E3,E4);
90|
91- x = kmem_alloc(E1,E2);
92+ x = kmem_zalloc(E1,E2);
93|
94- x = (T *)kmem_alloc(E1,E2);
95+ x = kmem_zalloc(E1,E2);
96|
97- x = (T)kmem_alloc(E1,E2);
98+ x = (T)kmem_zalloc(E1,E2);
99|
100- x = devm_kmalloc(E2,E1,E3);
101+ x = devm_kzalloc(E2,E1,E3);
102|
103- x = (T *)devm_kmalloc(E2,E1,E3);
104+ x = devm_kzalloc(E2,E1,E3);
105|
106- x = (T)devm_kmalloc(E2,E1,E3);
107+ x = (T)devm_kzalloc(E2,E1,E3);
108|
109- x = kvmalloc(E1,E2);
110+ x = kvzalloc(E1,E2);
111|
112- x = (T *)kvmalloc(E1,E2);
113+ x = kvzalloc(E1,E2);
114|
115- x = (T)kvmalloc(E1,E2);
116+ x = (T)kvzalloc(E1,E2);
117|
118- x = kvmalloc_node(E1,E2,E3);
119+ x = kvzalloc_node(E1,E2,E3);
120|
121- x = (T *)kvmalloc_node(E1,E2,E3);
122+ x = kvzalloc_node(E1,E2,E3);
123|
124- x = (T)kvmalloc_node(E1,E2,E3);
125+ x = (T)kvzalloc_node(E1,E2,E3);
126)
127 if ((x==NULL) || ...) S
128- memset((T2)x,0,E1);
129
130@depends on patch@
131type T, T2;
132expression x;
133expression E1,E2,E3,E4;
134statement S;
135@@
136 x = (T)dma_alloc_coherent(E1, E2, E3, E4);
137 if ((x==NULL) || ...) S
138- memset((T2)x, 0, E2);
139
140//----------------------------------------------------------
141// For org mode
142//----------------------------------------------------------
143
144@r depends on org || report@
145type T, T2;
146expression x;
147expression E1,E2;
148statement S;
149position p;
150@@
151
152 x = (T)kmalloc@p(E1,E2);
153 if ((x==NULL) || ...) S
154 memset((T2)x,0,E1);
155
156@script:python depends on org@
157p << r.p;
158x << r.x;
159@@
160
161msg="%s" % (x)
162msg_safe=msg.replace("[","@(").replace("]",")")
163coccilib.org.print_todo(p[0], msg_safe)
164
165@script:python depends on report@
166p << r.p;
167x << r.x;
168@@
169
170msg="WARNING: kzalloc should be used for %s, instead of kmalloc/memset" % (x)
171coccilib.report.print_report(p[0], msg)
172
173//-----------------------------------------------------------------
174@r1 depends on org || report@
175type T, T2;
176expression x;
177expression E1;
178statement S;
179position p;
180@@
181
182 x = (T)vmalloc@p(E1);
183 if ((x==NULL) || ...) S
184 memset((T2)x,0,E1);
185
186@script:python depends on org@
187p << r1.p;
188x << r1.x;
189@@
190
191msg="%s" % (x)
192msg_safe=msg.replace("[","@(").replace("]",")")
193coccilib.org.print_todo(p[0], msg_safe)
194
195@script:python depends on report@
196p << r1.p;
197x << r1.x;
198@@
199
200msg="WARNING: vzalloc should be used for %s, instead of vmalloc/memset" % (x)
201coccilib.report.print_report(p[0], msg)
202
203//-----------------------------------------------------------------
204@r2 depends on org || report@
205type T, T2;
206expression x;
207expression E1,E2,E3,E4;
208statement S;
209position p;
210@@
211
212 x = (T)dma_alloc_coherent@p(E1,E2,E3,E4);
213 if ((x==NULL) || ...) S
214 memset((T2)x,0,E2);
215
216@script:python depends on org@
217p << r2.p;
218x << r2.x;
219@@
220
221msg="%s" % (x)
222msg_safe=msg.replace("[","@(").replace("]",")")
223coccilib.org.print_todo(p[0], msg_safe)
224
225@script:python depends on report@
226p << r2.p;
227x << r2.x;
228@@
229
230msg="WARNING: dma_alloc_coherent used in %s already zeroes out memory, so memset is not needed" % (x)
231coccilib.report.print_report(p[0], msg)
232
233//-----------------------------------------------------------------
234@r3 depends on org || report@
235type T, T2;
236expression x;
237expression E1,E2,E3;
238statement S;
239position p;
240@@
241
242 x = (T)kmalloc_node@p(E1,E2,E3);
243 if ((x==NULL) || ...) S
244 memset((T2)x,0,E1);
245
246@script:python depends on org@
247p << r3.p;
248x << r3.x;
249@@
250
251msg="%s" % (x)
252msg_safe=msg.replace("[","@(").replace("]",")")
253coccilib.org.print_todo(p[0], msg_safe)
254
255@script:python depends on report@
256p << r3.p;
257x << r3.x;
258@@
259
260msg="WARNING: kzalloc_node should be used for %s, instead of kmalloc_node/memset" % (x)
261coccilib.report.print_report(p[0], msg)
262
263//-----------------------------------------------------------------
264@r4 depends on org || report@
265type T, T2;
266expression x;
267expression E1,E2,E3;
268statement S;
269position p;
270@@
271
272 x = (T)kmem_cache_alloc@p(E2,E3);
273 if ((x==NULL) || ...) S
274 memset((T2)x,0,E1);
275
276@script:python depends on org@
277p << r4.p;
278x << r4.x;
279@@
280
281msg="%s" % (x)
282msg_safe=msg.replace("[","@(").replace("]",")")
283coccilib.org.print_todo(p[0], msg_safe)
284
285@script:python depends on report@
286p << r4.p;
287x << r4.x;
288@@
289
290msg="WARNING: kmem_cache_zalloc should be used for %s, instead of kmem_cache_alloc/memset" % (x)
291coccilib.report.print_report(p[0], msg)
292
293//-----------------------------------------------------------------
294@r5 depends on org || report@
295type T, T2;
296expression x;
297expression E1,E2;
298statement S;
299position p;
300@@
301
302 x = (T)kmem_alloc@p(E1,E2);
303 if ((x==NULL) || ...) S
304 memset((T2)x,0,E1);
305
306@script:python depends on org@
307p << r5.p;
308x << r5.x;
309@@
310
311msg="%s" % (x)
312msg_safe=msg.replace("[","@(").replace("]",")")
313coccilib.org.print_todo(p[0], msg_safe)
314
315@script:python depends on report@
316p << r5.p;
317x << r5.x;
318@@
319
320msg="WARNING: kmem_zalloc should be used for %s, instead of kmem_alloc/memset" % (x)
321coccilib.report.print_report(p[0], msg)
322
323//-----------------------------------------------------------------
324@r6 depends on org || report@
325type T, T2;
326expression x;
327expression E1,E2,E3;
328statement S;
329position p;
330@@
331
332 x = (T)devm_kmalloc@p(E2,E1,E3);
333 if ((x==NULL) || ...) S
334 memset((T2)x,0,E1);
335
336@script:python depends on org@
337p << r6.p;
338x << r6.x;
339@@
340
341msg="%s" % (x)
342msg_safe=msg.replace("[","@(").replace("]",")")
343coccilib.org.print_todo(p[0], msg_safe)
344
345@script:python depends on report@
346p << r6.p;
347x << r6.x;
348@@
349
350msg="WARNING: devm_kzalloc should be used for %s, instead of devm_kmalloc/memset" % (x)
351coccilib.report.print_report(p[0], msg)
352
353//-----------------------------------------------------------------
354@r7 depends on org || report@
355type T, T2;
356expression x;
357expression E1,E2;
358statement S;
359position p;
360@@
361
362 x = (T)kvmalloc@p(E1,E2);
363 if ((x==NULL) || ...) S
364 memset((T2)x,0,E1);
365
366@script:python depends on org@
367p << r7.p;
368x << r7.x;
369@@
370
371msg="%s" % (x)
372msg_safe=msg.replace("[","@(").replace("]",")")
373coccilib.org.print_todo(p[0], msg_safe)
374
375@script:python depends on report@
376p << r7.p;
377x << r7.x;
378@@
379
380msg="WARNING: kvzalloc should be used for %s, instead of kvmalloc/memset" % (x)
381coccilib.report.print_report(p[0], msg)
382
383//-----------------------------------------------------------------
384@r9 depends on org || report@
385type T, T2;
386expression x;
387expression E1,E2,E3;
388statement S;
389position p;
390@@
391
392 x = (T)kvmalloc_node@p(E1,E2,E3);
393 if ((x==NULL) || ...) S
394 memset((T2)x,0,E1);
395
396@script:python depends on org@
397p << r9.p;
398x << r9.x;
399@@
400
401msg="%s" % (x)
402msg_safe=msg.replace("[","@(").replace("]",")")
403coccilib.org.print_todo(p[0], msg_safe)
404
405@script:python depends on report@
406p << r9.p;
407x << r9.x;
408@@
409
410msg="WARNING: kvzalloc_node should be used for %s, instead of kvmalloc_node/memset" % (x)
411coccilib.report.print_report(p[0], msg)
diff --git a/scripts/coccinelle/api/atomic_as_refcounter.cocci b/scripts/coccinelle/api/atomic_as_refcounter.cocci
new file mode 100644
index 000000000..0f78d94ab
--- /dev/null
+++ b/scripts/coccinelle/api/atomic_as_refcounter.cocci
@@ -0,0 +1,130 @@
1// SPDX-License-Identifier: GPL-2.0-only
2// Check if refcount_t type and API should be used
3// instead of atomic_t type when dealing with refcounters
4//
5// Copyright (c) 2016-2017, Elena Reshetova, Intel Corporation
6//
7// Confidence: Moderate
8// URL: http://coccinelle.lip6.fr/
9// Options: --include-headers --very-quiet
10
11virtual report
12
13@r1 exists@
14identifier a, x;
15position p1, p2;
16identifier fname =~ ".*free.*";
17identifier fname2 =~ ".*destroy.*";
18identifier fname3 =~ ".*del.*";
19identifier fname4 =~ ".*queue_work.*";
20identifier fname5 =~ ".*schedule_work.*";
21identifier fname6 =~ ".*call_rcu.*";
22
23@@
24
25(
26 atomic_dec_and_test@p1(&(a)->x)
27|
28 atomic_dec_and_lock@p1(&(a)->x, ...)
29|
30 atomic_long_dec_and_lock@p1(&(a)->x, ...)
31|
32 atomic_long_dec_and_test@p1(&(a)->x)
33|
34 atomic64_dec_and_test@p1(&(a)->x)
35|
36 local_dec_and_test@p1(&(a)->x)
37)
38...
39(
40 fname@p2(a, ...);
41|
42 fname2@p2(...);
43|
44 fname3@p2(...);
45|
46 fname4@p2(...);
47|
48 fname5@p2(...);
49|
50 fname6@p2(...);
51)
52
53
54@script:python depends on report@
55p1 << r1.p1;
56p2 << r1.p2;
57@@
58msg = "atomic_dec_and_test variation before object free at line %s."
59coccilib.report.print_report(p1[0], msg % (p2[0].line))
60
61@r4 exists@
62identifier a, x, y;
63position p1, p2;
64identifier fname =~ ".*free.*";
65
66@@
67
68(
69 atomic_dec_and_test@p1(&(a)->x)
70|
71 atomic_dec_and_lock@p1(&(a)->x, ...)
72|
73 atomic_long_dec_and_lock@p1(&(a)->x, ...)
74|
75 atomic_long_dec_and_test@p1(&(a)->x)
76|
77 atomic64_dec_and_test@p1(&(a)->x)
78|
79 local_dec_and_test@p1(&(a)->x)
80)
81...
82y=a
83...
84fname@p2(y, ...);
85
86
87@script:python depends on report@
88p1 << r4.p1;
89p2 << r4.p2;
90@@
91msg = "atomic_dec_and_test variation before object free at line %s."
92coccilib.report.print_report(p1[0], msg % (p2[0].line))
93
94@r2 exists@
95identifier a, x;
96position p1;
97@@
98
99(
100atomic_add_unless(&(a)->x,-1,1)@p1
101|
102atomic_long_add_unless(&(a)->x,-1,1)@p1
103|
104atomic64_add_unless(&(a)->x,-1,1)@p1
105)
106
107@script:python depends on report@
108p1 << r2.p1;
109@@
110msg = "atomic_add_unless"
111coccilib.report.print_report(p1[0], msg)
112
113@r3 exists@
114identifier x;
115position p1;
116@@
117
118(
119x = atomic_add_return@p1(-1, ...);
120|
121x = atomic_long_add_return@p1(-1, ...);
122|
123x = atomic64_add_return@p1(-1, ...);
124)
125
126@script:python depends on report@
127p1 << r3.p1;
128@@
129msg = "x = atomic_add_return(-1, ...)"
130coccilib.report.print_report(p1[0], msg)
diff --git a/scripts/coccinelle/api/check_bq27xxx_data.cocci b/scripts/coccinelle/api/check_bq27xxx_data.cocci
new file mode 100644
index 000000000..fae539ef0
--- /dev/null
+++ b/scripts/coccinelle/api/check_bq27xxx_data.cocci
@@ -0,0 +1,162 @@
1// SPDX-License-Identifier: GPL-2.0-only
2/// Detect BQ27XXX_DATA structures with identical registers, dm registers or
3/// properties.
4//# Doesn't unfold macros used in register or property fields.
5//# Requires OCaml scripting
6///
7// Confidence: High
8// Copyright: (C) 2017 Julia Lawall, Inria/LIP6,
9// URL: http://coccinelle.lip6.fr/
10// Requires: 1.0.7
11// Keywords: BQ27XXX_DATA
12
13virtual report
14
15@initialize:ocaml@
16@@
17
18let print_report p msg =
19 let p = List.hd p in
20 Printf.printf "%s:%d:%d-%d: %s" p.file p.line p.col p.col_end msg
21
22@str depends on report@
23type t;
24identifier i,i1,i2;
25expression e1,e2;
26@@
27
28t i[] = {
29 ...,
30 [e1] = BQ27XXX_DATA(i1,...),
31 ...,
32 [e2] = BQ27XXX_DATA(i2,...),
33 ...,
34};
35
36@script:ocaml tocheck@
37i1 << str.i1;
38i2 << str.i2;
39i1regs; i2regs;
40i1dmregs; i2dmregs;
41i1props; i2props;
42@@
43
44if not(i1 = i2)
45then
46 begin
47 i1regs := make_ident (i1 ^ "_regs");
48 i2regs := make_ident (i2 ^ "_regs");
49 i1dmregs := make_ident (i1 ^ "_dm_regs");
50 i2dmregs := make_ident (i2 ^ "_dm_regs");
51 i1props := make_ident (i1 ^ "_props");
52 i2props := make_ident (i2 ^ "_props")
53 end
54
55(* ---------------------------------------------------------------- *)
56
57@getregs1@
58typedef u8;
59identifier tocheck.i1regs;
60initializer list i1regs_vals;
61position p1;
62@@
63
64u8 i1regs@p1[...] = { i1regs_vals, };
65
66@getregs2@
67identifier tocheck.i2regs;
68initializer list i2regs_vals;
69position p2;
70@@
71
72u8 i2regs@p2[...] = { i2regs_vals, };
73
74@script:ocaml@
75(_,i1regs_vals) << getregs1.i1regs_vals;
76(_,i2regs_vals) << getregs2.i2regs_vals;
77i1regs << tocheck.i1regs;
78i2regs << tocheck.i2regs;
79p1 << getregs1.p1;
80p2 << getregs2.p2;
81@@
82
83if i1regs < i2regs &&
84 List.sort compare i1regs_vals = List.sort compare i2regs_vals
85then
86 let msg =
87 Printf.sprintf
88 "WARNING %s and %s (line %d) are identical\n"
89 i1regs i2regs (List.hd p2).line in
90 print_report p1 msg
91
92(* ---------------------------------------------------------------- *)
93
94@getdmregs1@
95identifier tocheck.i1dmregs;
96initializer list i1dmregs_vals;
97position p1;
98@@
99
100struct bq27xxx_dm_reg i1dmregs@p1[] = { i1dmregs_vals, };
101
102@getdmregs2@
103identifier tocheck.i2dmregs;
104initializer list i2dmregs_vals;
105position p2;
106@@
107
108struct bq27xxx_dm_reg i2dmregs@p2[] = { i2dmregs_vals, };
109
110@script:ocaml@
111(_,i1dmregs_vals) << getdmregs1.i1dmregs_vals;
112(_,i2dmregs_vals) << getdmregs2.i2dmregs_vals;
113i1dmregs << tocheck.i1dmregs;
114i2dmregs << tocheck.i2dmregs;
115p1 << getdmregs1.p1;
116p2 << getdmregs2.p2;
117@@
118
119if i1dmregs < i2dmregs &&
120 List.sort compare i1dmregs_vals = List.sort compare i2dmregs_vals
121then
122 let msg =
123 Printf.sprintf
124 "WARNING %s and %s (line %d) are identical\n"
125 i1dmregs i2dmregs (List.hd p2).line in
126 print_report p1 msg
127
128(* ---------------------------------------------------------------- *)
129
130@getprops1@
131identifier tocheck.i1props;
132initializer list[n1] i1props_vals;
133position p1;
134@@
135
136enum power_supply_property i1props@p1[] = { i1props_vals, };
137
138@getprops2@
139identifier tocheck.i2props;
140initializer list[n2] i2props_vals;
141position p2;
142@@
143
144enum power_supply_property i2props@p2[] = { i2props_vals, };
145
146@script:ocaml@
147(_,i1props_vals) << getprops1.i1props_vals;
148(_,i2props_vals) << getprops2.i2props_vals;
149i1props << tocheck.i1props;
150i2props << tocheck.i2props;
151p1 << getprops1.p1;
152p2 << getprops2.p2;
153@@
154
155if i1props < i2props &&
156 List.sort compare i1props_vals = List.sort compare i2props_vals
157then
158 let msg =
159 Printf.sprintf
160 "WARNING %s and %s (line %d) are identical\n"
161 i1props i2props (List.hd p2).line in
162 print_report p1 msg
diff --git a/scripts/coccinelle/api/d_find_alias.cocci b/scripts/coccinelle/api/d_find_alias.cocci
new file mode 100644
index 000000000..47e050166
--- /dev/null
+++ b/scripts/coccinelle/api/d_find_alias.cocci
@@ -0,0 +1,81 @@
1// SPDX-License-Identifier: GPL-2.0
2/// Make sure calls to d_find_alias() have a corresponding call to dput().
3//
4// Keywords: d_find_alias, dput
5//
6// Confidence: Moderate
7// URL: http://coccinelle.lip6.fr/
8// Options: --include-headers
9
10virtual context
11virtual org
12virtual patch
13virtual report
14
15@r exists@
16local idexpression struct dentry *dent;
17expression E, E1;
18statement S1, S2;
19position p1, p2;
20@@
21(
22 if (!(dent@p1 = d_find_alias(...))) S1
23|
24 dent@p1 = d_find_alias(...)
25)
26
27<...when != dput(dent)
28 when != if (...) { <+... dput(dent) ...+> }
29 when != true !dent || ...
30 when != dent = E
31 when != E = dent
32if (!dent || ...) S2
33...>
34(
35 return <+...dent...+>;
36|
37 return @p2 ...;
38|
39 dent@p2 = E1;
40|
41 E1 = dent;
42)
43
44@depends on context@
45local idexpression struct dentry *r.dent;
46position r.p1,r.p2;
47@@
48* dent@p1 = ...
49 ...
50(
51* return@p2 ...;
52|
53* dent@p2
54)
55
56
57@script:python depends on org@
58p1 << r.p1;
59p2 << r.p2;
60@@
61cocci.print_main("Missing call to dput()",p1)
62cocci.print_secs("",p2)
63
64@depends on patch@
65local idexpression struct dentry *r.dent;
66position r.p2;
67@@
68(
69+ dput(dent);
70 return @p2 ...;
71|
72+ dput(dent);
73 dent@p2 = ...;
74)
75
76@script:python depends on report@
77p1 << r.p1;
78p2 << r.p2;
79@@
80msg = "Missing call to dput() at line %s."
81coccilib.report.print_report(p1[0], msg % (p2[0].line))
diff --git a/scripts/coccinelle/api/debugfs/debugfs_simple_attr.cocci b/scripts/coccinelle/api/debugfs/debugfs_simple_attr.cocci
new file mode 100644
index 000000000..7c3123105
--- /dev/null
+++ b/scripts/coccinelle/api/debugfs/debugfs_simple_attr.cocci
@@ -0,0 +1,68 @@
1// SPDX-License-Identifier: GPL-2.0
2/// Use DEFINE_DEBUGFS_ATTRIBUTE rather than DEFINE_SIMPLE_ATTRIBUTE
3/// for debugfs files.
4///
5//# Rationale: DEFINE_SIMPLE_ATTRIBUTE + debugfs_create_file()
6//# imposes some significant overhead as compared to
7//# DEFINE_DEBUGFS_ATTRIBUTE + debugfs_create_file_unsafe().
8//
9// Copyright (C): 2016 Nicolai Stange
10// Options: --no-includes
11//
12
13virtual context
14virtual patch
15virtual org
16virtual report
17
18@dsa@
19declarer name DEFINE_SIMPLE_ATTRIBUTE;
20identifier dsa_fops;
21expression dsa_get, dsa_set, dsa_fmt;
22position p;
23@@
24DEFINE_SIMPLE_ATTRIBUTE@p(dsa_fops, dsa_get, dsa_set, dsa_fmt);
25
26@dcf@
27expression name, mode, parent, data;
28identifier dsa.dsa_fops;
29@@
30debugfs_create_file(name, mode, parent, data, &dsa_fops)
31
32
33@context_dsa depends on context && dcf@
34declarer name DEFINE_DEBUGFS_ATTRIBUTE;
35identifier dsa.dsa_fops;
36expression dsa.dsa_get, dsa.dsa_set, dsa.dsa_fmt;
37@@
38* DEFINE_SIMPLE_ATTRIBUTE(dsa_fops, dsa_get, dsa_set, dsa_fmt);
39
40
41@patch_dcf depends on patch expression@
42expression name, mode, parent, data;
43identifier dsa.dsa_fops;
44@@
45- debugfs_create_file(name, mode, parent, data, &dsa_fops)
46+ debugfs_create_file_unsafe(name, mode, parent, data, &dsa_fops)
47
48@patch_dsa depends on patch_dcf && patch@
49identifier dsa.dsa_fops;
50expression dsa.dsa_get, dsa.dsa_set, dsa.dsa_fmt;
51@@
52- DEFINE_SIMPLE_ATTRIBUTE(dsa_fops, dsa_get, dsa_set, dsa_fmt);
53+ DEFINE_DEBUGFS_ATTRIBUTE(dsa_fops, dsa_get, dsa_set, dsa_fmt);
54
55
56@script:python depends on org && dcf@
57fops << dsa.dsa_fops;
58p << dsa.p;
59@@
60msg="%s should be defined with DEFINE_DEBUGFS_ATTRIBUTE" % (fops)
61coccilib.org.print_todo(p[0], msg)
62
63@script:python depends on report && dcf@
64fops << dsa.dsa_fops;
65p << dsa.p;
66@@
67msg="WARNING: %s should be defined with DEFINE_DEBUGFS_ATTRIBUTE" % (fops)
68coccilib.report.print_report(p[0], msg)
diff --git a/scripts/coccinelle/api/device_attr_show.cocci b/scripts/coccinelle/api/device_attr_show.cocci
new file mode 100644
index 000000000..a28dc0616
--- /dev/null
+++ b/scripts/coccinelle/api/device_attr_show.cocci
@@ -0,0 +1,55 @@
1// SPDX-License-Identifier: GPL-2.0-only
2///
3/// From Documentation/filesystems/sysfs.rst:
4/// show() must not use snprintf() when formatting the value to be
5/// returned to user space. If you can guarantee that an overflow
6/// will never happen you can use sprintf() otherwise you must use
7/// scnprintf().
8///
9// Confidence: High
10// Copyright: (C) 2020 Denis Efremov ISPRAS
11// Options: --no-includes --include-headers
12//
13
14virtual report
15virtual org
16virtual context
17virtual patch
18
19@r depends on !patch@
20identifier show, dev, attr, buf;
21position p;
22@@
23
24ssize_t show(struct device *dev, struct device_attribute *attr, char *buf)
25{
26 <...
27* return snprintf@p(...);
28 ...>
29}
30
31@rp depends on patch@
32identifier show, dev, attr, buf;
33@@
34
35ssize_t show(struct device *dev, struct device_attribute *attr, char *buf)
36{
37 <...
38 return
39- snprintf
40+ scnprintf
41 (...);
42 ...>
43}
44
45@script: python depends on report@
46p << r.p;
47@@
48
49coccilib.report.print_report(p[0], "WARNING: use scnprintf or sprintf")
50
51@script: python depends on org@
52p << r.p;
53@@
54
55coccilib.org.print_todo(p[0], "WARNING: use scnprintf or sprintf")
diff --git a/scripts/coccinelle/api/err_cast.cocci b/scripts/coccinelle/api/err_cast.cocci
new file mode 100644
index 000000000..0e661c8d8
--- /dev/null
+++ b/scripts/coccinelle/api/err_cast.cocci
@@ -0,0 +1,57 @@
1// SPDX-License-Identifier: GPL-2.0-only
2///
3/// Use ERR_CAST inlined function instead of ERR_PTR(PTR_ERR(...))
4///
5// Confidence: High
6// Copyright: (C) 2009, 2010 Nicolas Palix, DIKU.
7// Copyright: (C) 2009, 2010 Julia Lawall, DIKU.
8// Copyright: (C) 2009, 2010 Gilles Muller, INRIA/LiP6.
9// URL: http://coccinelle.lip6.fr/
10// Options:
11//
12// Keywords: ERR_PTR, PTR_ERR, ERR_CAST
13// Version min: 2.6.25
14//
15
16virtual context
17virtual patch
18virtual org
19virtual report
20
21
22@ depends on context && !patch && !org && !report@
23expression x;
24@@
25
26* ERR_PTR(PTR_ERR(x))
27
28@ depends on !context && patch && !org && !report @
29expression x;
30@@
31
32- ERR_PTR(PTR_ERR(x))
33+ ERR_CAST(x)
34
35@r depends on !context && !patch && (org || report)@
36expression x;
37position p;
38@@
39
40 ERR_PTR@p(PTR_ERR(x))
41
42@script:python depends on org@
43p << r.p;
44x << r.x;
45@@
46
47msg="WARNING ERR_CAST can be used with %s" % (x)
48msg_safe=msg.replace("[","@(").replace("]",")")
49coccilib.org.print_todo(p[0], msg_safe)
50
51@script:python depends on report@
52p << r.p;
53x << r.x;
54@@
55
56msg="WARNING: ERR_CAST can be used with %s" % (x)
57coccilib.report.print_report(p[0], msg)
diff --git a/scripts/coccinelle/api/kfree_mismatch.cocci b/scripts/coccinelle/api/kfree_mismatch.cocci
new file mode 100644
index 000000000..d46a9b3eb
--- /dev/null
+++ b/scripts/coccinelle/api/kfree_mismatch.cocci
@@ -0,0 +1,228 @@
1// SPDX-License-Identifier: GPL-2.0-only
2///
3/// Check that kvmalloc'ed memory is freed by kfree functions,
4/// vmalloc'ed by vfree functions and kvmalloc'ed by kvfree
5/// functions.
6///
7// Confidence: High
8// Copyright: (C) 2020 Denis Efremov ISPRAS
9// Options: --no-includes --include-headers
10//
11
12virtual patch
13virtual report
14virtual org
15virtual context
16
17@alloc@
18expression E, E1;
19position kok, vok;
20@@
21
22(
23 if (...) {
24 ...
25 E = \(kmalloc\|kzalloc\|krealloc\|kcalloc\|
26 kmalloc_node\|kzalloc_node\|kmalloc_array\|
27 kmalloc_array_node\|kcalloc_node\)(...)@kok
28 ...
29 } else {
30 ...
31 E = \(vmalloc\|vzalloc\|vmalloc_user\|vmalloc_node\|
32 vzalloc_node\|vmalloc_exec\|vmalloc_32\|
33 vmalloc_32_user\|__vmalloc\|__vmalloc_node_range\|
34 __vmalloc_node\)(...)@vok
35 ...
36 }
37|
38 E = \(kmalloc\|kzalloc\|krealloc\|kcalloc\|kmalloc_node\|kzalloc_node\|
39 kmalloc_array\|kmalloc_array_node\|kcalloc_node\)(...)@kok
40 ... when != E = E1
41 when any
42 if (E == NULL) {
43 ...
44 E = \(vmalloc\|vzalloc\|vmalloc_user\|vmalloc_node\|
45 vzalloc_node\|vmalloc_exec\|vmalloc_32\|
46 vmalloc_32_user\|__vmalloc\|__vmalloc_node_range\|
47 __vmalloc_node\)(...)@vok
48 ...
49 }
50)
51
52@free@
53expression E;
54position fok;
55@@
56
57 E = \(kvmalloc\|kvzalloc\|kvcalloc\|kvzalloc_node\|kvmalloc_node\|
58 kvmalloc_array\)(...)
59 ...
60 kvfree(E)@fok
61
62@vfree depends on !patch@
63expression E;
64position a != alloc.kok;
65position f != free.fok;
66@@
67
68* E = \(kmalloc\|kzalloc\|krealloc\|kcalloc\|kmalloc_node\|
69* kzalloc_node\|kmalloc_array\|kmalloc_array_node\|
70* kcalloc_node\)(...)@a
71 ... when != if (...) { ... E = \(vmalloc\|vzalloc\|vmalloc_user\|vmalloc_node\|vzalloc_node\|vmalloc_exec\|vmalloc_32\|vmalloc_32_user\|__vmalloc\|__vmalloc_node_range\|__vmalloc_node\)(...); ... }
72 when != is_vmalloc_addr(E)
73 when any
74* \(vfree\|vfree_atomic\|kvfree\)(E)@f
75
76@depends on patch exists@
77expression E;
78position a != alloc.kok;
79position f != free.fok;
80@@
81
82 E = \(kmalloc\|kzalloc\|krealloc\|kcalloc\|kmalloc_node\|
83 kzalloc_node\|kmalloc_array\|kmalloc_array_node\|
84 kcalloc_node\)(...)@a
85 ... when != if (...) { ... E = \(vmalloc\|vzalloc\|vmalloc_user\|vmalloc_node\|vzalloc_node\|vmalloc_exec\|vmalloc_32\|vmalloc_32_user\|__vmalloc\|__vmalloc_node_range\|__vmalloc_node\)(...); ... }
86 when != is_vmalloc_addr(E)
87 when any
88- \(vfree\|vfree_atomic\|kvfree\)(E)@f
89+ kfree(E)
90
91@kfree depends on !patch@
92expression E;
93position a != alloc.vok;
94position f != free.fok;
95@@
96
97* E = \(vmalloc\|vzalloc\|vmalloc_user\|vmalloc_node\|vzalloc_node\|
98* vmalloc_exec\|vmalloc_32\|vmalloc_32_user\|__vmalloc\|
99* __vmalloc_node_range\|__vmalloc_node\)(...)@a
100 ... when != is_vmalloc_addr(E)
101 when any
102* \(kfree\|kfree_sensitive\|kvfree\)(E)@f
103
104@depends on patch exists@
105expression E;
106position a != alloc.vok;
107position f != free.fok;
108@@
109
110 E = \(vmalloc\|vzalloc\|vmalloc_user\|vmalloc_node\|vzalloc_node\|
111 vmalloc_exec\|vmalloc_32\|vmalloc_32_user\|__vmalloc\|
112 __vmalloc_node_range\|__vmalloc_node\)(...)@a
113 ... when != is_vmalloc_addr(E)
114 when any
115- \(kfree\|kvfree\)(E)@f
116+ vfree(E)
117
118@kvfree depends on !patch@
119expression E;
120position a, f;
121@@
122
123* E = \(kvmalloc\|kvzalloc\|kvcalloc\|kvzalloc_node\|kvmalloc_node\|
124* kvmalloc_array\)(...)@a
125 ... when != is_vmalloc_addr(E)
126 when any
127* \(kfree\|kfree_sensitive\|vfree\|vfree_atomic\)(E)@f
128
129@depends on patch exists@
130expression E;
131@@
132
133 E = \(kvmalloc\|kvzalloc\|kvcalloc\|kvzalloc_node\|kvmalloc_node\|
134 kvmalloc_array\)(...)
135 ... when != is_vmalloc_addr(E)
136 when any
137- \(kfree\|vfree\)(E)
138+ kvfree(E)
139
140@kvfree_switch depends on !patch@
141expression alloc.E;
142position f;
143@@
144
145 ... when != is_vmalloc_addr(E)
146 when any
147* \(kfree\|kfree_sensitive\|vfree\|vfree_atomic\)(E)@f
148
149@depends on patch exists@
150expression alloc.E;
151position f;
152@@
153
154 ... when != is_vmalloc_addr(E)
155 when any
156(
157- \(kfree\|vfree\)(E)@f
158+ kvfree(E)
159|
160- kfree_sensitive(E)@f
161+ kvfree_sensitive(E)
162)
163
164@script: python depends on report@
165a << vfree.a;
166f << vfree.f;
167@@
168
169msg = "WARNING kmalloc is used to allocate this memory at line %s" % (a[0].line)
170coccilib.report.print_report(f[0], msg)
171
172@script: python depends on org@
173a << vfree.a;
174f << vfree.f;
175@@
176
177msg = "WARNING kmalloc is used to allocate this memory at line %s" % (a[0].line)
178coccilib.org.print_todo(f[0], msg)
179
180@script: python depends on report@
181a << kfree.a;
182f << kfree.f;
183@@
184
185msg = "WARNING vmalloc is used to allocate this memory at line %s" % (a[0].line)
186coccilib.report.print_report(f[0], msg)
187
188@script: python depends on org@
189a << kfree.a;
190f << kfree.f;
191@@
192
193msg = "WARNING vmalloc is used to allocate this memory at line %s" % (a[0].line)
194coccilib.org.print_todo(f[0], msg)
195
196@script: python depends on report@
197a << kvfree.a;
198f << kvfree.f;
199@@
200
201msg = "WARNING kvmalloc is used to allocate this memory at line %s" % (a[0].line)
202coccilib.report.print_report(f[0], msg)
203
204@script: python depends on org@
205a << kvfree.a;
206f << kvfree.f;
207@@
208
209msg = "WARNING kvmalloc is used to allocate this memory at line %s" % (a[0].line)
210coccilib.org.print_todo(f[0], msg)
211
212@script: python depends on report@
213ka << alloc.kok;
214va << alloc.vok;
215f << kvfree_switch.f;
216@@
217
218msg = "WARNING kmalloc (line %s) && vmalloc (line %s) are used to allocate this memory" % (ka[0].line, va[0].line)
219coccilib.report.print_report(f[0], msg)
220
221@script: python depends on org@
222ka << alloc.kok;
223va << alloc.vok;
224f << kvfree_switch.f;
225@@
226
227msg = "WARNING kmalloc (line %s) && vmalloc (line %s) are used to allocate this memory" % (ka[0].line, va[0].line)
228coccilib.org.print_todo(f[0], msg)
diff --git a/scripts/coccinelle/api/kfree_sensitive.cocci b/scripts/coccinelle/api/kfree_sensitive.cocci
new file mode 100644
index 000000000..8d980ebf3
--- /dev/null
+++ b/scripts/coccinelle/api/kfree_sensitive.cocci
@@ -0,0 +1,100 @@
1// SPDX-License-Identifier: GPL-2.0-only
2///
3/// Use kfree_sensitive, kvfree_sensitive rather than memset or
4/// memzero_explicit followed by kfree.
5///
6// Confidence: High
7// Copyright: (C) 2020 Denis Efremov ISPRAS
8// Options: --no-includes --include-headers
9//
10// Keywords: kfree_sensitive, kvfree_sensitive
11//
12
13virtual context
14virtual patch
15virtual org
16virtual report
17
18@initialize:python@
19@@
20# kmalloc_oob_in_memset uses memset to explicitly trigger out-of-bounds access
21filter = frozenset(['kmalloc_oob_in_memset',
22 'kfree_sensitive', 'kvfree_sensitive'])
23
24def relevant(p):
25 return not (filter & {el.current_element for el in p})
26
27@cond@
28position ok;
29@@
30
31if (...)
32 \(memset@ok\|memzero_explicit@ok\)(...);
33
34@r depends on !patch forall@
35expression E;
36position p : script:python() { relevant(p) };
37position m != cond.ok;
38type T;
39@@
40
41(
42* memset@m((T)E, 0, ...);
43|
44* memzero_explicit@m((T)E, ...);
45)
46 ... when != E
47 when strict
48* \(kfree\|vfree\|kvfree\)(E)@p;
49
50@rp_memzero depends on patch@
51expression E, size;
52position p : script:python() { relevant(p) };
53position m != cond.ok;
54type T;
55@@
56
57- memzero_explicit@m((T)E, size);
58 ... when != E
59 when strict
60(
61- kfree(E)@p;
62+ kfree_sensitive(E);
63|
64- \(vfree\|kvfree\)(E)@p;
65+ kvfree_sensitive(E, size);
66)
67
68@rp_memset depends on patch@
69expression E, size;
70position p : script:python() { relevant(p) };
71position m != cond.ok;
72type T;
73@@
74
75- memset@m((T)E, 0, size);
76 ... when != E
77 when strict
78(
79- kfree(E)@p;
80+ kfree_sensitive(E);
81|
82- \(vfree\|kvfree\)(E)@p;
83+ kvfree_sensitive(E, size);
84)
85
86@script:python depends on report@
87p << r.p;
88m << r.m;
89@@
90
91msg = "WARNING opportunity for kfree_sensitive/kvfree_sensitive (memset at line %s)"
92coccilib.report.print_report(p[0], msg % (m[0].line))
93
94@script:python depends on org@
95p << r.p;
96m << r.m;
97@@
98
99msg = "WARNING opportunity for kfree_sensitive/kvfree_sensitive (memset at line %s)"
100coccilib.org.print_todo(p[0], msg % (m[0].line))
diff --git a/scripts/coccinelle/api/kobj_to_dev.cocci b/scripts/coccinelle/api/kobj_to_dev.cocci
new file mode 100644
index 000000000..cd5d31c6f
--- /dev/null
+++ b/scripts/coccinelle/api/kobj_to_dev.cocci
@@ -0,0 +1,45 @@
1// SPDX-License-Identifier: GPL-2.0-only
2///
3/// Use kobj_to_dev() instead of container_of()
4///
5// Confidence: High
6// Copyright: (C) 2020 Denis Efremov ISPRAS
7// Options: --no-includes --include-headers
8//
9// Keywords: kobj_to_dev, container_of
10//
11
12virtual context
13virtual report
14virtual org
15virtual patch
16
17
18@r depends on !patch@
19expression ptr;
20symbol kobj;
21position p;
22@@
23
24* container_of(ptr, struct device, kobj)@p
25
26
27@depends on patch@
28expression ptr;
29@@
30
31- container_of(ptr, struct device, kobj)
32+ kobj_to_dev(ptr)
33
34
35@script:python depends on report@
36p << r.p;
37@@
38
39coccilib.report.print_report(p[0], "WARNING opportunity for kobj_to_dev()")
40
41@script:python depends on org@
42p << r.p;
43@@
44
45coccilib.org.print_todo(p[0], "WARNING opportunity for kobj_to_dev()")
diff --git a/scripts/coccinelle/api/kstrdup.cocci b/scripts/coccinelle/api/kstrdup.cocci
new file mode 100644
index 000000000..3c6dc5469
--- /dev/null
+++ b/scripts/coccinelle/api/kstrdup.cocci
@@ -0,0 +1,105 @@
1// SPDX-License-Identifier: GPL-2.0-only
2/// Use kstrdup rather than duplicating its implementation
3///
4// Confidence: High
5// Copyright: (C) 2010-2012 Nicolas Palix.
6// Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6.
7// Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6.
8// URL: http://coccinelle.lip6.fr/
9// Comments:
10// Options: --no-includes --include-headers
11
12virtual patch
13virtual context
14virtual org
15virtual report
16
17@depends on patch@
18expression from,to;
19expression flag,E1,E2;
20statement S;
21@@
22
23- to = kmalloc(strlen(from) + 1,flag);
24+ to = kstrdup(from, flag);
25 ... when != \(from = E1 \| to = E1 \)
26 if (to==NULL || ...) S
27 ... when != \(from = E2 \| to = E2 \)
28- strcpy(to, from);
29
30@depends on patch@
31expression x,from,to;
32expression flag,E1,E2,E3;
33statement S;
34@@
35
36- x = strlen(from) + 1;
37 ... when != \( x = E1 \| from = E1 \)
38- to = \(kmalloc\|kzalloc\)(x,flag);
39+ to = kstrdup(from, flag);
40 ... when != \(x = E2 \| from = E2 \| to = E2 \)
41 if (to==NULL || ...) S
42 ... when != \(x = E3 \| from = E3 \| to = E3 \)
43- memcpy(to, from, x);
44
45// ---------------------------------------------------------------------
46
47@r1 depends on !patch exists@
48expression from,to;
49expression flag,E1,E2;
50statement S;
51position p1,p2;
52@@
53
54* to = kmalloc@p1(strlen(from) + 1,flag);
55 ... when != \(from = E1 \| to = E1 \)
56 if (to==NULL || ...) S
57 ... when != \(from = E2 \| to = E2 \)
58* strcpy@p2(to, from);
59
60@r2 depends on !patch exists@
61expression x,from,to;
62expression flag,E1,E2,E3;
63statement S;
64position p1,p2;
65@@
66
67* x = strlen(from) + 1;
68 ... when != \( x = E1 \| from = E1 \)
69* to = \(kmalloc@p1\|kzalloc@p1\)(x,flag);
70 ... when != \(x = E2 \| from = E2 \| to = E2 \)
71 if (to==NULL || ...) S
72 ... when != \(x = E3 \| from = E3 \| to = E3 \)
73* memcpy@p2(to, from, x);
74
75@script:python depends on org@
76p1 << r1.p1;
77p2 << r1.p2;
78@@
79
80cocci.print_main("WARNING opportunity for kstrdup",p1)
81cocci.print_secs("strcpy",p2)
82
83@script:python depends on org@
84p1 << r2.p1;
85p2 << r2.p2;
86@@
87
88cocci.print_main("WARNING opportunity for kstrdup",p1)
89cocci.print_secs("memcpy",p2)
90
91@script:python depends on report@
92p1 << r1.p1;
93p2 << r1.p2;
94@@
95
96msg = "WARNING opportunity for kstrdup (strcpy on line %s)" % (p2[0].line)
97coccilib.report.print_report(p1[0], msg)
98
99@script:python depends on report@
100p1 << r2.p1;
101p2 << r2.p2;
102@@
103
104msg = "WARNING opportunity for kstrdup (memcpy on line %s)" % (p2[0].line)
105coccilib.report.print_report(p1[0], msg)
diff --git a/scripts/coccinelle/api/kvmalloc.cocci b/scripts/coccinelle/api/kvmalloc.cocci
new file mode 100644
index 000000000..c30dab718
--- /dev/null
+++ b/scripts/coccinelle/api/kvmalloc.cocci
@@ -0,0 +1,256 @@
1// SPDX-License-Identifier: GPL-2.0-only
2///
3/// Find if/else condition with kmalloc/vmalloc calls.
4/// Suggest to use kvmalloc instead. Same for kvfree.
5///
6// Confidence: High
7// Copyright: (C) 2020 Denis Efremov ISPRAS
8// Options: --no-includes --include-headers
9//
10
11virtual patch
12virtual report
13virtual org
14virtual context
15
16@initialize:python@
17@@
18filter = frozenset(['kvfree'])
19
20def relevant(p):
21 return not (filter & {el.current_element for el in p})
22
23@kvmalloc depends on !patch@
24expression E, E1, size;
25identifier flags;
26binary operator cmp = {<=, <, ==, >, >=};
27identifier x;
28type T;
29position p;
30@@
31
32(
33* if (size cmp E1 || ...)@p {
34 ...
35* E = \(kmalloc\|kzalloc\|kcalloc\|kmalloc_node\|kzalloc_node\|
36* kmalloc_array\|kmalloc_array_node\|kcalloc_node\)
37* (..., size, \(flags\|GFP_KERNEL\|\(GFP_KERNEL\|flags\)|__GFP_NOWARN\), ...)
38 ...
39 } else {
40 ...
41* E = \(vmalloc\|vzalloc\|vmalloc_node\|vzalloc_node\)(..., size, ...)
42 ...
43 }
44|
45* E = \(kmalloc\|kzalloc\|kcalloc\|kmalloc_node\|kzalloc_node\|
46* kmalloc_array\|kmalloc_array_node\|kcalloc_node\)
47* (..., size, \(flags\|GFP_KERNEL\|\(GFP_KERNEL\|flags\)|__GFP_NOWARN\), ...)
48 ... when != E = E1
49 when != size = E1
50 when any
51* if (E == NULL)@p {
52 ...
53* E = \(vmalloc\|vzalloc\|vmalloc_node\|vzalloc_node\)(..., size, ...)
54 ...
55 }
56|
57* T x = \(kmalloc\|kzalloc\|kcalloc\|kmalloc_node\|kzalloc_node\|
58* kmalloc_array\|kmalloc_array_node\|kcalloc_node\)
59* (..., size, \(flags\|GFP_KERNEL\|\(GFP_KERNEL\|flags\)|__GFP_NOWARN\), ...);
60 ... when != x = E1
61 when != size = E1
62 when any
63* if (x == NULL)@p {
64 ...
65* x = \(vmalloc\|vzalloc\|vmalloc_node\|vzalloc_node\)(..., size, ...)
66 ...
67 }
68)
69
70@kvfree depends on !patch@
71expression E;
72position p : script:python() { relevant(p) };
73@@
74
75* if (is_vmalloc_addr(E))@p {
76 ...
77* vfree(E)
78 ...
79 } else {
80 ... when != krealloc(E, ...)
81 when any
82* \(kfree\|kzfree\)(E)
83 ...
84 }
85
86@depends on patch@
87expression E, E1, size, node;
88binary operator cmp = {<=, <, ==, >, >=};
89identifier flags, x;
90type T;
91@@
92
93(
94- if (size cmp E1)
95- E = kmalloc(size, flags);
96- else
97- E = vmalloc(size);
98+ E = kvmalloc(size, flags);
99|
100- if (size cmp E1)
101- E = kmalloc(size, \(GFP_KERNEL\|GFP_KERNEL|__GFP_NOWARN\));
102- else
103- E = vmalloc(size);
104+ E = kvmalloc(size, GFP_KERNEL);
105|
106- E = kmalloc(size, flags | __GFP_NOWARN);
107- if (E == NULL)
108- E = vmalloc(size);
109+ E = kvmalloc(size, flags);
110|
111- E = kmalloc(size, \(GFP_KERNEL\|GFP_KERNEL|__GFP_NOWARN\));
112- if (E == NULL)
113- E = vmalloc(size);
114+ E = kvmalloc(size, GFP_KERNEL);
115|
116- T x = kmalloc(size, flags | __GFP_NOWARN);
117- if (x == NULL)
118- x = vmalloc(size);
119+ T x = kvmalloc(size, flags);
120|
121- T x = kmalloc(size, \(GFP_KERNEL\|GFP_KERNEL|__GFP_NOWARN\));
122- if (x == NULL)
123- x = vmalloc(size);
124+ T x = kvmalloc(size, GFP_KERNEL);
125|
126- if (size cmp E1)
127- E = kzalloc(size, flags);
128- else
129- E = vzalloc(size);
130+ E = kvzalloc(size, flags);
131|
132- if (size cmp E1)
133- E = kzalloc(size, \(GFP_KERNEL\|GFP_KERNEL|__GFP_NOWARN\));
134- else
135- E = vzalloc(size);
136+ E = kvzalloc(size, GFP_KERNEL);
137|
138- E = kzalloc(size, flags | __GFP_NOWARN);
139- if (E == NULL)
140- E = vzalloc(size);
141+ E = kvzalloc(size, flags);
142|
143- E = kzalloc(size, \(GFP_KERNEL\|GFP_KERNEL|__GFP_NOWARN\));
144- if (E == NULL)
145- E = vzalloc(size);
146+ E = kvzalloc(size, GFP_KERNEL);
147|
148- T x = kzalloc(size, flags | __GFP_NOWARN);
149- if (x == NULL)
150- x = vzalloc(size);
151+ T x = kvzalloc(size, flags);
152|
153- T x = kzalloc(size, \(GFP_KERNEL\|GFP_KERNEL|__GFP_NOWARN\));
154- if (x == NULL)
155- x = vzalloc(size);
156+ T x = kvzalloc(size, GFP_KERNEL);
157|
158- if (size cmp E1)
159- E = kmalloc_node(size, flags, node);
160- else
161- E = vmalloc_node(size, node);
162+ E = kvmalloc_node(size, flags, node);
163|
164- if (size cmp E1)
165- E = kmalloc_node(size, \(GFP_KERNEL\|GFP_KERNEL|__GFP_NOWARN\), node);
166- else
167- E = vmalloc_node(size, node);
168+ E = kvmalloc_node(size, GFP_KERNEL, node);
169|
170- E = kmalloc_node(size, flags | __GFP_NOWARN, node);
171- if (E == NULL)
172- E = vmalloc_node(size, node);
173+ E = kvmalloc_node(size, flags, node);
174|
175- E = kmalloc_node(size, \(GFP_KERNEL\|GFP_KERNEL|__GFP_NOWARN\), node);
176- if (E == NULL)
177- E = vmalloc_node(size, node);
178+ E = kvmalloc_node(size, GFP_KERNEL, node);
179|
180- T x = kmalloc_node(size, flags | __GFP_NOWARN, node);
181- if (x == NULL)
182- x = vmalloc_node(size, node);
183+ T x = kvmalloc_node(size, flags, node);
184|
185- T x = kmalloc_node(size, \(GFP_KERNEL\|GFP_KERNEL|__GFP_NOWARN\), node);
186- if (x == NULL)
187- x = vmalloc_node(size, node);
188+ T x = kvmalloc_node(size, GFP_KERNEL, node);
189|
190- if (size cmp E1)
191- E = kvzalloc_node(size, flags, node);
192- else
193- E = vzalloc_node(size, node);
194+ E = kvzalloc_node(size, flags, node);
195|
196- if (size cmp E1)
197- E = kvzalloc_node(size, \(GFP_KERNEL\|GFP_KERNEL|__GFP_NOWARN\), node);
198- else
199- E = vzalloc_node(size, node);
200+ E = kvzalloc_node(size, GFP_KERNEL, node);
201|
202- E = kvzalloc_node(size, flags | __GFP_NOWARN, node);
203- if (E == NULL)
204- E = vzalloc_node(size, node);
205+ E = kvzalloc_node(size, flags, node);
206|
207- E = kvzalloc_node(size, \(GFP_KERNEL\|GFP_KERNEL|__GFP_NOWARN\), node);
208- if (E == NULL)
209- E = vzalloc_node(size, node);
210+ E = kvzalloc_node(size, GFP_KERNEL, node);
211|
212- T x = kvzalloc_node(size, flags | __GFP_NOWARN, node);
213- if (x == NULL)
214- x = vzalloc_node(size, node);
215+ T x = kvzalloc_node(size, flags, node);
216|
217- T x = kvzalloc_node(size, \(GFP_KERNEL\|GFP_KERNEL|__GFP_NOWARN\), node);
218- if (x == NULL)
219- x = vzalloc_node(size, node);
220+ T x = kvzalloc_node(size, GFP_KERNEL, node);
221)
222
223@depends on patch@
224expression E;
225position p : script:python() { relevant(p) };
226@@
227
228- if (is_vmalloc_addr(E))@p
229- vfree(E);
230- else
231- kfree(E);
232+ kvfree(E);
233
234@script: python depends on report@
235p << kvmalloc.p;
236@@
237
238coccilib.report.print_report(p[0], "WARNING opportunity for kvmalloc")
239
240@script: python depends on org@
241p << kvmalloc.p;
242@@
243
244coccilib.org.print_todo(p[0], "WARNING opportunity for kvmalloc")
245
246@script: python depends on report@
247p << kvfree.p;
248@@
249
250coccilib.report.print_report(p[0], "WARNING opportunity for kvfree")
251
252@script: python depends on org@
253p << kvfree.p;
254@@
255
256coccilib.org.print_todo(p[0], "WARNING opportunity for kvfree")
diff --git a/scripts/coccinelle/api/memdup.cocci b/scripts/coccinelle/api/memdup.cocci
new file mode 100644
index 000000000..30b15df73
--- /dev/null
+++ b/scripts/coccinelle/api/memdup.cocci
@@ -0,0 +1,66 @@
1// SPDX-License-Identifier: GPL-2.0-only
2/// Use kmemdup rather than duplicating its implementation
3///
4// Confidence: High
5// Copyright: (C) 2010-2012 Nicolas Palix.
6// Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6.
7// Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6.
8// URL: http://coccinelle.lip6.fr/
9// Comments:
10// Options: --no-includes --include-headers
11
12virtual patch
13virtual context
14virtual org
15virtual report
16
17@r1@
18expression from,to;
19expression flag;
20position p;
21@@
22
23 to = \(kmalloc@p\|kzalloc@p\)(strlen(from) + 1,flag);
24
25@r2@
26expression x,from,to;
27expression flag,E1;
28position p;
29@@
30
31 x = strlen(from) + 1;
32 ... when != \( x = E1 \| from = E1 \)
33 to = \(kmalloc@p\|kzalloc@p\)(x,flag);
34
35@depends on patch@
36expression from,to,size,flag;
37position p != {r1.p,r2.p};
38statement S;
39@@
40
41- to = \(kmalloc@p\|kzalloc@p\)(size,flag);
42+ to = kmemdup(from,size,flag);
43 if (to==NULL || ...) S
44- memcpy(to, from, size);
45
46@r depends on !patch@
47expression from,to,size,flag;
48position p != {r1.p,r2.p};
49statement S;
50@@
51
52* to = \(kmalloc@p\|kzalloc@p\)(size,flag);
53 if (to==NULL || ...) S
54* memcpy(to, from, size);
55
56@script:python depends on org@
57p << r.p;
58@@
59
60coccilib.org.print_todo(p[0], "WARNING opportunity for kmemdup")
61
62@script:python depends on report@
63p << r.p;
64@@
65
66coccilib.report.print_report(p[0], "WARNING opportunity for kmemdup")
diff --git a/scripts/coccinelle/api/memdup_user.cocci b/scripts/coccinelle/api/memdup_user.cocci
new file mode 100644
index 000000000..e01e95108
--- /dev/null
+++ b/scripts/coccinelle/api/memdup_user.cocci
@@ -0,0 +1,119 @@
1// SPDX-License-Identifier: GPL-2.0-only
2/// Use memdup_user rather than duplicating its implementation
3/// This is a little bit restricted to reduce false positives
4///
5// Confidence: High
6// Copyright: (C) 2010-2012 Nicolas Palix.
7// Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6.
8// Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6.
9// URL: http://coccinelle.lip6.fr/
10// Comments:
11// Options: --no-includes --include-headers
12
13virtual patch
14virtual context
15virtual org
16virtual report
17
18@initialize:python@
19@@
20filter = frozenset(['memdup_user', 'vmemdup_user'])
21
22def relevant(p):
23 return not (filter & {el.current_element for el in p})
24
25@depends on patch@
26expression from,to,size;
27identifier l1,l2;
28position p : script:python() { relevant(p) };
29@@
30
31- to = \(kmalloc@p\|kzalloc@p\)
32- (size,\(GFP_KERNEL\|GFP_USER\|
33- \(GFP_KERNEL\|GFP_USER\)|__GFP_NOWARN\));
34+ to = memdup_user(from,size);
35 if (
36- to==NULL
37+ IS_ERR(to)
38 || ...) {
39 <+... when != goto l1;
40- -ENOMEM
41+ PTR_ERR(to)
42 ...+>
43 }
44- if (copy_from_user(to, from, size) != 0) {
45- <+... when != goto l2;
46- -EFAULT
47- ...+>
48- }
49
50@depends on patch@
51expression from,to,size;
52identifier l1,l2;
53position p : script:python() { relevant(p) };
54@@
55
56- to = \(kvmalloc@p\|kvzalloc@p\)(size,\(GFP_KERNEL\|GFP_USER\));
57+ to = vmemdup_user(from,size);
58 if (
59- to==NULL
60+ IS_ERR(to)
61 || ...) {
62 <+... when != goto l1;
63- -ENOMEM
64+ PTR_ERR(to)
65 ...+>
66 }
67- if (copy_from_user(to, from, size) != 0) {
68- <+... when != goto l2;
69- -EFAULT
70- ...+>
71- }
72
73@r depends on !patch@
74expression from,to,size;
75position p : script:python() { relevant(p) };
76statement S1,S2;
77@@
78
79* to = \(kmalloc@p\|kzalloc@p\)
80 (size,\(GFP_KERNEL\|GFP_USER\|
81 \(GFP_KERNEL\|GFP_USER\)|__GFP_NOWARN\));
82 if (to==NULL || ...) S1
83 if (copy_from_user(to, from, size) != 0)
84 S2
85
86@rv depends on !patch@
87expression from,to,size;
88position p : script:python() { relevant(p) };
89statement S1,S2;
90@@
91
92* to = \(kvmalloc@p\|kvzalloc@p\)(size,\(GFP_KERNEL\|GFP_USER\));
93 if (to==NULL || ...) S1
94 if (copy_from_user(to, from, size) != 0)
95 S2
96
97@script:python depends on org@
98p << r.p;
99@@
100
101coccilib.org.print_todo(p[0], "WARNING opportunity for memdup_user")
102
103@script:python depends on report@
104p << r.p;
105@@
106
107coccilib.report.print_report(p[0], "WARNING opportunity for memdup_user")
108
109@script:python depends on org@
110p << rv.p;
111@@
112
113coccilib.org.print_todo(p[0], "WARNING opportunity for vmemdup_user")
114
115@script:python depends on report@
116p << rv.p;
117@@
118
119coccilib.report.print_report(p[0], "WARNING opportunity for vmemdup_user")
diff --git a/scripts/coccinelle/api/platform_get_irq.cocci b/scripts/coccinelle/api/platform_get_irq.cocci
new file mode 100644
index 000000000..06b6a95e2
--- /dev/null
+++ b/scripts/coccinelle/api/platform_get_irq.cocci
@@ -0,0 +1,102 @@
1// SPDX-License-Identifier: GPL-2.0
2/// Remove dev_err() messages after platform_get_irq*() failures
3//
4// Confidence: Medium
5// Options: --include-headers
6
7virtual patch
8virtual context
9virtual org
10virtual report
11
12@depends on context@
13expression ret;
14struct platform_device *E;
15@@
16
17ret =
18(
19platform_get_irq
20|
21platform_get_irq_byname
22)(E, ...);
23
24if ( \( ret < 0 \| ret <= 0 \) )
25{
26(
27if (ret != -EPROBE_DEFER)
28{ ...
29*dev_err(...);
30... }
31|
32...
33*dev_err(...);
34)
35...
36}
37
38@depends on patch@
39expression ret;
40struct platform_device *E;
41@@
42
43ret =
44(
45platform_get_irq
46|
47platform_get_irq_byname
48)(E, ...);
49
50if ( \( ret < 0 \| ret <= 0 \) )
51{
52(
53-if (ret != -EPROBE_DEFER)
54-{ ...
55-dev_err(...);
56-... }
57|
58...
59-dev_err(...);
60)
61...
62}
63
64@r depends on org || report@
65position p1;
66expression ret;
67struct platform_device *E;
68@@
69
70ret =
71(
72platform_get_irq
73|
74platform_get_irq_byname
75)(E, ...);
76
77if ( \( ret < 0 \| ret <= 0 \) )
78{
79(
80if (ret != -EPROBE_DEFER)
81{ ...
82dev_err@p1(...);
83... }
84|
85...
86dev_err@p1(...);
87)
88...
89}
90
91@script:python depends on org@
92p1 << r.p1;
93@@
94
95cocci.print_main(p1)
96
97@script:python depends on report@
98p1 << r.p1;
99@@
100
101msg = "line %s is redundant because platform_get_irq() already prints an error" % (p1[0].line)
102coccilib.report.print_report(p1[0],msg)
diff --git a/scripts/coccinelle/api/platform_no_drv_owner.cocci b/scripts/coccinelle/api/platform_no_drv_owner.cocci
new file mode 100644
index 000000000..8fa050eeb
--- /dev/null
+++ b/scripts/coccinelle/api/platform_no_drv_owner.cocci
@@ -0,0 +1,180 @@
1// SPDX-License-Identifier: GPL-2.0-only
2/// Remove .owner field if calls are used which set it automatically
3///
4// Confidence: High
5// Copyright: (C) 2014 Wolfram Sang.
6
7virtual patch
8virtual context
9virtual org
10virtual report
11
12@match1@
13declarer name module_i2c_driver;
14declarer name module_platform_driver;
15declarer name module_platform_driver_probe;
16identifier __driver;
17@@
18(
19 module_i2c_driver(__driver);
20|
21 module_platform_driver(__driver);
22|
23 module_platform_driver_probe(__driver, ...);
24)
25
26@fix1 depends on match1 && patch && !context && !org && !report@
27identifier match1.__driver;
28@@
29 static struct platform_driver __driver = {
30 .driver = {
31- .owner = THIS_MODULE,
32 }
33 };
34
35@fix1_i2c depends on match1 && patch && !context && !org && !report@
36identifier match1.__driver;
37@@
38 static struct i2c_driver __driver = {
39 .driver = {
40- .owner = THIS_MODULE,
41 }
42 };
43
44@match2@
45identifier __driver;
46@@
47(
48 platform_driver_register(&__driver)
49|
50 platform_driver_probe(&__driver, ...)
51|
52 platform_create_bundle(&__driver, ...)
53|
54 i2c_add_driver(&__driver)
55)
56
57@fix2 depends on match2 && patch && !context && !org && !report@
58identifier match2.__driver;
59@@
60 static struct platform_driver __driver = {
61 .driver = {
62- .owner = THIS_MODULE,
63 }
64 };
65
66@fix2_i2c depends on match2 && patch && !context && !org && !report@
67identifier match2.__driver;
68@@
69 static struct i2c_driver __driver = {
70 .driver = {
71- .owner = THIS_MODULE,
72 }
73 };
74
75// ----------------------------------------------------------------------------
76
77@fix1_context depends on match1 && !patch && (context || org || report)@
78identifier match1.__driver;
79position j0;
80@@
81
82 static struct platform_driver __driver = {
83 .driver = {
84* .owner@j0 = THIS_MODULE,
85 }
86 };
87
88@fix1_i2c_context depends on match1 && !patch && (context || org || report)@
89identifier match1.__driver;
90position j0;
91@@
92
93 static struct i2c_driver __driver = {
94 .driver = {
95* .owner@j0 = THIS_MODULE,
96 }
97 };
98
99@fix2_context depends on match2 && !patch && (context || org || report)@
100identifier match2.__driver;
101position j0;
102@@
103
104 static struct platform_driver __driver = {
105 .driver = {
106* .owner@j0 = THIS_MODULE,
107 }
108 };
109
110@fix2_i2c_context depends on match2 && !patch && (context || org || report)@
111identifier match2.__driver;
112position j0;
113@@
114
115 static struct i2c_driver __driver = {
116 .driver = {
117* .owner@j0 = THIS_MODULE,
118 }
119 };
120
121// ----------------------------------------------------------------------------
122
123@script:python fix1_org depends on org@
124j0 << fix1_context.j0;
125@@
126
127msg = "No need to set .owner here. The core will do it."
128coccilib.org.print_todo(j0[0], msg)
129
130@script:python fix1_i2c_org depends on org@
131j0 << fix1_i2c_context.j0;
132@@
133
134msg = "No need to set .owner here. The core will do it."
135coccilib.org.print_todo(j0[0], msg)
136
137@script:python fix2_org depends on org@
138j0 << fix2_context.j0;
139@@
140
141msg = "No need to set .owner here. The core will do it."
142coccilib.org.print_todo(j0[0], msg)
143
144@script:python fix2_i2c_org depends on org@
145j0 << fix2_i2c_context.j0;
146@@
147
148msg = "No need to set .owner here. The core will do it."
149coccilib.org.print_todo(j0[0], msg)
150
151// ----------------------------------------------------------------------------
152
153@script:python fix1_report depends on report@
154j0 << fix1_context.j0;
155@@
156
157msg = "No need to set .owner here. The core will do it."
158coccilib.report.print_report(j0[0], msg)
159
160@script:python fix1_i2c_report depends on report@
161j0 << fix1_i2c_context.j0;
162@@
163
164msg = "No need to set .owner here. The core will do it."
165coccilib.report.print_report(j0[0], msg)
166
167@script:python fix2_report depends on report@
168j0 << fix2_context.j0;
169@@
170
171msg = "No need to set .owner here. The core will do it."
172coccilib.report.print_report(j0[0], msg)
173
174@script:python fix2_i2c_report depends on report@
175j0 << fix2_i2c_context.j0;
176@@
177
178msg = "No need to set .owner here. The core will do it."
179coccilib.report.print_report(j0[0], msg)
180
diff --git a/scripts/coccinelle/api/pm_runtime.cocci b/scripts/coccinelle/api/pm_runtime.cocci
new file mode 100644
index 000000000..1ccce3fd0
--- /dev/null
+++ b/scripts/coccinelle/api/pm_runtime.cocci
@@ -0,0 +1,114 @@
1// SPDX-License-Identifier: GPL-2.0-only
2/// Make sure pm_runtime_* calls does not use unnecessary IS_ERR_VALUE
3///
4// Keywords: pm_runtime
5// Confidence: Medium
6// Copyright (C) 2013 Texas Instruments Incorporated -
7// URL: http://coccinelle.lip6.fr/
8// Options: --include-headers
9
10virtual patch
11virtual context
12virtual org
13virtual report
14
15//----------------------------------------------------------
16// Detection
17//----------------------------------------------------------
18
19@runtime_bad_err_handle exists@
20expression ret;
21position p;
22@@
23(
24ret@p = \(pm_runtime_idle\|
25 pm_runtime_suspend\|
26 pm_runtime_autosuspend\|
27 pm_runtime_resume\|
28 pm_request_idle\|
29 pm_request_resume\|
30 pm_request_autosuspend\|
31 pm_runtime_get\|
32 pm_runtime_get_sync\|
33 pm_runtime_put\|
34 pm_runtime_put_autosuspend\|
35 pm_runtime_put_sync\|
36 pm_runtime_put_sync_suspend\|
37 pm_runtime_put_sync_autosuspend\|
38 pm_runtime_set_active\|
39 pm_schedule_suspend\|
40 pm_runtime_barrier\|
41 pm_generic_runtime_suspend\|
42 pm_generic_runtime_resume\)(...);
43...
44IS_ERR_VALUE(ret)
45...
46)
47
48//----------------------------------------------------------
49// For context mode
50//----------------------------------------------------------
51
52@depends on context@
53identifier pm_runtime_api;
54expression ret;
55position runtime_bad_err_handle.p;
56@@
57(
58ret@p = pm_runtime_api(...);
59...
60* IS_ERR_VALUE(ret)
61...
62)
63
64//----------------------------------------------------------
65// For patch mode
66//----------------------------------------------------------
67
68@depends on patch@
69identifier pm_runtime_api;
70expression ret;
71position runtime_bad_err_handle.p;
72@@
73(
74ret@p = pm_runtime_api(...);
75...
76- IS_ERR_VALUE(ret)
77+ ret < 0
78...
79)
80
81//----------------------------------------------------------
82// For org and report mode
83//----------------------------------------------------------
84
85@r depends on (org || report) exists@
86position p1, p2;
87identifier pm_runtime_api;
88expression ret;
89position runtime_bad_err_handle.p;
90@@
91(
92ret@p = pm_runtime_api@p1(...);
93...
94IS_ERR_VALUE@p2(ret)
95...
96)
97
98@script:python depends on org@
99p1 << r.p1;
100p2 << r.p2;
101pm_runtime_api << r.pm_runtime_api;
102@@
103
104cocci.print_main(pm_runtime_api,p1)
105cocci.print_secs("IS_ERR_VALUE",p2)
106
107@script:python depends on report@
108p1 << r.p1;
109p2 << r.p2;
110pm_runtime_api << r.pm_runtime_api;
111@@
112
113msg = "%s returns < 0 as error. Unecessary IS_ERR_VALUE at line %s" % (pm_runtime_api, p2[0].line)
114coccilib.report.print_report(p1[0],msg)
diff --git a/scripts/coccinelle/api/ptr_ret.cocci b/scripts/coccinelle/api/ptr_ret.cocci
new file mode 100644
index 000000000..e76cd5d90
--- /dev/null
+++ b/scripts/coccinelle/api/ptr_ret.cocci
@@ -0,0 +1,97 @@
1// SPDX-License-Identifier: GPL-2.0-only
2///
3/// Use PTR_ERR_OR_ZERO rather than if(IS_ERR(...)) + PTR_ERR
4///
5// Confidence: High
6// Copyright: (C) 2012 Julia Lawall, INRIA/LIP6.
7// Copyright: (C) 2012 Gilles Muller, INRIA/LiP6.
8// URL: http://coccinelle.lip6.fr/
9// Options: --no-includes --include-headers
10//
11// Keywords: ERR_PTR, PTR_ERR, PTR_ERR_OR_ZERO
12// Version min: 2.6.39
13//
14
15virtual context
16virtual patch
17virtual org
18virtual report
19
20@depends on patch@
21expression ptr;
22@@
23
24- if (IS_ERR(ptr)) return PTR_ERR(ptr); else return 0;
25+ return PTR_ERR_OR_ZERO(ptr);
26
27@depends on patch@
28expression ptr;
29@@
30
31- if (IS_ERR(ptr)) return PTR_ERR(ptr); return 0;
32+ return PTR_ERR_OR_ZERO(ptr);
33
34@depends on patch@
35expression ptr;
36@@
37
38- (IS_ERR(ptr) ? PTR_ERR(ptr) : 0)
39+ PTR_ERR_OR_ZERO(ptr)
40
41@r1 depends on !patch@
42expression ptr;
43position p1;
44@@
45
46* if@p1 (IS_ERR(ptr)) return PTR_ERR(ptr); else return 0;
47
48@r2 depends on !patch@
49expression ptr;
50position p2;
51@@
52
53* if@p2 (IS_ERR(ptr)) return PTR_ERR(ptr); return 0;
54
55@r3 depends on !patch@
56expression ptr;
57position p3;
58@@
59
60* IS_ERR@p3(ptr) ? PTR_ERR(ptr) : 0
61
62@script:python depends on org@
63p << r1.p1;
64@@
65
66coccilib.org.print_todo(p[0], "WARNING: PTR_ERR_OR_ZERO can be used")
67
68
69@script:python depends on org@
70p << r2.p2;
71@@
72
73coccilib.org.print_todo(p[0], "WARNING: PTR_ERR_OR_ZERO can be used")
74
75@script:python depends on org@
76p << r3.p3;
77@@
78
79coccilib.org.print_todo(p[0], "WARNING: PTR_ERR_OR_ZERO can be used")
80
81@script:python depends on report@
82p << r1.p1;
83@@
84
85coccilib.report.print_report(p[0], "WARNING: PTR_ERR_OR_ZERO can be used")
86
87@script:python depends on report@
88p << r2.p2;
89@@
90
91coccilib.report.print_report(p[0], "WARNING: PTR_ERR_OR_ZERO can be used")
92
93@script:python depends on report@
94p << r3.p3;
95@@
96
97coccilib.report.print_report(p[0], "WARNING: PTR_ERR_OR_ZERO can be used")
diff --git a/scripts/coccinelle/api/resource_size.cocci b/scripts/coccinelle/api/resource_size.cocci
new file mode 100644
index 000000000..a9a571ac0
--- /dev/null
+++ b/scripts/coccinelle/api/resource_size.cocci
@@ -0,0 +1,94 @@
1// SPDX-License-Identifier: GPL-2.0-only
2///
3/// Use resource_size function on resource object
4/// instead of explicit computation.
5///
6// Confidence: High
7// Copyright: (C) 2009, 2010 Nicolas Palix, DIKU.
8// Copyright: (C) 2009, 2010 Julia Lawall, DIKU.
9// Copyright: (C) 2009, 2010 Gilles Muller, INRIA/LiP6.
10// URL: http://coccinelle.lip6.fr/
11// Options:
12//
13// Keywords: resource_size
14// Version min: 2.6.27 resource_size
15//
16
17virtual context
18virtual patch
19virtual org
20virtual report
21
22//----------------------------------------------------------
23// For context mode
24//----------------------------------------------------------
25
26@r_context depends on context && !patch && !org@
27struct resource *res;
28@@
29
30* (res->end - res->start) + 1
31
32//----------------------------------------------------------
33// For patch mode
34//----------------------------------------------------------
35
36@r_patch depends on !context && patch && !org@
37struct resource *res;
38@@
39
40- (res->end - res->start) + 1
41+ resource_size(res)
42
43//----------------------------------------------------------
44// For org mode
45//----------------------------------------------------------
46
47
48@r_org depends on !context && !patch && (org || report)@
49struct resource *res;
50position p;
51@@
52
53 (res->end@p - res->start) + 1
54
55@rbad_org depends on !context && !patch && (org || report)@
56struct resource *res;
57position p != r_org.p;
58@@
59
60 res->end@p - res->start
61
62@script:python depends on org@
63p << r_org.p;
64x << r_org.res;
65@@
66
67msg="ERROR with %s" % (x)
68msg_safe=msg.replace("[","@(").replace("]",")")
69coccilib.org.print_todo(p[0], msg_safe)
70
71@script:python depends on report@
72p << r_org.p;
73x << r_org.res;
74@@
75
76msg="ERROR: Missing resource_size with %s" % (x)
77coccilib.report.print_report(p[0], msg)
78
79@script:python depends on org@
80p << rbad_org.p;
81x << rbad_org.res;
82@@
83
84msg="WARNING with %s" % (x)
85msg_safe=msg.replace("[","@(").replace("]",")")
86coccilib.org.print_todo(p[0], msg_safe)
87
88@script:python depends on report@
89p << rbad_org.p;
90x << rbad_org.res;
91@@
92
93msg="WARNING: Suspicious code. resource_size is maybe missing with %s" % (x)
94coccilib.report.print_report(p[0], msg)
diff --git a/scripts/coccinelle/api/simple_open.cocci b/scripts/coccinelle/api/simple_open.cocci
new file mode 100644
index 000000000..c121876d5
--- /dev/null
+++ b/scripts/coccinelle/api/simple_open.cocci
@@ -0,0 +1,71 @@
1// SPDX-License-Identifier: GPL-2.0
2/// Remove an open coded simple_open() function
3/// and replace file operations references to the function
4/// with simple_open() instead.
5///
6// Confidence: High
7// Comments:
8// Options: --no-includes --include-headers
9
10virtual patch
11virtual report
12
13@ open depends on patch @
14identifier open_f != simple_open;
15identifier i, f;
16@@
17-int open_f(struct inode *i, struct file *f)
18-{
19(
20-if (i->i_private)
21-f->private_data = i->i_private;
22|
23-f->private_data = i->i_private;
24)
25-return 0;
26-}
27
28@ has_open depends on open @
29identifier fops;
30identifier open.open_f;
31@@
32struct file_operations fops = {
33...,
34-.open = open_f,
35+.open = simple_open,
36...
37};
38
39@ openr depends on report @
40identifier open_f != simple_open;
41identifier i, f;
42position p;
43@@
44int open_f@p(struct inode *i, struct file *f)
45{
46(
47if (i->i_private)
48f->private_data = i->i_private;
49|
50f->private_data = i->i_private;
51)
52return 0;
53}
54
55@ has_openr depends on openr @
56identifier fops;
57identifier openr.open_f;
58position p;
59@@
60struct file_operations fops = {
61...,
62.open = open_f@p,
63...
64};
65
66@script:python@
67pf << openr.p;
68ps << has_openr.p;
69@@
70
71coccilib.report.print_report(pf[0],"WARNING opportunity for simple_open, see also structure on line %s"%(ps[0].line))
diff --git a/scripts/coccinelle/api/stream_open.cocci b/scripts/coccinelle/api/stream_open.cocci
new file mode 100644
index 000000000..df00d6619
--- /dev/null
+++ b/scripts/coccinelle/api/stream_open.cocci
@@ -0,0 +1,370 @@
1// SPDX-License-Identifier: GPL-2.0
2// Author: Kirill Smelkov (kirr@nexedi.com)
3//
4// Search for stream-like files that are using nonseekable_open and convert
5// them to stream_open. A stream-like file is a file that does not use ppos in
6// its read and write. Rationale for the conversion is to avoid deadlock in
7// between read and write.
8
9virtual report
10virtual patch
11virtual explain // explain decisions in the patch (SPFLAGS="-D explain")
12
13// stream-like reader & writer - ones that do not depend on f_pos.
14@ stream_reader @
15identifier readstream, ppos;
16identifier f, buf, len;
17type loff_t;
18@@
19 ssize_t readstream(struct file *f, char *buf, size_t len, loff_t *ppos)
20 {
21 ... when != ppos
22 }
23
24@ stream_writer @
25identifier writestream, ppos;
26identifier f, buf, len;
27type loff_t;
28@@
29 ssize_t writestream(struct file *f, const char *buf, size_t len, loff_t *ppos)
30 {
31 ... when != ppos
32 }
33
34
35// a function that blocks
36@ blocks @
37identifier block_f;
38identifier wait =~ "^wait_.*";
39@@
40 block_f(...) {
41 ... when exists
42 wait(...)
43 ... when exists
44 }
45
46// stream_reader that can block inside.
47//
48// XXX wait_* can be called not directly from current function (e.g. func -> f -> g -> wait())
49// XXX currently reader_blocks supports only direct and 1-level indirect cases.
50@ reader_blocks_direct @
51identifier stream_reader.readstream;
52identifier wait =~ "^wait_.*";
53@@
54 readstream(...)
55 {
56 ... when exists
57 wait(...)
58 ... when exists
59 }
60
61@ reader_blocks_1 @
62identifier stream_reader.readstream;
63identifier blocks.block_f;
64@@
65 readstream(...)
66 {
67 ... when exists
68 block_f(...)
69 ... when exists
70 }
71
72@ reader_blocks depends on reader_blocks_direct || reader_blocks_1 @
73identifier stream_reader.readstream;
74@@
75 readstream(...) {
76 ...
77 }
78
79
80// file_operations + whether they have _any_ .read, .write, .llseek ... at all.
81//
82// XXX add support for file_operations xxx[N] = ... (sound/core/pcm_native.c)
83@ fops0 @
84identifier fops;
85@@
86 struct file_operations fops = {
87 ...
88 };
89
90@ has_read @
91identifier fops0.fops;
92identifier read_f;
93@@
94 struct file_operations fops = {
95 .read = read_f,
96 };
97
98@ has_read_iter @
99identifier fops0.fops;
100identifier read_iter_f;
101@@
102 struct file_operations fops = {
103 .read_iter = read_iter_f,
104 };
105
106@ has_write @
107identifier fops0.fops;
108identifier write_f;
109@@
110 struct file_operations fops = {
111 .write = write_f,
112 };
113
114@ has_write_iter @
115identifier fops0.fops;
116identifier write_iter_f;
117@@
118 struct file_operations fops = {
119 .write_iter = write_iter_f,
120 };
121
122@ has_llseek @
123identifier fops0.fops;
124identifier llseek_f;
125@@
126 struct file_operations fops = {
127 .llseek = llseek_f,
128 };
129
130@ has_no_llseek @
131identifier fops0.fops;
132@@
133 struct file_operations fops = {
134 .llseek = no_llseek,
135 };
136
137@ has_noop_llseek @
138identifier fops0.fops;
139@@
140 struct file_operations fops = {
141 .llseek = noop_llseek,
142 };
143
144@ has_mmap @
145identifier fops0.fops;
146identifier mmap_f;
147@@
148 struct file_operations fops = {
149 .mmap = mmap_f,
150 };
151
152@ has_copy_file_range @
153identifier fops0.fops;
154identifier copy_file_range_f;
155@@
156 struct file_operations fops = {
157 .copy_file_range = copy_file_range_f,
158 };
159
160@ has_remap_file_range @
161identifier fops0.fops;
162identifier remap_file_range_f;
163@@
164 struct file_operations fops = {
165 .remap_file_range = remap_file_range_f,
166 };
167
168@ has_splice_read @
169identifier fops0.fops;
170identifier splice_read_f;
171@@
172 struct file_operations fops = {
173 .splice_read = splice_read_f,
174 };
175
176@ has_splice_write @
177identifier fops0.fops;
178identifier splice_write_f;
179@@
180 struct file_operations fops = {
181 .splice_write = splice_write_f,
182 };
183
184
185// file_operations that is candidate for stream_open conversion - it does not
186// use mmap and other methods that assume @offset access to file.
187//
188// XXX for simplicity require no .{read/write}_iter and no .splice_{read/write} for now.
189// XXX maybe_steam.fops cannot be used in other rules - it gives "bad rule maybe_stream or bad variable fops".
190@ maybe_stream depends on (!has_llseek || has_no_llseek || has_noop_llseek) && !has_mmap && !has_copy_file_range && !has_remap_file_range && !has_read_iter && !has_write_iter && !has_splice_read && !has_splice_write @
191identifier fops0.fops;
192@@
193 struct file_operations fops = {
194 };
195
196
197// ---- conversions ----
198
199// XXX .open = nonseekable_open -> .open = stream_open
200// XXX .open = func -> openfunc -> nonseekable_open
201
202// read & write
203//
204// if both are used in the same file_operations together with an opener -
205// under that conditions we can use stream_open instead of nonseekable_open.
206@ fops_rw depends on maybe_stream @
207identifier fops0.fops, openfunc;
208identifier stream_reader.readstream;
209identifier stream_writer.writestream;
210@@
211 struct file_operations fops = {
212 .open = openfunc,
213 .read = readstream,
214 .write = writestream,
215 };
216
217@ report_rw depends on report @
218identifier fops_rw.openfunc;
219position p1;
220@@
221 openfunc(...) {
222 <...
223 nonseekable_open@p1
224 ...>
225 }
226
227@ script:python depends on report && reader_blocks @
228fops << fops0.fops;
229p << report_rw.p1;
230@@
231coccilib.report.print_report(p[0],
232 "ERROR: %s: .read() can deadlock .write(); change nonseekable_open -> stream_open to fix." % (fops,))
233
234@ script:python depends on report && !reader_blocks @
235fops << fops0.fops;
236p << report_rw.p1;
237@@
238coccilib.report.print_report(p[0],
239 "WARNING: %s: .read() and .write() have stream semantic; safe to change nonseekable_open -> stream_open." % (fops,))
240
241
242@ explain_rw_deadlocked depends on explain && reader_blocks @
243identifier fops_rw.openfunc;
244@@
245 openfunc(...) {
246 <...
247- nonseekable_open
248+ nonseekable_open /* read & write (was deadlock) */
249 ...>
250 }
251
252
253@ explain_rw_nodeadlock depends on explain && !reader_blocks @
254identifier fops_rw.openfunc;
255@@
256 openfunc(...) {
257 <...
258- nonseekable_open
259+ nonseekable_open /* read & write (no direct deadlock) */
260 ...>
261 }
262
263@ patch_rw depends on patch @
264identifier fops_rw.openfunc;
265@@
266 openfunc(...) {
267 <...
268- nonseekable_open
269+ stream_open
270 ...>
271 }
272
273
274// read, but not write
275@ fops_r depends on maybe_stream && !has_write @
276identifier fops0.fops, openfunc;
277identifier stream_reader.readstream;
278@@
279 struct file_operations fops = {
280 .open = openfunc,
281 .read = readstream,
282 };
283
284@ report_r depends on report @
285identifier fops_r.openfunc;
286position p1;
287@@
288 openfunc(...) {
289 <...
290 nonseekable_open@p1
291 ...>
292 }
293
294@ script:python depends on report @
295fops << fops0.fops;
296p << report_r.p1;
297@@
298coccilib.report.print_report(p[0],
299 "WARNING: %s: .read() has stream semantic; safe to change nonseekable_open -> stream_open." % (fops,))
300
301@ explain_r depends on explain @
302identifier fops_r.openfunc;
303@@
304 openfunc(...) {
305 <...
306- nonseekable_open
307+ nonseekable_open /* read only */
308 ...>
309 }
310
311@ patch_r depends on patch @
312identifier fops_r.openfunc;
313@@
314 openfunc(...) {
315 <...
316- nonseekable_open
317+ stream_open
318 ...>
319 }
320
321
322// write, but not read
323@ fops_w depends on maybe_stream && !has_read @
324identifier fops0.fops, openfunc;
325identifier stream_writer.writestream;
326@@
327 struct file_operations fops = {
328 .open = openfunc,
329 .write = writestream,
330 };
331
332@ report_w depends on report @
333identifier fops_w.openfunc;
334position p1;
335@@
336 openfunc(...) {
337 <...
338 nonseekable_open@p1
339 ...>
340 }
341
342@ script:python depends on report @
343fops << fops0.fops;
344p << report_w.p1;
345@@
346coccilib.report.print_report(p[0],
347 "WARNING: %s: .write() has stream semantic; safe to change nonseekable_open -> stream_open." % (fops,))
348
349@ explain_w depends on explain @
350identifier fops_w.openfunc;
351@@
352 openfunc(...) {
353 <...
354- nonseekable_open
355+ nonseekable_open /* write only */
356 ...>
357 }
358
359@ patch_w depends on patch @
360identifier fops_w.openfunc;
361@@
362 openfunc(...) {
363 <...
364- nonseekable_open
365+ stream_open
366 ...>
367 }
368
369
370// no read, no write - don't change anything
diff --git a/scripts/coccinelle/api/vma_pages.cocci b/scripts/coccinelle/api/vma_pages.cocci
new file mode 100644
index 000000000..10511b9bf
--- /dev/null
+++ b/scripts/coccinelle/api/vma_pages.cocci
@@ -0,0 +1,61 @@
1// SPDX-License-Identifier: GPL-2.0
2///
3/// Use vma_pages function on vma object instead of explicit computation.
4///
5// Confidence: High
6// Keywords: vma_pages vma
7// Comment: Based on resource_size.cocci
8
9virtual context
10virtual patch
11virtual org
12virtual report
13
14//----------------------------------------------------------
15// For context mode
16//----------------------------------------------------------
17
18@r_context depends on context && !patch && !org && !report@
19struct vm_area_struct *vma;
20@@
21
22* (vma->vm_end - vma->vm_start) >> PAGE_SHIFT
23
24//----------------------------------------------------------
25// For patch mode
26//----------------------------------------------------------
27
28@r_patch depends on !context && patch && !org && !report@
29struct vm_area_struct *vma;
30@@
31
32- ((vma->vm_end - vma->vm_start) >> PAGE_SHIFT)
33+ vma_pages(vma)
34
35//----------------------------------------------------------
36// For org mode
37//----------------------------------------------------------
38
39@r_org depends on !context && !patch && (org || report)@
40struct vm_area_struct *vma;
41position p;
42@@
43
44 (vma->vm_end@p - vma->vm_start) >> PAGE_SHIFT
45
46@script:python depends on report@
47p << r_org.p;
48x << r_org.vma;
49@@
50
51msg="WARNING: Consider using vma_pages helper on %s" % (x)
52coccilib.report.print_report(p[0], msg)
53
54@script:python depends on org@
55p << r_org.p;
56x << r_org.vma;
57@@
58
59msg="WARNING: Consider using vma_pages helper on %s" % (x)
60msg_safe=msg.replace("[","@(").replace("]",")")
61coccilib.org.print_todo(p[0], msg_safe)