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))
101