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