257 lines
6.1 KiB
Plaintext
257 lines
6.1 KiB
Plaintext
// SPDX-License-Identifier: GPL-2.0-only
|
|
///
|
|
/// Find if/else condition with kmalloc/vmalloc calls.
|
|
/// Suggest to use kvmalloc instead. Same for kvfree.
|
|
///
|
|
// Confidence: High
|
|
// Copyright: (C) 2020 Denis Efremov ISPRAS
|
|
// Options: --no-includes --include-headers
|
|
//
|
|
|
|
virtual patch
|
|
virtual report
|
|
virtual org
|
|
virtual context
|
|
|
|
@initialize:python@
|
|
@@
|
|
filter = frozenset(['kvfree'])
|
|
|
|
def relevant(p):
|
|
return not (filter & {el.current_element for el in p})
|
|
|
|
@kvmalloc depends on !patch@
|
|
expression E, E1, size;
|
|
identifier flags;
|
|
binary operator cmp = {<=, <, ==, >, >=};
|
|
identifier x;
|
|
type T;
|
|
position p;
|
|
@@
|
|
|
|
(
|
|
* if (size cmp E1 || ...)@p {
|
|
...
|
|
* E = \(kmalloc\|kzalloc\|kcalloc\|kmalloc_node\|kzalloc_node\|
|
|
* kmalloc_array\|kmalloc_array_node\|kcalloc_node\)
|
|
* (..., size, \(flags\|GFP_KERNEL\|\(GFP_KERNEL\|flags\)|__GFP_NOWARN\), ...)
|
|
...
|
|
} else {
|
|
...
|
|
* E = \(vmalloc\|vzalloc\|vmalloc_node\|vzalloc_node\)(..., size, ...)
|
|
...
|
|
}
|
|
|
|
|
* E = \(kmalloc\|kzalloc\|kcalloc\|kmalloc_node\|kzalloc_node\|
|
|
* kmalloc_array\|kmalloc_array_node\|kcalloc_node\)
|
|
* (..., size, \(flags\|GFP_KERNEL\|\(GFP_KERNEL\|flags\)|__GFP_NOWARN\), ...)
|
|
... when != E = E1
|
|
when != size = E1
|
|
when any
|
|
* if (E == NULL)@p {
|
|
...
|
|
* E = \(vmalloc\|vzalloc\|vmalloc_node\|vzalloc_node\)(..., size, ...)
|
|
...
|
|
}
|
|
|
|
|
* T x = \(kmalloc\|kzalloc\|kcalloc\|kmalloc_node\|kzalloc_node\|
|
|
* kmalloc_array\|kmalloc_array_node\|kcalloc_node\)
|
|
* (..., size, \(flags\|GFP_KERNEL\|\(GFP_KERNEL\|flags\)|__GFP_NOWARN\), ...);
|
|
... when != x = E1
|
|
when != size = E1
|
|
when any
|
|
* if (x == NULL)@p {
|
|
...
|
|
* x = \(vmalloc\|vzalloc\|vmalloc_node\|vzalloc_node\)(..., size, ...)
|
|
...
|
|
}
|
|
)
|
|
|
|
@kvfree depends on !patch@
|
|
expression E;
|
|
position p : script:python() { relevant(p) };
|
|
@@
|
|
|
|
* if (is_vmalloc_addr(E))@p {
|
|
...
|
|
* vfree(E)
|
|
...
|
|
} else {
|
|
... when != krealloc(E, ...)
|
|
when any
|
|
* \(kfree\|kzfree\)(E)
|
|
...
|
|
}
|
|
|
|
@depends on patch@
|
|
expression E, E1, size, node;
|
|
binary operator cmp = {<=, <, ==, >, >=};
|
|
identifier flags, x;
|
|
type T;
|
|
@@
|
|
|
|
(
|
|
- if (size cmp E1)
|
|
- E = kmalloc(size, flags);
|
|
- else
|
|
- E = vmalloc(size);
|
|
+ E = kvmalloc(size, flags);
|
|
|
|
|
- if (size cmp E1)
|
|
- E = kmalloc(size, \(GFP_KERNEL\|GFP_KERNEL|__GFP_NOWARN\));
|
|
- else
|
|
- E = vmalloc(size);
|
|
+ E = kvmalloc(size, GFP_KERNEL);
|
|
|
|
|
- E = kmalloc(size, flags | __GFP_NOWARN);
|
|
- if (E == NULL)
|
|
- E = vmalloc(size);
|
|
+ E = kvmalloc(size, flags);
|
|
|
|
|
- E = kmalloc(size, \(GFP_KERNEL\|GFP_KERNEL|__GFP_NOWARN\));
|
|
- if (E == NULL)
|
|
- E = vmalloc(size);
|
|
+ E = kvmalloc(size, GFP_KERNEL);
|
|
|
|
|
- T x = kmalloc(size, flags | __GFP_NOWARN);
|
|
- if (x == NULL)
|
|
- x = vmalloc(size);
|
|
+ T x = kvmalloc(size, flags);
|
|
|
|
|
- T x = kmalloc(size, \(GFP_KERNEL\|GFP_KERNEL|__GFP_NOWARN\));
|
|
- if (x == NULL)
|
|
- x = vmalloc(size);
|
|
+ T x = kvmalloc(size, GFP_KERNEL);
|
|
|
|
|
- if (size cmp E1)
|
|
- E = kzalloc(size, flags);
|
|
- else
|
|
- E = vzalloc(size);
|
|
+ E = kvzalloc(size, flags);
|
|
|
|
|
- if (size cmp E1)
|
|
- E = kzalloc(size, \(GFP_KERNEL\|GFP_KERNEL|__GFP_NOWARN\));
|
|
- else
|
|
- E = vzalloc(size);
|
|
+ E = kvzalloc(size, GFP_KERNEL);
|
|
|
|
|
- E = kzalloc(size, flags | __GFP_NOWARN);
|
|
- if (E == NULL)
|
|
- E = vzalloc(size);
|
|
+ E = kvzalloc(size, flags);
|
|
|
|
|
- E = kzalloc(size, \(GFP_KERNEL\|GFP_KERNEL|__GFP_NOWARN\));
|
|
- if (E == NULL)
|
|
- E = vzalloc(size);
|
|
+ E = kvzalloc(size, GFP_KERNEL);
|
|
|
|
|
- T x = kzalloc(size, flags | __GFP_NOWARN);
|
|
- if (x == NULL)
|
|
- x = vzalloc(size);
|
|
+ T x = kvzalloc(size, flags);
|
|
|
|
|
- T x = kzalloc(size, \(GFP_KERNEL\|GFP_KERNEL|__GFP_NOWARN\));
|
|
- if (x == NULL)
|
|
- x = vzalloc(size);
|
|
+ T x = kvzalloc(size, GFP_KERNEL);
|
|
|
|
|
- if (size cmp E1)
|
|
- E = kmalloc_node(size, flags, node);
|
|
- else
|
|
- E = vmalloc_node(size, node);
|
|
+ E = kvmalloc_node(size, flags, node);
|
|
|
|
|
- if (size cmp E1)
|
|
- E = kmalloc_node(size, \(GFP_KERNEL\|GFP_KERNEL|__GFP_NOWARN\), node);
|
|
- else
|
|
- E = vmalloc_node(size, node);
|
|
+ E = kvmalloc_node(size, GFP_KERNEL, node);
|
|
|
|
|
- E = kmalloc_node(size, flags | __GFP_NOWARN, node);
|
|
- if (E == NULL)
|
|
- E = vmalloc_node(size, node);
|
|
+ E = kvmalloc_node(size, flags, node);
|
|
|
|
|
- E = kmalloc_node(size, \(GFP_KERNEL\|GFP_KERNEL|__GFP_NOWARN\), node);
|
|
- if (E == NULL)
|
|
- E = vmalloc_node(size, node);
|
|
+ E = kvmalloc_node(size, GFP_KERNEL, node);
|
|
|
|
|
- T x = kmalloc_node(size, flags | __GFP_NOWARN, node);
|
|
- if (x == NULL)
|
|
- x = vmalloc_node(size, node);
|
|
+ T x = kvmalloc_node(size, flags, node);
|
|
|
|
|
- T x = kmalloc_node(size, \(GFP_KERNEL\|GFP_KERNEL|__GFP_NOWARN\), node);
|
|
- if (x == NULL)
|
|
- x = vmalloc_node(size, node);
|
|
+ T x = kvmalloc_node(size, GFP_KERNEL, node);
|
|
|
|
|
- if (size cmp E1)
|
|
- E = kvzalloc_node(size, flags, node);
|
|
- else
|
|
- E = vzalloc_node(size, node);
|
|
+ E = kvzalloc_node(size, flags, node);
|
|
|
|
|
- if (size cmp E1)
|
|
- E = kvzalloc_node(size, \(GFP_KERNEL\|GFP_KERNEL|__GFP_NOWARN\), node);
|
|
- else
|
|
- E = vzalloc_node(size, node);
|
|
+ E = kvzalloc_node(size, GFP_KERNEL, node);
|
|
|
|
|
- E = kvzalloc_node(size, flags | __GFP_NOWARN, node);
|
|
- if (E == NULL)
|
|
- E = vzalloc_node(size, node);
|
|
+ E = kvzalloc_node(size, flags, node);
|
|
|
|
|
- E = kvzalloc_node(size, \(GFP_KERNEL\|GFP_KERNEL|__GFP_NOWARN\), node);
|
|
- if (E == NULL)
|
|
- E = vzalloc_node(size, node);
|
|
+ E = kvzalloc_node(size, GFP_KERNEL, node);
|
|
|
|
|
- T x = kvzalloc_node(size, flags | __GFP_NOWARN, node);
|
|
- if (x == NULL)
|
|
- x = vzalloc_node(size, node);
|
|
+ T x = kvzalloc_node(size, flags, node);
|
|
|
|
|
- T x = kvzalloc_node(size, \(GFP_KERNEL\|GFP_KERNEL|__GFP_NOWARN\), node);
|
|
- if (x == NULL)
|
|
- x = vzalloc_node(size, node);
|
|
+ T x = kvzalloc_node(size, GFP_KERNEL, node);
|
|
)
|
|
|
|
@depends on patch@
|
|
expression E;
|
|
position p : script:python() { relevant(p) };
|
|
@@
|
|
|
|
- if (is_vmalloc_addr(E))@p
|
|
- vfree(E);
|
|
- else
|
|
- kfree(E);
|
|
+ kvfree(E);
|
|
|
|
@script: python depends on report@
|
|
p << kvmalloc.p;
|
|
@@
|
|
|
|
coccilib.report.print_report(p[0], "WARNING opportunity for kvmalloc")
|
|
|
|
@script: python depends on org@
|
|
p << kvmalloc.p;
|
|
@@
|
|
|
|
coccilib.org.print_todo(p[0], "WARNING opportunity for kvmalloc")
|
|
|
|
@script: python depends on report@
|
|
p << kvfree.p;
|
|
@@
|
|
|
|
coccilib.report.print_report(p[0], "WARNING opportunity for kvfree")
|
|
|
|
@script: python depends on org@
|
|
p << kvfree.p;
|
|
@@
|
|
|
|
coccilib.org.print_todo(p[0], "WARNING opportunity for kvfree")
|