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