From 4b2bd20c350a66d4f8a7c2da48b115fd4e06d15e Mon Sep 17 00:00:00 2001 From: Sumera Priyadarsini Date: Wed, 5 Aug 2020 14:27:40 +0530 Subject: scripts: coccicheck: Add chain mode to list of modes This patch adds chain mode to the list of available modes in coccicheck. Signed-off-by: Sumera Priyadarsini Signed-off-by: Julia Lawall --- scripts/coccicheck | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/coccicheck b/scripts/coccicheck index e04d328210ac..6e37cf36caae 100755 --- a/scripts/coccicheck +++ b/scripts/coccicheck @@ -99,7 +99,7 @@ fi if [ "$MODE" = "" ] ; then if [ "$ONLINE" = "0" ] ; then 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="' echo 'Note however that some modes are not implemented by some semantic patches.' fi -- cgit v1.2.3-70-g09d2 From 7a2624e6de03050c9f15af21c216818d5508b5e9 Mon Sep 17 00:00:00 2001 From: Alex Dewar Date: Fri, 21 Aug 2020 00:55:57 +0100 Subject: coccinelle: add patch rule for dma_alloc_coherent Commit dfd32cad146e ("dma-mapping: remove dma_zalloc_coherent()") removed the definition of dma_zalloc_coherent() and also removed the corresponding patch rule for replacing instances of dma_alloc_coherent + memset in zalloc-simple.cocci (though left the report rule). Add a new patch rule to remove unnecessary calls to memset after allocating with dma_alloc_coherent. While we're at it, fix a couple of typos. Fixes: dfd32cad146e ("dma-mapping: remove dma_zalloc_coherent()") Signed-off-by: Alex Dewar Signed-off-by: Julia Lawall --- scripts/coccinelle/api/alloc/zalloc-simple.cocci | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) (limited to 'scripts') diff --git a/scripts/coccinelle/api/alloc/zalloc-simple.cocci b/scripts/coccinelle/api/alloc/zalloc-simple.cocci index 26cda3f48f01..b3d0c3c230c1 100644 --- a/scripts/coccinelle/api/alloc/zalloc-simple.cocci +++ b/scripts/coccinelle/api/alloc/zalloc-simple.cocci @@ -127,6 +127,16 @@ statement S; if ((x==NULL) || ...) S - 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 //---------------------------------------------------------- @@ -199,9 +209,9 @@ statement S; 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 - memset((T2)x,0,E1); + memset((T2)x,0,E2); @script:python depends on org@ p << r2.p; @@ -217,7 +227,7 @@ p << r2.p; 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) //----------------------------------------------------------------- -- cgit v1.2.3-70-g09d2 From a2fc3718bc22e85378085568ecc5765fb28cabce Mon Sep 17 00:00:00 2001 From: Denis Efremov Date: Fri, 21 Aug 2020 23:11:37 +0300 Subject: coccinelle: api: add kobj_to_dev.cocci script Use kobj_to_dev() instead of container_of(). Signed-off-by: Denis Efremov Signed-off-by: Julia Lawall --- scripts/coccinelle/api/kobj_to_dev.cocci | 45 ++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 scripts/coccinelle/api/kobj_to_dev.cocci (limited to 'scripts') diff --git a/scripts/coccinelle/api/kobj_to_dev.cocci b/scripts/coccinelle/api/kobj_to_dev.cocci new file mode 100644 index 000000000000..cd5d31c6fe76 --- /dev/null +++ b/scripts/coccinelle/api/kobj_to_dev.cocci @@ -0,0 +1,45 @@ +// 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()") -- cgit v1.2.3-70-g09d2 From 5e0c074e5b4be02d57d1b60abc3391afe7edd088 Mon Sep 17 00:00:00 2001 From: Denis Efremov Date: Wed, 2 Sep 2020 07:40:59 +0300 Subject: coccinelle: ifnullfree: add vfree(), kvfree*() functions Extend the list of free functions with kvfree(), kvfree_sensitive(), vfree(). Signed-off-by: Denis Efremov Signed-off-by: Julia Lawall --- scripts/coccinelle/free/ifnullfree.cocci | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/coccinelle/free/ifnullfree.cocci b/scripts/coccinelle/free/ifnullfree.cocci index 2045391e36a0..285b92d5c665 100644 --- a/scripts/coccinelle/free/ifnullfree.cocci +++ b/scripts/coccinelle/free/ifnullfree.cocci @@ -20,8 +20,14 @@ expression E; - if (E != NULL) ( kfree(E); +| + kvfree(E); | kfree_sensitive(E); +| + kvfree_sensitive(E, ...); +| + vfree(E); | debugfs_remove(E); | @@ -42,9 +48,10 @@ position p; @@ * 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\| -* dma_pool_destroy@p\)(E); +* dma_pool_destroy@p\)(E, ...); @script:python depends on org@ p << r.p; -- cgit v1.2.3-70-g09d2 From 7c9dc603d55617edcc3190f9a6d7b5cf763feb57 Mon Sep 17 00:00:00 2001 From: Denis Efremov Date: Tue, 1 Sep 2020 12:48:12 +0300 Subject: coccinelle: misc: add uninitialized_var.cocci script uninitialized_var() macro was removed from the sources [1] and other warning-silencing tricks were deprecated [2]. The purpose of this cocci script is to prevent new occurrences of uninitialized_var() open-coded variants. [1] commit 63a0895d960a ("compiler: Remove uninitialized_var() macro") [2] commit 4b19bec97c88 ("docs: deprecated.rst: Add uninitialized_var()") Cc: Kees Cook Cc: Gustavo A. R. Silva Signed-off-by: Denis Efremov Signed-off-by: Julia Lawall --- scripts/coccinelle/misc/uninitialized_var.cocci | 51 +++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 scripts/coccinelle/misc/uninitialized_var.cocci (limited to 'scripts') diff --git a/scripts/coccinelle/misc/uninitialized_var.cocci b/scripts/coccinelle/misc/uninitialized_var.cocci new file mode 100644 index 000000000000..8fa845cefe11 --- /dev/null +++ b/scripts/coccinelle/misc/uninitialized_var.cocci @@ -0,0 +1,51 @@ +// 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)") -- cgit v1.2.3-70-g09d2 From 6519a5ab1a9ffe5cf8056f688a69960bf126e723 Mon Sep 17 00:00:00 2001 From: Denis Efremov Date: Tue, 11 Aug 2020 10:49:53 +0300 Subject: coccinelle: api: update kzfree script to kfree_sensitive Commit 453431a54934 ("mm, treewide: rename kzfree() to kfree_sensitive()") renames kzfree to kfree_sensitive and uses memzero_explicit(...) instead of memset(..., 0, ...) internally. Update cocci script to reflect these changes. Signed-off-by: Denis Efremov Signed-off-by: Julia Lawall --- scripts/coccinelle/api/kfree_sensitive.cocci | 98 ++++++++++++++++++++++++++ scripts/coccinelle/api/kzfree.cocci | 101 --------------------------- 2 files changed, 98 insertions(+), 101 deletions(-) create mode 100644 scripts/coccinelle/api/kfree_sensitive.cocci delete mode 100644 scripts/coccinelle/api/kzfree.cocci (limited to 'scripts') diff --git a/scripts/coccinelle/api/kfree_sensitive.cocci b/scripts/coccinelle/api/kfree_sensitive.cocci new file mode 100644 index 000000000000..e4a066a0b77d --- /dev/null +++ b/scripts/coccinelle/api/kfree_sensitive.cocci @@ -0,0 +1,98 @@ +// SPDX-License-Identifier: GPL-2.0-only +/// +/// Use kfree_sensitive, kvfree_sensitive rather than memset or +/// memzero_explicit followed by kfree. +/// +// Confidence: High +// Copyright: (C) 2020 Denis Efremov ISPRAS +// Options: --no-includes --include-headers +// +// Keywords: kfree_sensitive, kvfree_sensitive +// + +virtual context +virtual patch +virtual org +virtual report + +@initialize:python@ +@@ +# kmalloc_oob_in_memset uses memset to explicitly trigger out-of-bounds access +filter = frozenset(['kmalloc_oob_in_memset', + 'kfree_sensitive', 'kvfree_sensitive']) + +def relevant(p): + return not (filter & {el.current_element for el in p}) + +@cond@ +position ok; +@@ + +if (...) + \(memset@ok\|memzero_explicit@ok\)(...); + +@r depends on !patch forall@ +expression E; +position p : script:python() { relevant(p) }; +position m != cond.ok; +type T; +@@ + +( +* memset@m((T)E, 0, ...); +| +* memzero_explicit@m((T)E, ...); +) + ... when != E + when strict +* \(kfree\|vfree\|kvfree\)(E)@p; + +@rp_memzero depends on patch@ +expression E, size; +position p : script:python() { relevant(p) }; +position m != cond.ok; +type T; +@@ + +- memzero_explicit@m((T)E, size); + ... when != E + when strict +( +- kfree(E)@p; ++ kfree_sensitive(E); +| +- \(vfree\|kvfree\)(E)@p; ++ kvfree_sensitive(E, size); +) + +@rp_memset depends on patch@ +expression E, size; +position p : script:python() { relevant(p) }; +position m != cond.ok; +type T; +@@ + +- memset@m((T)E, 0, size); + ... when != E + when strict +( +- kfree(E)@p; ++ kfree_sensitive(E); +| +- \(vfree\|kvfree\)(E)@p; ++ kvfree_sensitive(E, size); +) + +@script:python depends on report@ +p << r.p; +@@ + +coccilib.report.print_report(p[0], + "WARNING: opportunity for kfree_sensitive/kvfree_sensitive") + +@script:python depends on org@ +p << r.p; +@@ + +coccilib.org.print_todo(p[0], + "WARNING: opportunity for kfree_sensitive/kvfree_sensitive") diff --git a/scripts/coccinelle/api/kzfree.cocci b/scripts/coccinelle/api/kzfree.cocci deleted file mode 100644 index 33625bd7cec9..000000000000 --- a/scripts/coccinelle/api/kzfree.cocci +++ /dev/null @@ -1,101 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/// -/// Use kzfree, kvfree_sensitive rather than memset or -/// memzero_explicit followed by kfree -/// -// Confidence: High -// Copyright: (C) 2020 Denis Efremov ISPRAS -// Options: --no-includes --include-headers -// -// Keywords: kzfree, kvfree_sensitive -// - -virtual context -virtual patch -virtual org -virtual report - -@initialize:python@ -@@ -# kmalloc_oob_in_memset uses memset to explicitly trigger out-of-bounds access -filter = frozenset(['kmalloc_oob_in_memset', 'kzfree', 'kvfree_sensitive']) - -def relevant(p): - return not (filter & {el.current_element for el in p}) - -@cond@ -position ok; -@@ - -if (...) - \(memset@ok\|memzero_explicit@ok\)(...); - -@r depends on !patch forall@ -expression E; -position p : script:python() { relevant(p) }; -position m != cond.ok; -type T; -@@ - -( -* memset@m((T)E, 0, ...); -| -* memzero_explicit@m((T)E, ...); -) - ... when != E - when strict -* \(kfree\|vfree\|kvfree\)(E)@p; - -@rp_memzero depends on patch@ -expression E, size; -position p : script:python() { relevant(p) }; -position m != cond.ok; -type T; -@@ - -- memzero_explicit@m((T)E, size); - ... when != E - when strict -// TODO: uncomment when kfree_sensitive will be merged. -// Only this case is commented out because developers -// may not like patches like this since kzfree uses memset -// internally (not memzero_explicit). -//( -//- kfree(E)@p; -//+ kfree_sensitive(E); -//| -- \(vfree\|kvfree\)(E)@p; -+ kvfree_sensitive(E, size); -//) - -@rp_memset depends on patch@ -expression E, size; -position p : script:python() { relevant(p) }; -position m != cond.ok; -type T; -@@ - -- memset@m((T)E, 0, size); - ... when != E - when strict -( -- kfree(E)@p; -+ kzfree(E); -| -- \(vfree\|kvfree\)(E)@p; -+ kvfree_sensitive(E, size); -) - -@script:python depends on report@ -p << r.p; -@@ - -coccilib.report.print_report(p[0], - "WARNING: opportunity for kzfree/kvfree_sensitive") - -@script:python depends on org@ -p << r.p; -@@ - -coccilib.org.print_todo(p[0], - "WARNING: opportunity for kzfree/kvfree_sensitive") -- cgit v1.2.3-70-g09d2 From a19d1358345e040af9164ee7dd0f39ea0a99d565 Mon Sep 17 00:00:00 2001 From: Sumera Priyadarsini Date: Sun, 13 Sep 2020 17:35:48 +0530 Subject: scripts: coccicheck: Improve error feedback when coccicheck fails Currently, coccicheck fails with only the message "coccicheck failed" and the error code for the failure. To obtain the error logs, one needs to specify a debug file using the DEBUG_FILE option. Modify coccicheck to display error logs when it crashes unless DEBUG_FILE is set, in which case, the error logs are stored in the specified debug file. Signed-off-by: Sumera Priyadarsini Signed-off-by: Julia Lawall --- scripts/coccicheck | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/coccicheck b/scripts/coccicheck index 6e37cf36caae..85136f4fe970 100755 --- a/scripts/coccicheck +++ b/scripts/coccicheck @@ -126,8 +126,14 @@ run_cmd_parmap() { if [ $VERBOSE -ne 0 ] ; then echo "Running ($NPROC in parallel): $@" fi - echo $@ >>$DEBUG_FILE - $@ 2>>$DEBUG_FILE + if [ "$DEBUG_FILE" != "/dev/null" -a "$DEBUG_FILE" != "" ]; then + echo $@>>$DEBUG_FILE + $@ 2>>$DEBUG_FILE + else + echo $@ + $@ 2>&1 + fi + err=$? if [[ $err -ne 0 ]]; then echo "coccicheck failed" -- cgit v1.2.3-70-g09d2 From b76f0ea013125358d1b4ca147a6f9b6883dd2493 Mon Sep 17 00:00:00 2001 From: Denis Efremov Date: Mon, 21 Sep 2020 18:28:50 +0300 Subject: coccinelle: misc: add excluded_middle.cocci script Check for !A || A && B condition. It's equivalent to !A || B. Signed-off-by: Denis Efremov Signed-off-by: Julia Lawall --- scripts/coccinelle/misc/excluded_middle.cocci | 39 +++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 scripts/coccinelle/misc/excluded_middle.cocci (limited to 'scripts') diff --git a/scripts/coccinelle/misc/excluded_middle.cocci b/scripts/coccinelle/misc/excluded_middle.cocci new file mode 100644 index 000000000000..ab28393e4843 --- /dev/null +++ b/scripts/coccinelle/misc/excluded_middle.cocci @@ -0,0 +1,39 @@ +// 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") -- cgit v1.2.3-70-g09d2 From e16a7c47d56b4eeee82be662014c145bce2380e5 Mon Sep 17 00:00:00 2001 From: Sumera Priyadarsini Date: Thu, 24 Sep 2020 16:56:08 +0530 Subject: scripts: coccicheck: Change default value for parallelism By default, coccicheck utilizes all available threads to implement parallelisation. However, when all available threads are used, a decrease in performance is noted. The elapsed time is minimum when at most one thread per core is used. For example, on benchmarking the semantic patch kfree.cocci for usb/serial using hyperfine, the outputs obtained for J=5 and J=2 are 1.32 and 1.90 times faster than those for J=10 and J=9 respectively for two separate runs. For the larger drivers/staging directory, minimium elapsed time is obtained for J=3 which is 1.86 times faster than that for J=12. The optimal J value does not exceed 6 in any of the test runs. The benchmarks are run on a machine with 6 cores, with 2 threads per core, i.e, 12 hyperthreads in all. To improve performance, modify coccicheck to use at most only one thread per core by default. Signed-off-by: Sumera Priyadarsini Signed-off-by: Julia Lawall --- scripts/coccicheck | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'scripts') diff --git a/scripts/coccicheck b/scripts/coccicheck index 85136f4fe970..6789751607f5 100755 --- a/scripts/coccicheck +++ b/scripts/coccicheck @@ -75,8 +75,13 @@ else OPTIONS="--dir $KBUILD_EXTMOD $COCCIINCLUDE" 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 NPROC=$(getconf _NPROCESSORS_ONLN) + if [ $THREADS_PER_CORE -gt 1 -a $NPROC -gt 2 ] ; then + NPROC=$((NPROC/2)) + fi else NPROC="$J" fi -- cgit v1.2.3-70-g09d2 From 44d8870f21529cfa8f50b503b5d949c6d46e6fc1 Mon Sep 17 00:00:00 2001 From: Denis Efremov Date: Wed, 30 Sep 2020 19:00:46 +0300 Subject: coccinelle: api: add kvmalloc script Suggest kvmalloc, kvfree instead of opencoded patterns. Signed-off-by: Denis Efremov Signed-off-by: Julia Lawall --- scripts/coccinelle/api/kvmalloc.cocci | 256 ++++++++++++++++++++++++++++++++++ 1 file changed, 256 insertions(+) create mode 100644 scripts/coccinelle/api/kvmalloc.cocci (limited to 'scripts') diff --git a/scripts/coccinelle/api/kvmalloc.cocci b/scripts/coccinelle/api/kvmalloc.cocci new file mode 100644 index 000000000000..c30dab718a49 --- /dev/null +++ b/scripts/coccinelle/api/kvmalloc.cocci @@ -0,0 +1,256 @@ +// 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") -- cgit v1.2.3-70-g09d2 From 7b36c1398fb63f9c38cc83dc75f143d2e5995062 Mon Sep 17 00:00:00 2001 From: Denis Efremov Date: Mon, 21 Sep 2020 20:49:20 +0300 Subject: coccinelle: misc: add flexible_array.cocci script One-element and zero-length arrays are deprecated [1]. Kernel code should always use "flexible array members" instead, except for existing uapi definitions. The script warns about one-element and zero-length arrays in structs. [1] commit 68e4cd17e218 ("docs: deprecated.rst: Add zero-length and one-element arrays") Cc: Kees Cook Cc: Gustavo A. R. Silva Signed-off-by: Denis Efremov Signed-off-by: Julia Lawall --- scripts/coccinelle/misc/flexible_array.cocci | 88 ++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 scripts/coccinelle/misc/flexible_array.cocci (limited to 'scripts') diff --git a/scripts/coccinelle/misc/flexible_array.cocci b/scripts/coccinelle/misc/flexible_array.cocci new file mode 100644 index 000000000000..947fbaff82a9 --- /dev/null +++ b/scripts/coccinelle/misc/flexible_array.cocci @@ -0,0 +1,88 @@ +// 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) -- cgit v1.2.3-70-g09d2 From 28c185a88607bc361ec7f071b907285e2e75de1b Mon Sep 17 00:00:00 2001 From: Denis Efremov Date: Fri, 9 Oct 2020 15:54:53 +0300 Subject: coccinelle: api: kfree_sensitive: print memset position Print memset() call position in addition to the kfree() position to ease issues identification. Signed-off-by: Denis Efremov Signed-off-by: Julia Lawall --- scripts/coccinelle/api/kfree_sensitive.cocci | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'scripts') diff --git a/scripts/coccinelle/api/kfree_sensitive.cocci b/scripts/coccinelle/api/kfree_sensitive.cocci index e4a066a0b77d..8d980ebf3223 100644 --- a/scripts/coccinelle/api/kfree_sensitive.cocci +++ b/scripts/coccinelle/api/kfree_sensitive.cocci @@ -85,14 +85,16 @@ type T; @script:python depends on report@ p << r.p; +m << r.m; @@ -coccilib.report.print_report(p[0], - "WARNING: opportunity for kfree_sensitive/kvfree_sensitive") +msg = "WARNING opportunity for kfree_sensitive/kvfree_sensitive (memset at line %s)" +coccilib.report.print_report(p[0], msg % (m[0].line)) @script:python depends on org@ p << r.p; +m << r.m; @@ -coccilib.org.print_todo(p[0], - "WARNING: opportunity for kfree_sensitive/kvfree_sensitive") +msg = "WARNING opportunity for kfree_sensitive/kvfree_sensitive (memset at line %s)" +coccilib.org.print_todo(p[0], msg % (m[0].line)) -- cgit v1.2.3-70-g09d2 From 2f324dd8ab2e3d8b097f3eac6d380d1adbdbe6e6 Mon Sep 17 00:00:00 2001 From: Sumera Priyadarsini Date: Sun, 11 Oct 2020 15:58:43 +0530 Subject: scripts: coccicheck: Add quotes to improve portability While fetching the number of threads per core with lscpu, the [:digit:] set is used for translation of digits from 0-9. However, using [:digit:] instead of "[:digit:]" does not seem to work uniformly for some shell types and configurations (such as zsh). Therefore, modify coccicheck to use double quotes around the [:digit:] set for uniformity and better portability. Signed-off-by: Sumera Priyadarsini Signed-off-by: Julia Lawall --- scripts/coccicheck | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/coccicheck b/scripts/coccicheck index 6789751607f5..d67907b8a38b 100755 --- a/scripts/coccicheck +++ b/scripts/coccicheck @@ -76,7 +76,7 @@ else 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:]) + THREADS_PER_CORE=$(lscpu | grep "Thread(s) per core: " | tr -cd "[:digit:]") if [ -z "$J" ]; then NPROC=$(getconf _NPROCESSORS_ONLN) if [ $THREADS_PER_CORE -gt 1 -a $NPROC -gt 2 ] ; then -- cgit v1.2.3-70-g09d2 From c5864560d935db879cafa21feca0156d91eba842 Mon Sep 17 00:00:00 2001 From: Sumera Priyadarsini Date: Sun, 11 Oct 2020 15:59:42 +0530 Subject: scripts: coccicheck: Change default condition for parallelism Currently, Coccinelle uses at most one thread per core by default in machines with more than 2 hyperthreads. However, for systems with only 4 hyperthreads, this does not improve performance. Modify coccicheck to use all available threads in machines with upto 4 hyperthreads. Signed-off-by: Sumera Priyadarsini Signed-off-by: Julia Lawall --- scripts/coccicheck | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/coccicheck b/scripts/coccicheck index d67907b8a38b..209bb0427b43 100755 --- a/scripts/coccicheck +++ b/scripts/coccicheck @@ -79,7 +79,7 @@ else THREADS_PER_CORE=$(lscpu | grep "Thread(s) per core: " | tr -cd "[:digit:]") if [ -z "$J" ]; then NPROC=$(getconf _NPROCESSORS_ONLN) - if [ $THREADS_PER_CORE -gt 1 -a $NPROC -gt 2 ] ; then + if [ $THREADS_PER_CORE -gt 1 -a $NPROC -gt 4 ] ; then NPROC=$((NPROC/2)) fi else -- cgit v1.2.3-70-g09d2 From 82c2d81361ecd142a54e84a9da1e287113314a4f Mon Sep 17 00:00:00 2001 From: Sumera Priyadarsini Date: Thu, 15 Oct 2020 16:21:40 +0530 Subject: coccinelle: iterators: Add for_each_child.cocci script While iterating over child nodes with the for_each functions, if control is transferred from the middle of the loop, as in the case of a break or return or goto, there is no decrement in the reference counter thus ultimately resulting in a memory leak. Add this script to detect potential memory leaks caused by the absence of of_node_put() before break, goto, or, return statements which transfer control outside the loop. Signed-off-by: Sumera Priyadarsini Signed-off-by: Julia Lawall --- scripts/coccinelle/iterators/for_each_child.cocci | 358 ++++++++++++++++++++++ 1 file changed, 358 insertions(+) create mode 100644 scripts/coccinelle/iterators/for_each_child.cocci (limited to 'scripts') diff --git a/scripts/coccinelle/iterators/for_each_child.cocci b/scripts/coccinelle/iterators/for_each_child.cocci new file mode 100644 index 000000000000..bc394615948e --- /dev/null +++ b/scripts/coccinelle/iterators/for_each_child.cocci @@ -0,0 +1,358 @@ +// 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) -- cgit v1.2.3-70-g09d2 From edc05fe5559e9b79e64cfec3b960f6a913b73493 Mon Sep 17 00:00:00 2001 From: Denis Efremov Date: Fri, 16 Oct 2020 11:54:42 +0300 Subject: coccinelle: api: add kfree_mismatch script Check that alloc and free types of functions match each other. Signed-off-by: Denis Efremov Signed-off-by: Julia Lawall --- scripts/coccinelle/api/kfree_mismatch.cocci | 228 ++++++++++++++++++++++++++++ 1 file changed, 228 insertions(+) create mode 100644 scripts/coccinelle/api/kfree_mismatch.cocci (limited to 'scripts') diff --git a/scripts/coccinelle/api/kfree_mismatch.cocci b/scripts/coccinelle/api/kfree_mismatch.cocci new file mode 100644 index 000000000000..d46a9b3eb7b3 --- /dev/null +++ b/scripts/coccinelle/api/kfree_mismatch.cocci @@ -0,0 +1,228 @@ +// 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) -- cgit v1.2.3-70-g09d2