lkml.org 
[lkml]   [2020]   [Jul]   [30]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v3] coccinelle: api: add kvfree script
    Date
    Check that alloc and free types of functions match each other.

    Signed-off-by: Denis Efremov <efremov@linux.com>
    ---
    Changes in v2:
    - Lines are limited to 80 characters where possible
    - Confidence changed from High to Medium because of
    fs/btrfs/send.c:1119 false-positive
    - __vmalloc_area_node() explicitly excluded from analysis
    instead of !(file in "mm/vmalloc.c") condition
    Changes in v3:
    - prints style in org && report modes changed for python2

    scripts/coccinelle/api/kvfree.cocci | 227 ++++++++++++++++++++++++++++
    1 file changed, 227 insertions(+)
    create mode 100644 scripts/coccinelle/api/kvfree.cocci

    diff --git a/scripts/coccinelle/api/kvfree.cocci b/scripts/coccinelle/api/kvfree.cocci
    new file mode 100644
    index 000000000000..7c396daeacad
    --- /dev/null
    +++ b/scripts/coccinelle/api/kvfree.cocci
    @@ -0,0 +1,227 @@
    +// 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: Medium
    +// Copyright: (C) 2020 Denis Efremov ISPRAS
    +// Options: --no-includes --include-headers
    +//
    +
    +virtual patch
    +virtual report
    +virtual org
    +virtual context
    +
    +@initialize:python@
    +@@
    +# low-level memory api
    +filter = frozenset(['__vmalloc_area_node'])
    +
    +def relevant(p):
    + return not (filter & {el.current_element for el in p})
    +
    +@choice@
    +expression E, E1;
    +position kok, vok;
    +@@
    +
    +(
    + if (...) {
    + ...
    + E = \(kmalloc@kok\|kzalloc@kok\|krealloc@kok\|kcalloc@kok\|
    + kmalloc_node@kok\|kzalloc_node@kok\|kmalloc_array@kok\|
    + kmalloc_array_node@kok\|kcalloc_node@kok\)(...)
    + ...
    + } else {
    + ...
    + E = \(vmalloc@vok\|vzalloc@vok\|vmalloc_user@vok\|vmalloc_node@vok\|
    + vzalloc_node@vok\|vmalloc_exec@vok\|vmalloc_32@vok\|
    + vmalloc_32_user@vok\|__vmalloc@vok\|__vmalloc_node_range@vok\|
    + __vmalloc_node@vok\)(...)
    + ...
    + }
    +|
    + E = \(kmalloc\|kzalloc\|krealloc\|kcalloc\|kmalloc_node\|kzalloc_node\|
    + kmalloc_array\|kmalloc_array_node\|kcalloc_node\)(...)
    + ... when != E = E1
    + when any
    + if (\(!E\|E == NULL\)) {
    + ...
    + E = \(vmalloc@vok\|vzalloc@vok\|vmalloc_user@vok\|vmalloc_node@vok\|
    + vzalloc_node@vok\|vmalloc_exec@vok\|vmalloc_32@vok\|
    + vmalloc_32_user@vok\|__vmalloc@vok\|__vmalloc_node_range@vok\|
    + __vmalloc_node@vok\)(...)
    + ...
    + }
    +)
    +
    +@opportunity depends on !patch@
    +expression E, E1, size;
    +position p : script:python() { relevant(p) };
    +@@
    +
    +(
    +* if (\(size <= E1\|size < E1\|size = E1\|size > E1\) || ...)@p {
    + ...
    + E = \(kmalloc\|kzalloc\|krealloc\|kcalloc\|kmalloc_node\|kzalloc_node\|
    + kmalloc_array\|kmalloc_array_node\|kcalloc_node\)(..., size, ...)
    + ...
    + } else {
    + ...
    + E = \(vmalloc\|vzalloc\|vmalloc_user\|vmalloc_node\|vzalloc_node\|
    + vmalloc_exec\|vmalloc_32\|vmalloc_32_user\|__vmalloc\|
    + __vmalloc_node_range\|__vmalloc_node\)(..., size, ...)
    + ...
    + }
    +|
    + E = \(kmalloc\|kzalloc\|krealloc\|kcalloc\|kmalloc_node\|kzalloc_node\|
    + kmalloc_array\|kmalloc_array_node\|kcalloc_node\)(..., size, ...)
    + ... when != E = E1
    + when != size = E1
    + when any
    +* if (\(!E\|E == NULL\))@p {
    + ...
    + E = \(vmalloc\|vzalloc\|vmalloc_user\|vmalloc_node\|vzalloc_node\|
    + vmalloc_exec\|vmalloc_32\|vmalloc_32_user\|__vmalloc\|
    + __vmalloc_node_range\|__vmalloc_node\)(..., size, ...)
    + ...
    + }
    +)
    +
    +@vfree depends on !patch@
    +expression E;
    +position k != choice.kok;
    +position p;
    +@@
    +
    +* E = \(kmalloc@k\|kzalloc@k\|krealloc@k\|kcalloc@k\|kmalloc_node@k\|
    + kzalloc_node@k\|kmalloc_array@k\|kmalloc_array_node@k\|
    + kcalloc_node@k\)(...)
    + ... 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)@p
    +
    +@pvfree depends on patch exists@
    +expression E;
    +position k != choice.kok;
    +@@
    +
    + E = \(kmalloc@k\|kzalloc@k\|krealloc@k\|kcalloc@k\|kmalloc_node@k\|
    + kzalloc_node@k\|kmalloc_array@k\|kmalloc_array_node@k\|
    + kcalloc_node@k\)(...)
    + ... 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)
    ++ kfree(E)
    +
    +@kfree depends on !patch@
    +expression E;
    +position v != choice.vok;
    +position p;
    +@@
    +
    +* E = \(vmalloc@v\|vzalloc@v\|vmalloc_user@v\|vmalloc_node@v\|vzalloc_node@v\|
    + vmalloc_exec@v\|vmalloc_32@v\|vmalloc_32_user@v\|__vmalloc@v\|
    + __vmalloc_node_range@v\|__vmalloc_node@v\)(...)
    + ... when != !is_vmalloc_addr(E)
    + when any
    +* \(kfree\|kzfree\|kvfree\)(E)
    +
    +@pkfree depends on patch exists@
    +expression E;
    +position v != choice.vok;
    +@@
    +
    + E = \(vmalloc@v\|vzalloc@v\|vmalloc_user@v\|vmalloc_node@v\|vzalloc_node@v\|
    + vmalloc_exec@v\|vmalloc_32@v\|vmalloc_32_user@v\|__vmalloc@v\|
    + __vmalloc_node_range@v\|__vmalloc_node@v\)(...)
    + ... when != !is_vmalloc_addr(E)
    + when any
    +- \(kfree\|kvfree\)(E)
    ++ vfree(E)
    +
    +@kvfree depends on !patch@
    +expression E;
    +position p, k;
    +@@
    +
    +* E = \(kvmalloc\|kvzalloc\|kvcalloc\|kvzalloc_node\|kvmalloc_node\|
    + kvmalloc_array\)(...)@k
    + ... when != is_vmalloc_addr(E)
    + when any
    +* \(kfree\|kzfree\|vfree\|vfree_atomic\)(E)@p
    +
    +@pkvfree 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)
    +
    +@script: python depends on report@
    +k << vfree.k;
    +p << vfree.p;
    +@@
    +
    +msg = "WARNING: kmalloc is used to allocate this memory at line %s" % (k[0].line)
    +coccilib.report.print_report(p[0], msg)
    +
    +@script: python depends on org@
    +k << vfree.k;
    +p << vfree.p;
    +@@
    +
    +msg = "WARNING: kmalloc is used to allocate this memory at line %s" % (k[0].line)
    +coccilib.org.print_todo(p[0], msg)
    +
    +@script: python depends on report@
    +v << kfree.v;
    +p << kfree.p;
    +@@
    +
    +msg = "WARNING: vmalloc is used to allocate this memory at line %s" % (v[0].line)
    +coccilib.report.print_report(p[0], msg)
    +
    +@script: python depends on org@
    +v << kfree.v;
    +p << kfree.p;
    +@@
    +
    +msg = "WARNING: vmalloc is used to allocate this memory at line %s" % (v[0].line)
    +coccilib.org.print_todo(p[0],
    +
    +@script: python depends on report@
    +k << kvfree.k;
    +p << kvfree.p;
    +@@
    +
    +msg = "WARNING: kvmalloc is used to allocate this memory at line %s" % (k[0].line)
    +coccilib.report.print_report(p[0], msg)
    +
    +@script: python depends on org@
    +k << kvfree.k;
    +p << kvfree.p;
    +@@
    +
    +msg = "WARNING: kvmalloc is used to allocate this memory at line %s" % (k[0].line)
    +coccilib.org.print_todo(p[0], msg)
    +
    +@script: python depends on report@
    +p << opportunity.p;
    +@@
    +
    +coccilib.report.print_report(p[0], "WARNING: opportunity for kvmalloc")
    +
    +@script: python depends on org@
    +p << opportunity.p;
    +@@
    +
    +coccilib.org.print_todo(p[0], "WARNING: opportunity for kvmalloc")
    --
    2.26.2
    \
     
     \ /
      Last update: 2020-07-30 16:02    [W:3.588 / U:0.040 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site