Skip to content

Commit f66179c

Browse files
committed
Merge branch 'for-5.10' of git://git.kernel.org/pub/scm/linux/kernel/git/jlawall/linux
Pull coccinelle updates from Julia Lawall. * 'for-5.10' of git://git.kernel.org/pub/scm/linux/kernel/git/jlawall/linux: coccinelle: api: add kfree_mismatch script coccinelle: iterators: Add for_each_child.cocci script scripts: coccicheck: Change default condition for parallelism scripts: coccicheck: Add quotes to improve portability coccinelle: api: kfree_sensitive: print memset position coccinelle: misc: add flexible_array.cocci script coccinelle: api: add kvmalloc script scripts: coccicheck: Change default value for parallelism coccinelle: misc: add excluded_middle.cocci script scripts: coccicheck: Improve error feedback when coccicheck fails coccinelle: api: update kzfree script to kfree_sensitive coccinelle: misc: add uninitialized_var.cocci script coccinelle: ifnullfree: add vfree(), kvfree*() functions coccinelle: api: add kobj_to_dev.cocci script coccinelle: add patch rule for dma_alloc_coherent scripts: coccicheck: Add chain mode to list of modes
2 parents 1912b04 + edc05fe commit f66179c

File tree

11 files changed

+1118
-26
lines changed

11 files changed

+1118
-26
lines changed

scripts/coccicheck

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,13 @@ else
7575
OPTIONS="--dir $KBUILD_EXTMOD $COCCIINCLUDE"
7676
fi
7777

78+
# Use only one thread per core by default if hyperthreading is enabled
79+
THREADS_PER_CORE=$(lscpu | grep "Thread(s) per core: " | tr -cd "[:digit:]")
7880
if [ -z "$J" ]; then
7981
NPROC=$(getconf _NPROCESSORS_ONLN)
82+
if [ $THREADS_PER_CORE -gt 1 -a $NPROC -gt 4 ] ; then
83+
NPROC=$((NPROC/2))
84+
fi
8085
else
8186
NPROC="$J"
8287
fi
@@ -99,7 +104,7 @@ fi
99104
if [ "$MODE" = "" ] ; then
100105
if [ "$ONLINE" = "0" ] ; then
101106
echo 'You have not explicitly specified the mode to use. Using default "report" mode.'
102-
echo 'Available modes are the following: patch, report, context, org'
107+
echo 'Available modes are the following: patch, report, context, org, chain'
103108
echo 'You can specify the mode with "make coccicheck MODE=<mode>"'
104109
echo 'Note however that some modes are not implemented by some semantic patches.'
105110
fi
@@ -126,8 +131,14 @@ run_cmd_parmap() {
126131
if [ $VERBOSE -ne 0 ] ; then
127132
echo "Running ($NPROC in parallel): $@"
128133
fi
129-
echo $@ >>$DEBUG_FILE
130-
$@ 2>>$DEBUG_FILE
134+
if [ "$DEBUG_FILE" != "/dev/null" -a "$DEBUG_FILE" != "" ]; then
135+
echo $@>>$DEBUG_FILE
136+
$@ 2>>$DEBUG_FILE
137+
else
138+
echo $@
139+
$@ 2>&1
140+
fi
141+
131142
err=$?
132143
if [[ $err -ne 0 ]]; then
133144
echo "coccicheck failed"

scripts/coccinelle/api/alloc/zalloc-simple.cocci

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,16 @@ statement S;
127127
if ((x==NULL) || ...) S
128128
- memset((T2)x,0,E1);
129129

130+
@depends on patch@
131+
type T, T2;
132+
expression x;
133+
expression E1,E2,E3,E4;
134+
statement S;
135+
@@
136+
x = (T)dma_alloc_coherent(E1, E2, E3, E4);
137+
if ((x==NULL) || ...) S
138+
- memset((T2)x, 0, E2);
139+
130140
//----------------------------------------------------------
131141
// For org mode
132142
//----------------------------------------------------------
@@ -199,9 +209,9 @@ statement S;
199209
position p;
200210
@@
201211

202-
x = (T)dma_alloc_coherent@p(E2,E1,E3,E4);
212+
x = (T)dma_alloc_coherent@p(E1,E2,E3,E4);
203213
if ((x==NULL) || ...) S
204-
memset((T2)x,0,E1);
214+
memset((T2)x,0,E2);
205215

206216
@script:python depends on org@
207217
p << r2.p;
@@ -217,7 +227,7 @@ p << r2.p;
217227
x << r2.x;
218228
@@
219229
220-
msg="WARNING: dma_alloc_coherent use in %s already zeroes out memory, so memset is not needed" % (x)
230+
msg="WARNING: dma_alloc_coherent used in %s already zeroes out memory, so memset is not needed" % (x)
221231
coccilib.report.print_report(p[0], msg)
222232
223233
//-----------------------------------------------------------------
Lines changed: 228 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
12+
virtual patch
13+
virtual report
14+
virtual org
15+
virtual context
16+
17+
@alloc@
18+
expression E, E1;
19+
position 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@
53+
expression E;
54+
position 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@
63+
expression E;
64+
position a != alloc.kok;
65+
position 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@
77+
expression E;
78+
position a != alloc.kok;
79+
position 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@
92+
expression E;
93+
position a != alloc.vok;
94+
position 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@
105+
expression E;
106+
position a != alloc.vok;
107+
position 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@
119+
expression E;
120+
position 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@
130+
expression 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@
141+
expression alloc.E;
142+
position 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@
150+
expression alloc.E;
151+
position 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@
165+
a << vfree.a;
166+
f << vfree.f;
167+
@@
168+
169+
msg = "WARNING kmalloc is used to allocate this memory at line %s" % (a[0].line)
170+
coccilib.report.print_report(f[0], msg)
171+
172+
@script: python depends on org@
173+
a << vfree.a;
174+
f << vfree.f;
175+
@@
176+
177+
msg = "WARNING kmalloc is used to allocate this memory at line %s" % (a[0].line)
178+
coccilib.org.print_todo(f[0], msg)
179+
180+
@script: python depends on report@
181+
a << kfree.a;
182+
f << kfree.f;
183+
@@
184+
185+
msg = "WARNING vmalloc is used to allocate this memory at line %s" % (a[0].line)
186+
coccilib.report.print_report(f[0], msg)
187+
188+
@script: python depends on org@
189+
a << kfree.a;
190+
f << kfree.f;
191+
@@
192+
193+
msg = "WARNING vmalloc is used to allocate this memory at line %s" % (a[0].line)
194+
coccilib.org.print_todo(f[0], msg)
195+
196+
@script: python depends on report@
197+
a << kvfree.a;
198+
f << kvfree.f;
199+
@@
200+
201+
msg = "WARNING kvmalloc is used to allocate this memory at line %s" % (a[0].line)
202+
coccilib.report.print_report(f[0], msg)
203+
204+
@script: python depends on org@
205+
a << kvfree.a;
206+
f << kvfree.f;
207+
@@
208+
209+
msg = "WARNING kvmalloc is used to allocate this memory at line %s" % (a[0].line)
210+
coccilib.org.print_todo(f[0], msg)
211+
212+
@script: python depends on report@
213+
ka << alloc.kok;
214+
va << alloc.vok;
215+
f << kvfree_switch.f;
216+
@@
217+
218+
msg = "WARNING kmalloc (line %s) && vmalloc (line %s) are used to allocate this memory" % (ka[0].line, va[0].line)
219+
coccilib.report.print_report(f[0], msg)
220+
221+
@script: python depends on org@
222+
ka << alloc.kok;
223+
va << alloc.vok;
224+
f << kvfree_switch.f;
225+
@@
226+
227+
msg = "WARNING kmalloc (line %s) && vmalloc (line %s) are used to allocate this memory" % (ka[0].line, va[0].line)
228+
coccilib.org.print_todo(f[0], msg)

scripts/coccinelle/api/kzfree.cocci renamed to scripts/coccinelle/api/kfree_sensitive.cocci

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
// SPDX-License-Identifier: GPL-2.0-only
22
///
3-
/// Use kzfree, kvfree_sensitive rather than memset or
4-
/// memzero_explicit followed by kfree
3+
/// Use kfree_sensitive, kvfree_sensitive rather than memset or
4+
/// memzero_explicit followed by kfree.
55
///
66
// Confidence: High
77
// Copyright: (C) 2020 Denis Efremov ISPRAS
88
// Options: --no-includes --include-headers
99
//
10-
// Keywords: kzfree, kvfree_sensitive
10+
// Keywords: kfree_sensitive, kvfree_sensitive
1111
//
1212

1313
virtual context
@@ -18,7 +18,8 @@ virtual report
1818
@initialize:python@
1919
@@
2020
# kmalloc_oob_in_memset uses memset to explicitly trigger out-of-bounds access
21-
filter = frozenset(['kmalloc_oob_in_memset', 'kzfree', 'kvfree_sensitive'])
21+
filter = frozenset(['kmalloc_oob_in_memset',
22+
'kfree_sensitive', 'kvfree_sensitive'])
2223
2324
def relevant(p):
2425
return not (filter & {el.current_element for el in p})
@@ -56,17 +57,13 @@ type T;
5657
- memzero_explicit@m((T)E, size);
5758
... when != E
5859
when strict
59-
// TODO: uncomment when kfree_sensitive will be merged.
60-
// Only this case is commented out because developers
61-
// may not like patches like this since kzfree uses memset
62-
// internally (not memzero_explicit).
63-
//(
64-
//- kfree(E)@p;
65-
//+ kfree_sensitive(E);
66-
//|
60+
(
61+
- kfree(E)@p;
62+
+ kfree_sensitive(E);
63+
|
6764
- \(vfree\|kvfree\)(E)@p;
6865
+ kvfree_sensitive(E, size);
69-
//)
66+
)
7067

7168
@rp_memset depends on patch@
7269
expression E, size;
@@ -80,22 +77,24 @@ type T;
8077
when strict
8178
(
8279
- kfree(E)@p;
83-
+ kzfree(E);
80+
+ kfree_sensitive(E);
8481
|
8582
- \(vfree\|kvfree\)(E)@p;
8683
+ kvfree_sensitive(E, size);
8784
)
8885

8986
@script:python depends on report@
9087
p << r.p;
88+
m << r.m;
9189
@@
9290
93-
coccilib.report.print_report(p[0],
94-
"WARNING: opportunity for kzfree/kvfree_sensitive")
91+
msg = "WARNING opportunity for kfree_sensitive/kvfree_sensitive (memset at line %s)"
92+
coccilib.report.print_report(p[0], msg % (m[0].line))
9593
9694
@script:python depends on org@
9795
p << r.p;
96+
m << r.m;
9897
@@
9998
100-
coccilib.org.print_todo(p[0],
101-
"WARNING: opportunity for kzfree/kvfree_sensitive")
99+
msg = "WARNING opportunity for kfree_sensitive/kvfree_sensitive (memset at line %s)"
100+
coccilib.org.print_todo(p[0], msg % (m[0].line))

0 commit comments

Comments
 (0)