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