Skip to content

Commit e3243e2

Browse files
committed
Merge branch 'for-5.9' of git://git.kernel.org/pub/scm/linux/kernel/git/jlawall/linux
Pull coccinelle updates from Julia Lawall: "New semantic patches and semantic patch improvements from Denis Efremov" * 'for-5.9' of git://git.kernel.org/pub/scm/linux/kernel/git/jlawall/linux: coccinelle: api: filter out memdup_user definitions coccinelle: api: extend memdup_user rule with vmemdup_user() coccinelle: api: extend memdup_user transformation with GFP_USER coccinelle: api: add kzfree script coccinelle: misc: add array_size_dup script to detect missed overflow checks coccinelle: api/kstrdup: fix coccinelle position coccinelle: api: add device_attr_show script
2 parents 1e21b5c + d05f94a commit e3243e2

File tree

5 files changed

+427
-4
lines changed

5 files changed

+427
-4
lines changed
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
// SPDX-License-Identifier: GPL-2.0-only
2+
///
3+
/// From Documentation/filesystems/sysfs.txt:
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+
14+
virtual report
15+
virtual org
16+
virtual context
17+
virtual patch
18+
19+
@r depends on !patch@
20+
identifier show, dev, attr, buf;
21+
position p;
22+
@@
23+
24+
ssize_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@
32+
identifier show, dev, attr, buf;
33+
@@
34+
35+
ssize_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@
46+
p << r.p;
47+
@@
48+
49+
coccilib.report.print_report(p[0], "WARNING: use scnprintf or sprintf")
50+
51+
@script: python depends on org@
52+
p << r.p;
53+
@@
54+
55+
coccilib.org.print_todo(p[0], "WARNING: use scnprintf or sprintf")

scripts/coccinelle/api/kstrdup.cocci

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ position p1,p2;
6666

6767
* x = strlen(from) + 1;
6868
... when != \( x = E1 \| from = E1 \)
69-
* to = \(kmalloc@p1\|kzalloc@p2\)(x,flag);
69+
* to = \(kmalloc@p1\|kzalloc@p1\)(x,flag);
7070
... when != \(x = E2 \| from = E2 \| to = E2 \)
7171
if (to==NULL || ...) S
7272
... when != \(x = E3 \| from = E3 \| to = E3 \)

scripts/coccinelle/api/kzfree.cocci

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
// SPDX-License-Identifier: GPL-2.0-only
2+
///
3+
/// Use kzfree, 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: kzfree, kvfree_sensitive
11+
//
12+
13+
virtual context
14+
virtual patch
15+
virtual org
16+
virtual report
17+
18+
@initialize:python@
19+
@@
20+
# kmalloc_oob_in_memset uses memset to explicitly trigger out-of-bounds access
21+
filter = frozenset(['kmalloc_oob_in_memset', 'kzfree', 'kvfree_sensitive'])
22+
23+
def relevant(p):
24+
return not (filter & {el.current_element for el in p})
25+
26+
@cond@
27+
position ok;
28+
@@
29+
30+
if (...)
31+
\(memset@ok\|memzero_explicit@ok\)(...);
32+
33+
@r depends on !patch forall@
34+
expression E;
35+
position p : script:python() { relevant(p) };
36+
position m != cond.ok;
37+
type T;
38+
@@
39+
40+
(
41+
* memset@m((T)E, 0, ...);
42+
|
43+
* memzero_explicit@m((T)E, ...);
44+
)
45+
... when != E
46+
when strict
47+
* \(kfree\|vfree\|kvfree\)(E)@p;
48+
49+
@rp_memzero depends on patch@
50+
expression E, size;
51+
position p : script:python() { relevant(p) };
52+
position m != cond.ok;
53+
type T;
54+
@@
55+
56+
- memzero_explicit@m((T)E, size);
57+
... when != E
58+
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+
//|
67+
- \(vfree\|kvfree\)(E)@p;
68+
+ kvfree_sensitive(E, size);
69+
//)
70+
71+
@rp_memset depends on patch@
72+
expression E, size;
73+
position p : script:python() { relevant(p) };
74+
position m != cond.ok;
75+
type T;
76+
@@
77+
78+
- memset@m((T)E, 0, size);
79+
... when != E
80+
when strict
81+
(
82+
- kfree(E)@p;
83+
+ kzfree(E);
84+
|
85+
- \(vfree\|kvfree\)(E)@p;
86+
+ kvfree_sensitive(E, size);
87+
)
88+
89+
@script:python depends on report@
90+
p << r.p;
91+
@@
92+
93+
coccilib.report.print_report(p[0],
94+
"WARNING: opportunity for kzfree/kvfree_sensitive")
95+
96+
@script:python depends on org@
97+
p << r.p;
98+
@@
99+
100+
coccilib.org.print_todo(p[0],
101+
"WARNING: opportunity for kzfree/kvfree_sensitive")

scripts/coccinelle/api/memdup_user.cocci

Lines changed: 61 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,22 @@ virtual context
1515
virtual org
1616
virtual report
1717

18+
@initialize:python@
19+
@@
20+
filter = frozenset(['memdup_user', 'vmemdup_user'])
21+
22+
def relevant(p):
23+
return not (filter & {el.current_element for el in p})
24+
1825
@depends on patch@
1926
expression from,to,size;
2027
identifier l1,l2;
28+
position p : script:python() { relevant(p) };
2129
@@
2230

23-
- to = \(kmalloc\|kzalloc\)(size,GFP_KERNEL);
31+
- to = \(kmalloc@p\|kzalloc@p\)
32+
- (size,\(GFP_KERNEL\|GFP_USER\|
33+
- \(GFP_KERNEL\|GFP_USER\)|__GFP_NOWARN\));
2434
+ to = memdup_user(from,size);
2535
if (
2636
- to==NULL
@@ -37,13 +47,49 @@ identifier l1,l2;
3747
- ...+>
3848
- }
3949

50+
@depends on patch@
51+
expression from,to,size;
52+
identifier l1,l2;
53+
position 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+
4073
@r depends on !patch@
4174
expression from,to,size;
42-
position p;
75+
position p : script:python() { relevant(p) };
4376
statement S1,S2;
4477
@@
4578

46-
* to = \(kmalloc@p\|kzalloc@p\)(size,GFP_KERNEL);
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@
87+
expression from,to,size;
88+
position p : script:python() { relevant(p) };
89+
statement S1,S2;
90+
@@
91+
92+
* to = \(kvmalloc@p\|kvzalloc@p\)(size,\(GFP_KERNEL\|GFP_USER\));
4793
if (to==NULL || ...) S1
4894
if (copy_from_user(to, from, size) != 0)
4995
S2
@@ -59,3 +105,15 @@ p << r.p;
59105
@@
60106
61107
coccilib.report.print_report(p[0], "WARNING opportunity for memdup_user")
108+
109+
@script:python depends on org@
110+
p << rv.p;
111+
@@
112+
113+
coccilib.org.print_todo(p[0], "WARNING opportunity for vmemdup_user")
114+
115+
@script:python depends on report@
116+
p << rv.p;
117+
@@
118+
119+
coccilib.report.print_report(p[0], "WARNING opportunity for vmemdup_user")

0 commit comments

Comments
 (0)