Commit f66179ca authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'for-5.10' of git://git.kernel.org/pub/scm/linux/kernel/git/jlawall/linux

Pull coccinelle updates from Julia Lawall.

* 'for-5.10' of git://git.kernel.org/pub/scm/linux/kernel/git/jlawall/linux:
  coccinelle: api: add kfree_mismatch script
  coccinelle: iterators: Add for_each_child.cocci script
  scripts: coccicheck: Change default condition for parallelism
  scripts: coccicheck: Add quotes to improve portability
  coccinelle: api: kfree_sensitive: print memset position
  coccinelle: misc: add flexible_array.cocci script
  coccinelle: api: add kvmalloc script
  scripts: coccicheck: Change default value for parallelism
  coccinelle: misc: add excluded_middle.cocci script
  scripts: coccicheck: Improve error feedback when coccicheck fails
  coccinelle: api: update kzfree script to kfree_sensitive
  coccinelle: misc: add uninitialized_var.cocci script
  coccinelle: ifnullfree: add vfree(), kvfree*() functions
  coccinelle: api: add kobj_to_dev.cocci script
  coccinelle: add patch rule for dma_alloc_coherent
  scripts: coccicheck: Add chain mode to list of modes
parents 1912b04e edc05fe5
...@@ -75,8 +75,13 @@ else ...@@ -75,8 +75,13 @@ else
OPTIONS="--dir $KBUILD_EXTMOD $COCCIINCLUDE" OPTIONS="--dir $KBUILD_EXTMOD $COCCIINCLUDE"
fi fi
# Use only one thread per core by default if hyperthreading is enabled
THREADS_PER_CORE=$(lscpu | grep "Thread(s) per core: " | tr -cd "[:digit:]")
if [ -z "$J" ]; then if [ -z "$J" ]; then
NPROC=$(getconf _NPROCESSORS_ONLN) NPROC=$(getconf _NPROCESSORS_ONLN)
if [ $THREADS_PER_CORE -gt 1 -a $NPROC -gt 4 ] ; then
NPROC=$((NPROC/2))
fi
else else
NPROC="$J" NPROC="$J"
fi fi
...@@ -99,7 +104,7 @@ fi ...@@ -99,7 +104,7 @@ fi
if [ "$MODE" = "" ] ; then if [ "$MODE" = "" ] ; then
if [ "$ONLINE" = "0" ] ; then if [ "$ONLINE" = "0" ] ; then
echo 'You have not explicitly specified the mode to use. Using default "report" mode.' echo 'You have not explicitly specified the mode to use. Using default "report" mode.'
echo 'Available modes are the following: patch, report, context, org' echo 'Available modes are the following: patch, report, context, org, chain'
echo 'You can specify the mode with "make coccicheck MODE=<mode>"' echo 'You can specify the mode with "make coccicheck MODE=<mode>"'
echo 'Note however that some modes are not implemented by some semantic patches.' echo 'Note however that some modes are not implemented by some semantic patches.'
fi fi
...@@ -126,8 +131,14 @@ run_cmd_parmap() { ...@@ -126,8 +131,14 @@ run_cmd_parmap() {
if [ $VERBOSE -ne 0 ] ; then if [ $VERBOSE -ne 0 ] ; then
echo "Running ($NPROC in parallel): $@" echo "Running ($NPROC in parallel): $@"
fi fi
echo $@ >>$DEBUG_FILE if [ "$DEBUG_FILE" != "/dev/null" -a "$DEBUG_FILE" != "" ]; then
$@ 2>>$DEBUG_FILE echo $@>>$DEBUG_FILE
$@ 2>>$DEBUG_FILE
else
echo $@
$@ 2>&1
fi
err=$? err=$?
if [[ $err -ne 0 ]]; then if [[ $err -ne 0 ]]; then
echo "coccicheck failed" echo "coccicheck failed"
......
...@@ -127,6 +127,16 @@ statement S; ...@@ -127,6 +127,16 @@ statement S;
if ((x==NULL) || ...) S if ((x==NULL) || ...) S
- memset((T2)x,0,E1); - memset((T2)x,0,E1);
@depends on patch@
type T, T2;
expression x;
expression E1,E2,E3,E4;
statement S;
@@
x = (T)dma_alloc_coherent(E1, E2, E3, E4);
if ((x==NULL) || ...) S
- memset((T2)x, 0, E2);
//---------------------------------------------------------- //----------------------------------------------------------
// For org mode // For org mode
//---------------------------------------------------------- //----------------------------------------------------------
...@@ -199,9 +209,9 @@ statement S; ...@@ -199,9 +209,9 @@ statement S;
position p; position p;
@@ @@
x = (T)dma_alloc_coherent@p(E2,E1,E3,E4); x = (T)dma_alloc_coherent@p(E1,E2,E3,E4);
if ((x==NULL) || ...) S if ((x==NULL) || ...) S
memset((T2)x,0,E1); memset((T2)x,0,E2);
@script:python depends on org@ @script:python depends on org@
p << r2.p; p << r2.p;
...@@ -217,7 +227,7 @@ p << r2.p; ...@@ -217,7 +227,7 @@ p << r2.p;
x << r2.x; x << r2.x;
@@ @@
msg="WARNING: dma_alloc_coherent use in %s already zeroes out memory, so memset is not needed" % (x) msg="WARNING: dma_alloc_coherent used in %s already zeroes out memory, so memset is not needed" % (x)
coccilib.report.print_report(p[0], msg) coccilib.report.print_report(p[0], msg)
//----------------------------------------------------------------- //-----------------------------------------------------------------
......
// 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)
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/// ///
/// Use kzfree, kvfree_sensitive rather than memset or /// Use kfree_sensitive, kvfree_sensitive rather than memset or
/// memzero_explicit followed by kfree /// memzero_explicit followed by kfree.
/// ///
// Confidence: High // Confidence: High
// Copyright: (C) 2020 Denis Efremov ISPRAS // Copyright: (C) 2020 Denis Efremov ISPRAS
// Options: --no-includes --include-headers // Options: --no-includes --include-headers
// //
// Keywords: kzfree, kvfree_sensitive // Keywords: kfree_sensitive, kvfree_sensitive
// //
virtual context virtual context
...@@ -18,7 +18,8 @@ virtual report ...@@ -18,7 +18,8 @@ virtual report
@initialize:python@ @initialize:python@
@@ @@
# kmalloc_oob_in_memset uses memset to explicitly trigger out-of-bounds access # kmalloc_oob_in_memset uses memset to explicitly trigger out-of-bounds access
filter = frozenset(['kmalloc_oob_in_memset', 'kzfree', 'kvfree_sensitive']) filter = frozenset(['kmalloc_oob_in_memset',
'kfree_sensitive', 'kvfree_sensitive'])
def relevant(p): def relevant(p):
return not (filter & {el.current_element for el in p}) return not (filter & {el.current_element for el in p})
...@@ -56,17 +57,13 @@ type T; ...@@ -56,17 +57,13 @@ type T;
- memzero_explicit@m((T)E, size); - memzero_explicit@m((T)E, size);
... when != E ... when != E
when strict when strict
// TODO: uncomment when kfree_sensitive will be merged. (
// Only this case is commented out because developers - kfree(E)@p;
// may not like patches like this since kzfree uses memset + kfree_sensitive(E);
// internally (not memzero_explicit). |
//(
//- kfree(E)@p;
//+ kfree_sensitive(E);
//|
- \(vfree\|kvfree\)(E)@p; - \(vfree\|kvfree\)(E)@p;
+ kvfree_sensitive(E, size); + kvfree_sensitive(E, size);
//) )
@rp_memset depends on patch@ @rp_memset depends on patch@
expression E, size; expression E, size;
...@@ -80,7 +77,7 @@ type T; ...@@ -80,7 +77,7 @@ type T;
when strict when strict
( (
- kfree(E)@p; - kfree(E)@p;
+ kzfree(E); + kfree_sensitive(E);
| |
- \(vfree\|kvfree\)(E)@p; - \(vfree\|kvfree\)(E)@p;
+ kvfree_sensitive(E, size); + kvfree_sensitive(E, size);
...@@ -88,14 +85,16 @@ type T; ...@@ -88,14 +85,16 @@ type T;
@script:python depends on report@ @script:python depends on report@
p << r.p; p << r.p;
m << r.m;
@@ @@
coccilib.report.print_report(p[0], msg = "WARNING opportunity for kfree_sensitive/kvfree_sensitive (memset at line %s)"
"WARNING: opportunity for kzfree/kvfree_sensitive") coccilib.report.print_report(p[0], msg % (m[0].line))
@script:python depends on org@ @script:python depends on org@
p << r.p; p << r.p;
m << r.m;
@@ @@
coccilib.org.print_todo(p[0], msg = "WARNING opportunity for kfree_sensitive/kvfree_sensitive (memset at line %s)"
"WARNING: opportunity for kzfree/kvfree_sensitive") coccilib.org.print_todo(p[0], msg % (m[0].line))
// SPDX-License-Identifier: GPL-2.0-only
///
/// Use kobj_to_dev() instead of container_of()
///
// Confidence: High
// Copyright: (C) 2020 Denis Efremov ISPRAS
// Options: --no-includes --include-headers
//
// Keywords: kobj_to_dev, container_of
//
virtual context
virtual report
virtual org
virtual patch
@r depends on !patch@
expression ptr;
symbol kobj;
position p;
@@
* container_of(ptr, struct device, kobj)@p
@depends on patch@
expression ptr;
@@
- container_of(ptr, struct device, kobj)
+ kobj_to_dev(ptr)
@script:python depends on report@
p << r.p;
@@
coccilib.report.print_report(p[0], "WARNING opportunity for kobj_to_dev()")
@script:python depends on org@
p << r.p;
@@
coccilib.org.print_todo(p[0], "WARNING opportunity for kobj_to_dev()")
// 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")
...@@ -20,8 +20,14 @@ expression E; ...@@ -20,8 +20,14 @@ expression E;
- if (E != NULL) - if (E != NULL)
( (
kfree(E); kfree(E);
|
kvfree(E);
| |
kfree_sensitive(E); kfree_sensitive(E);
|
kvfree_sensitive(E, ...);
|
vfree(E);
| |
debugfs_remove(E); debugfs_remove(E);
| |
...@@ -42,9 +48,10 @@ position p; ...@@ -42,9 +48,10 @@ position p;
@@ @@
* if (E != NULL) * if (E != NULL)
* \(kfree@p\|kfree_sensitive@p\|debugfs_remove@p\|debugfs_remove_recursive@p\| * \(kfree@p\|kvfree@p\|kfree_sensitive@p\|kvfree_sensitive@p\|vfree@p\|
* debugfs_remove@p\|debugfs_remove_recursive@p\|
* usb_free_urb@p\|kmem_cache_destroy@p\|mempool_destroy@p\| * usb_free_urb@p\|kmem_cache_destroy@p\|mempool_destroy@p\|
* dma_pool_destroy@p\)(E); * dma_pool_destroy@p\)(E, ...);
@script:python depends on org@ @script:python depends on org@
p << r.p; p << r.p;
......
// SPDX-License-Identifier: GPL-2.0-only
// Adds missing of_node_put() before return/break/goto statement within a for_each iterator for child nodes.
//# False positives can be due to function calls within the for_each
//# loop that may encapsulate an of_node_put.
///
// Confidence: High
// Copyright: (C) 2020 Sumera Priyadarsini
// URL: http://coccinelle.lip6.fr
// Options: --no-includes --include-headers
virtual patch
virtual context
virtual org
virtual report
@r@
local idexpression n;
expression e1,e2;
iterator name for_each_node_by_name, for_each_node_by_type,
for_each_compatible_node, for_each_matching_node,
for_each_matching_node_and_match, for_each_child_of_node,
for_each_available_child_of_node, for_each_node_with_property;
iterator i;
statement S;
expression list [n1] es;
@@
(
(
for_each_node_by_name(n,e1) S
|
for_each_node_by_type(n,e1) S
|
for_each_compatible_node(n,e1,e2) S
|
for_each_matching_node(n,e1) S
|
for_each_matching_node_and_match(n,e1,e2) S
|
for_each_child_of_node(e1,n) S
|
for_each_available_child_of_node(e1,n) S
|
for_each_node_with_property(n,e1) S
)
&
i(es,n,...) S
)
@ruleone depends on patch && !context && !org && !report@
local idexpression r.n;
iterator r.i,i1;
expression e;
expression list [r.n1] es;
statement S;
@@
i(es,n,...) {
...
(
of_node_put(n);
|
e = n
|
return n;
|
i1(...,n,...) S
|
- return of_node_get(n);
+ return n;
|
+ of_node_put(n);
? return ...;
)
... when any
}
@ruletwo depends on patch && !context && !org && !report@
local idexpression r.n;
iterator r.i,i1,i2;
expression e,e1;
expression list [r.n1] es;
statement S,S2;
@@
i(es,n,...) {
...
(
of_node_put(n);
|
e = n
|
i1(...,n,...) S
|
+ of_node_put(n);
? break;
)
... when any
}
... when != n
when strict
when forall
(
n = e1;
|
?i2(...,n,...) S2
)
@rulethree depends on patch && !context && !org && !report exists@
local idexpression r.n;
iterator r.i,i1,i2;
expression e,e1;
identifier l;
expression list [r.n1] es;
statement S,S2;
@@
i(es,n,...) {
...
(
of_node_put(n);
|
e = n
|
i1(...,n,...) S
|
+ of_node_put(n);
? goto l;
)
... when any
}
... when exists
l: ... when != n
when strict
when forall
(
n = e1;
|
?i2(...,n,...) S2
)
// ----------------------------------------------------------------------------
@ruleone_context depends on !patch && (context || org || report) exists@
statement S;
expression e;
expression list[r.n1] es;
iterator r.i, i1;
local idexpression r.n;
position j0, j1;
@@
i@j0(es,n,...) {
...
(
of_node_put(n);
|
e = n
|
return n;
|
i1(...,n,...) S
|
return @j1 ...;
)
... when any
}
@ruleone_disj depends on !patch && (context || org || report)@
expression list[r.n1] es;
iterator r.i;
local idexpression r.n;
position ruleone_context.j0, ruleone_context.j1;
@@
* i@j0(es,n,...) {
...
*return @j1...;
... when any
}
@ruletwo_context depends on !patch && (context || org || report) exists@
statement S, S2;
expression e, e1;
expression list[r.n1] es;
iterator r.i, i1, i2;
local idexpression r.n;
position j0, j2;
@@
i@j0(es,n,...) {
...
(
of_node_put(n);
|
e = n
|
i1(...,n,...) S
|
break@j2;
)
... when any
}
... when != n
when strict
when forall
(
n = e1;
|
?i2(...,n,...) S2
)
@ruletwo_disj depends on !patch && (context || org || report)@
statement S2;
expression e1;
expression list[r.n1] es;
iterator r.i, i2;
local idexpression r.n;
position ruletwo_context.j0, ruletwo_context.j2;
@@
* i@j0(es,n,...) {
...
*break @j2;
... when any
}
... when != n
when strict
when forall
(
n = e1;
|
?i2(...,n,...) S2
)
@rulethree_context depends on !patch && (context || org || report) exists@
identifier l;
statement S,S2;
expression e, e1;
expression list[r.n1] es;
iterator r.i, i1, i2;
local idexpression r.n;
position j0, j3;
@@
i@j0(es,n,...) {
...
(
of_node_put(n);
|
e = n
|
i1(...,n,...) S
|
goto l@j3;
)
... when any
}
... when exists
l:
... when != n
when strict
when forall
(
n = e1;
|
?i2(...,n,...) S2
)
@rulethree_disj depends on !patch && (context || org || report) exists@
identifier l;
statement S2;
expression e1;
expression list[r.n1] es;
iterator r.i, i2;
local idexpression r.n;
position rulethree_context.j0, rulethree_context.j3;
@@
* i@j0(es,n,...) {
...
*goto l@j3;
... when any
}
... when exists
l:
... when != n
when strict
when forall
(
n = e1;
|
?i2(...,n,...) S2
)
// ----------------------------------------------------------------------------
@script:python ruleone_org depends on org@
i << r.i;
j0 << ruleone_context.j0;
j1 << ruleone_context. j1;
@@
msg = "WARNING: Function \"%s\" should have of_node_put() before return " % (i)
coccilib.org.print_safe_todo(j0[0], msg)
coccilib.org.print_link(j1[0], "")
@script:python ruletwo_org depends on org@
i << r.i;
j0 << ruletwo_context.j0;
j2 << ruletwo_context.j2;
@@
msg = "WARNING: Function \"%s\" should have of_node_put() before break " % (i)
coccilib.org.print_safe_todo(j0[0], msg)
coccilib.org.print_link(j2[0], "")
@script:python rulethree_org depends on org@
i << r.i;
j0 << rulethree_context.j0;
j3 << rulethree_context.j3;
@@
msg = "WARNING: Function \"%s\" should have of_node_put() before goto " % (i)
coccilib.org.print_safe_todo(j0[0], msg)
coccilib.org.print_link(j3[0], "")
// ----------------------------------------------------------------------------
@script:python ruleone_report depends on report@
i << r.i;
j0 << ruleone_context.j0;
j1 << ruleone_context.j1;
@@
msg = "WARNING: Function \"%s\" should have of_node_put() before return around line %s." % (i, j1[0].line)
coccilib.report.print_report(j0[0], msg)
@script:python ruletwo_report depends on report@
i << r.i;
j0 << ruletwo_context.j0;
j2 << ruletwo_context.j2;
@@
msg = "WARNING: Function \"%s\" should have of_node_put() before break around line %s." % (i,j2[0].line)
coccilib.report.print_report(j0[0], msg)
@script:python rulethree_report depends on report@
i << r.i;
j0 << rulethree_context.j0;
j3 << rulethree_context.j3;
@@
msg = "WARNING: Function \"%s\" should have of_node_put() before goto around lines %s." % (i,j3[0].line)
coccilib.report.print_report(j0[0], msg)
// SPDX-License-Identifier: GPL-2.0-only
///
/// Condition !A || A && B is equivalent to !A || B.
///
// Confidence: High
// Copyright: (C) 2020 Denis Efremov ISPRAS
// Options: --no-includes --include-headers
virtual patch
virtual context
virtual org
virtual report
@r depends on !patch@
expression A, B;
position p;
@@
* !A || (A &&@p B)
@depends on patch@
expression A, B;
@@
!A ||
- (A && B)
+ B
@script:python depends on report@
p << r.p;
@@
coccilib.report.print_report(p[0], "WARNING !A || A && B is equivalent to !A || B")
@script:python depends on org@
p << r.p;
@@
coccilib.org.print_todo(p[0], "WARNING !A || A && B is equivalent to !A || B")
// SPDX-License-Identifier: GPL-2.0-only
///
/// Zero-length and one-element arrays are deprecated, see
/// Documentation/process/deprecated.rst
/// Flexible-array members should be used instead.
///
//
// Confidence: High
// Copyright: (C) 2020 Denis Efremov ISPRAS.
// Comments:
// Options: --no-includes --include-headers
virtual context
virtual report
virtual org
virtual patch
@initialize:python@
@@
def relevant(positions):
for p in positions:
if "uapi" in p.file:
return False
return True
@r depends on !patch@
identifier name, array;
type T;
position p : script:python() { relevant(p) };
@@
(
struct name {
...
* T array@p[\(0\|1\)];
};
|
struct {
...
* T array@p[\(0\|1\)];
};
|
union name {
...
* T array@p[\(0\|1\)];
};
|
union {
...
* T array@p[\(0\|1\)];
};
)
@depends on patch@
identifier name, array;
type T;
position p : script:python() { relevant(p) };
@@
(
struct name {
...
T array@p[
- 0
];
};
|
struct {
...
T array@p[
- 0
];
};
)
@script: python depends on report@
p << r.p;
@@
msg = "WARNING use flexible-array member instead (https://www.kernel.org/doc/html/latest/process/deprecated.html#zero-length-and-one-element-arrays)"
coccilib.report.print_report(p[0], msg)
@script: python depends on org@
p << r.p;
@@
msg = "WARNING use flexible-array member instead (https://www.kernel.org/doc/html/latest/process/deprecated.html#zero-length-and-one-element-arrays)"
coccilib.org.print_todo(p[0], msg)
// SPDX-License-Identifier: GPL-2.0-only
///
/// Please, don't reintroduce uninitialized_var().
/// From Documentation/process/deprecated.rst:
/// For any compiler warnings about uninitialized variables, just add
/// an initializer. Using warning-silencing tricks is dangerous as it
/// papers over real bugs (or can in the future), and suppresses unrelated
/// compiler warnings (e.g. "unused variable"). If the compiler thinks it
/// is uninitialized, either simply initialize the variable or make compiler
/// changes. Keep in mind that in most cases, if an initialization is
/// obviously redundant, the compiler's dead-store elimination pass will make
/// sure there are no needless variable writes.
///
// Confidence: High
// Copyright: (C) 2020 Denis Efremov ISPRAS
// Options: --no-includes --include-headers
//
virtual context
virtual report
virtual org
@r@
identifier var;
type T;
position p;
@@
(
* T var =@p var;
|
* T var =@p *(&(var));
|
* var =@p var
|
* var =@p *(&(var))
)
@script:python depends on report@
p << r.p;
@@
coccilib.report.print_report(p[0],
"WARNING this kind of initialization is deprecated (https://www.kernel.org/doc/html/latest/process/deprecated.html#uninitialized-var)")
@script:python depends on org@
p << r.p;
@@
coccilib.org.print_todo(p[0],
"WARNING this kind of initialization is deprecated (https://www.kernel.org/doc/html/latest/process/deprecated.html#uninitialized-var)")
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment