|
@@ -0,0 +1,228 @@
|
|
|
+// SPDX-License-Identifier: GPL-2.0-only
|
|
|
+///
|
|
|
+/// Check that kvmalloc'ed memory is freed by kfree functions,
|
|
|
+/// vmalloc'ed by vfree functions and kvmalloc'ed by kvfree
|
|
|
+/// functions.
|
|
|
+///
|
|
|
+// Confidence: High
|
|
|
+// Copyright: (C) 2020 Denis Efremov ISPRAS
|
|
|
+// Options: --no-includes --include-headers
|
|
|
+//
|
|
|
+
|
|
|
+virtual patch
|
|
|
+virtual report
|
|
|
+virtual org
|
|
|
+virtual context
|
|
|
+
|
|
|
+@alloc@
|
|
|
+expression E, E1;
|
|
|
+position kok, vok;
|
|
|
+@@
|
|
|
+
|
|
|
+(
|
|
|
+ if (...) {
|
|
|
+ ...
|
|
|
+ E = \(kmalloc\|kzalloc\|krealloc\|kcalloc\|
|
|
|
+ kmalloc_node\|kzalloc_node\|kmalloc_array\|
|
|
|
+ kmalloc_array_node\|kcalloc_node\)(...)@kok
|
|
|
+ ...
|
|
|
+ } else {
|
|
|
+ ...
|
|
|
+ E = \(vmalloc\|vzalloc\|vmalloc_user\|vmalloc_node\|
|
|
|
+ vzalloc_node\|vmalloc_exec\|vmalloc_32\|
|
|
|
+ vmalloc_32_user\|__vmalloc\|__vmalloc_node_range\|
|
|
|
+ __vmalloc_node\)(...)@vok
|
|
|
+ ...
|
|
|
+ }
|
|
|
+|
|
|
|
+ E = \(kmalloc\|kzalloc\|krealloc\|kcalloc\|kmalloc_node\|kzalloc_node\|
|
|
|
+ kmalloc_array\|kmalloc_array_node\|kcalloc_node\)(...)@kok
|
|
|
+ ... when != E = E1
|
|
|
+ when any
|
|
|
+ if (E == NULL) {
|
|
|
+ ...
|
|
|
+ E = \(vmalloc\|vzalloc\|vmalloc_user\|vmalloc_node\|
|
|
|
+ vzalloc_node\|vmalloc_exec\|vmalloc_32\|
|
|
|
+ vmalloc_32_user\|__vmalloc\|__vmalloc_node_range\|
|
|
|
+ __vmalloc_node\)(...)@vok
|
|
|
+ ...
|
|
|
+ }
|
|
|
+)
|
|
|
+
|
|
|
+@free@
|
|
|
+expression E;
|
|
|
+position fok;
|
|
|
+@@
|
|
|
+
|
|
|
+ E = \(kvmalloc\|kvzalloc\|kvcalloc\|kvzalloc_node\|kvmalloc_node\|
|
|
|
+ kvmalloc_array\)(...)
|
|
|
+ ...
|
|
|
+ kvfree(E)@fok
|
|
|
+
|
|
|
+@vfree depends on !patch@
|
|
|
+expression E;
|
|
|
+position a != alloc.kok;
|
|
|
+position f != free.fok;
|
|
|
+@@
|
|
|
+
|
|
|
+* E = \(kmalloc\|kzalloc\|krealloc\|kcalloc\|kmalloc_node\|
|
|
|
+* kzalloc_node\|kmalloc_array\|kmalloc_array_node\|
|
|
|
+* kcalloc_node\)(...)@a
|
|
|
+ ... when != if (...) { ... E = \(vmalloc\|vzalloc\|vmalloc_user\|vmalloc_node\|vzalloc_node\|vmalloc_exec\|vmalloc_32\|vmalloc_32_user\|__vmalloc\|__vmalloc_node_range\|__vmalloc_node\)(...); ... }
|
|
|
+ when != is_vmalloc_addr(E)
|
|
|
+ when any
|
|
|
+* \(vfree\|vfree_atomic\|kvfree\)(E)@f
|
|
|
+
|
|
|
+@depends on patch exists@
|
|
|
+expression E;
|
|
|
+position a != alloc.kok;
|
|
|
+position f != free.fok;
|
|
|
+@@
|
|
|
+
|
|
|
+ E = \(kmalloc\|kzalloc\|krealloc\|kcalloc\|kmalloc_node\|
|
|
|
+ kzalloc_node\|kmalloc_array\|kmalloc_array_node\|
|
|
|
+ kcalloc_node\)(...)@a
|
|
|
+ ... when != if (...) { ... E = \(vmalloc\|vzalloc\|vmalloc_user\|vmalloc_node\|vzalloc_node\|vmalloc_exec\|vmalloc_32\|vmalloc_32_user\|__vmalloc\|__vmalloc_node_range\|__vmalloc_node\)(...); ... }
|
|
|
+ when != is_vmalloc_addr(E)
|
|
|
+ when any
|
|
|
+- \(vfree\|vfree_atomic\|kvfree\)(E)@f
|
|
|
++ kfree(E)
|
|
|
+
|
|
|
+@kfree depends on !patch@
|
|
|
+expression E;
|
|
|
+position a != alloc.vok;
|
|
|
+position f != free.fok;
|
|
|
+@@
|
|
|
+
|
|
|
+* E = \(vmalloc\|vzalloc\|vmalloc_user\|vmalloc_node\|vzalloc_node\|
|
|
|
+* vmalloc_exec\|vmalloc_32\|vmalloc_32_user\|__vmalloc\|
|
|
|
+* __vmalloc_node_range\|__vmalloc_node\)(...)@a
|
|
|
+ ... when != is_vmalloc_addr(E)
|
|
|
+ when any
|
|
|
+* \(kfree\|kfree_sensitive\|kvfree\)(E)@f
|
|
|
+
|
|
|
+@depends on patch exists@
|
|
|
+expression E;
|
|
|
+position a != alloc.vok;
|
|
|
+position f != free.fok;
|
|
|
+@@
|
|
|
+
|
|
|
+ E = \(vmalloc\|vzalloc\|vmalloc_user\|vmalloc_node\|vzalloc_node\|
|
|
|
+ vmalloc_exec\|vmalloc_32\|vmalloc_32_user\|__vmalloc\|
|
|
|
+ __vmalloc_node_range\|__vmalloc_node\)(...)@a
|
|
|
+ ... when != is_vmalloc_addr(E)
|
|
|
+ when any
|
|
|
+- \(kfree\|kvfree\)(E)@f
|
|
|
++ vfree(E)
|
|
|
+
|
|
|
+@kvfree depends on !patch@
|
|
|
+expression E;
|
|
|
+position a, f;
|
|
|
+@@
|
|
|
+
|
|
|
+* E = \(kvmalloc\|kvzalloc\|kvcalloc\|kvzalloc_node\|kvmalloc_node\|
|
|
|
+* kvmalloc_array\)(...)@a
|
|
|
+ ... when != is_vmalloc_addr(E)
|
|
|
+ when any
|
|
|
+* \(kfree\|kfree_sensitive\|vfree\|vfree_atomic\)(E)@f
|
|
|
+
|
|
|
+@depends on patch exists@
|
|
|
+expression E;
|
|
|
+@@
|
|
|
+
|
|
|
+ E = \(kvmalloc\|kvzalloc\|kvcalloc\|kvzalloc_node\|kvmalloc_node\|
|
|
|
+ kvmalloc_array\)(...)
|
|
|
+ ... when != is_vmalloc_addr(E)
|
|
|
+ when any
|
|
|
+- \(kfree\|vfree\)(E)
|
|
|
++ kvfree(E)
|
|
|
+
|
|
|
+@kvfree_switch depends on !patch@
|
|
|
+expression alloc.E;
|
|
|
+position f;
|
|
|
+@@
|
|
|
+
|
|
|
+ ... when != is_vmalloc_addr(E)
|
|
|
+ when any
|
|
|
+* \(kfree\|kfree_sensitive\|vfree\|vfree_atomic\)(E)@f
|
|
|
+
|
|
|
+@depends on patch exists@
|
|
|
+expression alloc.E;
|
|
|
+position f;
|
|
|
+@@
|
|
|
+
|
|
|
+ ... when != is_vmalloc_addr(E)
|
|
|
+ when any
|
|
|
+(
|
|
|
+- \(kfree\|vfree\)(E)@f
|
|
|
++ kvfree(E)
|
|
|
+|
|
|
|
+- kfree_sensitive(E)@f
|
|
|
++ kvfree_sensitive(E)
|
|
|
+)
|
|
|
+
|
|
|
+@script: python depends on report@
|
|
|
+a << vfree.a;
|
|
|
+f << vfree.f;
|
|
|
+@@
|
|
|
+
|
|
|
+msg = "WARNING kmalloc is used to allocate this memory at line %s" % (a[0].line)
|
|
|
+coccilib.report.print_report(f[0], msg)
|
|
|
+
|
|
|
+@script: python depends on org@
|
|
|
+a << vfree.a;
|
|
|
+f << vfree.f;
|
|
|
+@@
|
|
|
+
|
|
|
+msg = "WARNING kmalloc is used to allocate this memory at line %s" % (a[0].line)
|
|
|
+coccilib.org.print_todo(f[0], msg)
|
|
|
+
|
|
|
+@script: python depends on report@
|
|
|
+a << kfree.a;
|
|
|
+f << kfree.f;
|
|
|
+@@
|
|
|
+
|
|
|
+msg = "WARNING vmalloc is used to allocate this memory at line %s" % (a[0].line)
|
|
|
+coccilib.report.print_report(f[0], msg)
|
|
|
+
|
|
|
+@script: python depends on org@
|
|
|
+a << kfree.a;
|
|
|
+f << kfree.f;
|
|
|
+@@
|
|
|
+
|
|
|
+msg = "WARNING vmalloc is used to allocate this memory at line %s" % (a[0].line)
|
|
|
+coccilib.org.print_todo(f[0], msg)
|
|
|
+
|
|
|
+@script: python depends on report@
|
|
|
+a << kvfree.a;
|
|
|
+f << kvfree.f;
|
|
|
+@@
|
|
|
+
|
|
|
+msg = "WARNING kvmalloc is used to allocate this memory at line %s" % (a[0].line)
|
|
|
+coccilib.report.print_report(f[0], msg)
|
|
|
+
|
|
|
+@script: python depends on org@
|
|
|
+a << kvfree.a;
|
|
|
+f << kvfree.f;
|
|
|
+@@
|
|
|
+
|
|
|
+msg = "WARNING kvmalloc is used to allocate this memory at line %s" % (a[0].line)
|
|
|
+coccilib.org.print_todo(f[0], msg)
|
|
|
+
|
|
|
+@script: python depends on report@
|
|
|
+ka << alloc.kok;
|
|
|
+va << alloc.vok;
|
|
|
+f << kvfree_switch.f;
|
|
|
+@@
|
|
|
+
|
|
|
+msg = "WARNING kmalloc (line %s) && vmalloc (line %s) are used to allocate this memory" % (ka[0].line, va[0].line)
|
|
|
+coccilib.report.print_report(f[0], msg)
|
|
|
+
|
|
|
+@script: python depends on org@
|
|
|
+ka << alloc.kok;
|
|
|
+va << alloc.vok;
|
|
|
+f << kvfree_switch.f;
|
|
|
+@@
|
|
|
+
|
|
|
+msg = "WARNING kmalloc (line %s) && vmalloc (line %s) are used to allocate this memory" % (ka[0].line, va[0].line)
|
|
|
+coccilib.org.print_todo(f[0], msg)
|