xref: /OK3568_Linux_fs/kernel/scripts/coccinelle/api/kfree_sensitive.cocci (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun// SPDX-License-Identifier: GPL-2.0-only
2*4882a593Smuzhiyun///
3*4882a593Smuzhiyun/// Use kfree_sensitive, kvfree_sensitive rather than memset or
4*4882a593Smuzhiyun/// memzero_explicit followed by kfree.
5*4882a593Smuzhiyun///
6*4882a593Smuzhiyun// Confidence: High
7*4882a593Smuzhiyun// Copyright: (C) 2020 Denis Efremov ISPRAS
8*4882a593Smuzhiyun// Options: --no-includes --include-headers
9*4882a593Smuzhiyun//
10*4882a593Smuzhiyun// Keywords: kfree_sensitive, kvfree_sensitive
11*4882a593Smuzhiyun//
12*4882a593Smuzhiyun
13*4882a593Smuzhiyunvirtual context
14*4882a593Smuzhiyunvirtual patch
15*4882a593Smuzhiyunvirtual org
16*4882a593Smuzhiyunvirtual report
17*4882a593Smuzhiyun
18*4882a593Smuzhiyun@initialize:python@
19*4882a593Smuzhiyun@@
20*4882a593Smuzhiyun# kmalloc_oob_in_memset uses memset to explicitly trigger out-of-bounds access
21*4882a593Smuzhiyunfilter = frozenset(['kmalloc_oob_in_memset',
22*4882a593Smuzhiyun		    'kfree_sensitive', 'kvfree_sensitive'])
23*4882a593Smuzhiyun
24*4882a593Smuzhiyundef relevant(p):
25*4882a593Smuzhiyun    return not (filter & {el.current_element for el in p})
26*4882a593Smuzhiyun
27*4882a593Smuzhiyun@cond@
28*4882a593Smuzhiyunposition ok;
29*4882a593Smuzhiyun@@
30*4882a593Smuzhiyun
31*4882a593Smuzhiyunif (...)
32*4882a593Smuzhiyun  \(memset@ok\|memzero_explicit@ok\)(...);
33*4882a593Smuzhiyun
34*4882a593Smuzhiyun@r depends on !patch forall@
35*4882a593Smuzhiyunexpression E;
36*4882a593Smuzhiyunposition p : script:python() { relevant(p) };
37*4882a593Smuzhiyunposition m != cond.ok;
38*4882a593Smuzhiyuntype T;
39*4882a593Smuzhiyun@@
40*4882a593Smuzhiyun
41*4882a593Smuzhiyun(
42*4882a593Smuzhiyun* memset@m((T)E, 0, ...);
43*4882a593Smuzhiyun|
44*4882a593Smuzhiyun* memzero_explicit@m((T)E, ...);
45*4882a593Smuzhiyun)
46*4882a593Smuzhiyun  ... when != E
47*4882a593Smuzhiyun      when strict
48*4882a593Smuzhiyun* \(kfree\|vfree\|kvfree\)(E)@p;
49*4882a593Smuzhiyun
50*4882a593Smuzhiyun@rp_memzero depends on patch@
51*4882a593Smuzhiyunexpression E, size;
52*4882a593Smuzhiyunposition p : script:python() { relevant(p) };
53*4882a593Smuzhiyunposition m != cond.ok;
54*4882a593Smuzhiyuntype T;
55*4882a593Smuzhiyun@@
56*4882a593Smuzhiyun
57*4882a593Smuzhiyun- memzero_explicit@m((T)E, size);
58*4882a593Smuzhiyun  ... when != E
59*4882a593Smuzhiyun      when strict
60*4882a593Smuzhiyun(
61*4882a593Smuzhiyun- kfree(E)@p;
62*4882a593Smuzhiyun+ kfree_sensitive(E);
63*4882a593Smuzhiyun|
64*4882a593Smuzhiyun- \(vfree\|kvfree\)(E)@p;
65*4882a593Smuzhiyun+ kvfree_sensitive(E, size);
66*4882a593Smuzhiyun)
67*4882a593Smuzhiyun
68*4882a593Smuzhiyun@rp_memset depends on patch@
69*4882a593Smuzhiyunexpression E, size;
70*4882a593Smuzhiyunposition p : script:python() { relevant(p) };
71*4882a593Smuzhiyunposition m != cond.ok;
72*4882a593Smuzhiyuntype T;
73*4882a593Smuzhiyun@@
74*4882a593Smuzhiyun
75*4882a593Smuzhiyun- memset@m((T)E, 0, size);
76*4882a593Smuzhiyun  ... when != E
77*4882a593Smuzhiyun      when strict
78*4882a593Smuzhiyun(
79*4882a593Smuzhiyun- kfree(E)@p;
80*4882a593Smuzhiyun+ kfree_sensitive(E);
81*4882a593Smuzhiyun|
82*4882a593Smuzhiyun- \(vfree\|kvfree\)(E)@p;
83*4882a593Smuzhiyun+ kvfree_sensitive(E, size);
84*4882a593Smuzhiyun)
85*4882a593Smuzhiyun
86*4882a593Smuzhiyun@script:python depends on report@
87*4882a593Smuzhiyunp << r.p;
88*4882a593Smuzhiyunm << r.m;
89*4882a593Smuzhiyun@@
90*4882a593Smuzhiyun
91*4882a593Smuzhiyunmsg = "WARNING opportunity for kfree_sensitive/kvfree_sensitive (memset at line %s)"
92*4882a593Smuzhiyuncoccilib.report.print_report(p[0], msg % (m[0].line))
93*4882a593Smuzhiyun
94*4882a593Smuzhiyun@script:python depends on org@
95*4882a593Smuzhiyunp << r.p;
96*4882a593Smuzhiyunm << r.m;
97*4882a593Smuzhiyun@@
98*4882a593Smuzhiyun
99*4882a593Smuzhiyunmsg = "WARNING opportunity for kfree_sensitive/kvfree_sensitive (memset at line %s)"
100*4882a593Smuzhiyuncoccilib.org.print_todo(p[0], msg % (m[0].line))
101