Re: [Cocci] [PATCH v8] coccinelle: api: add kfree_mismatch script

2020-10-16 Thread Julia Lawall


On Fri, 16 Oct 2020, Markus Elfring wrote:

> …
> > +E = \(kmalloc\|kzalloc\|krealloc\|kcalloc\|
> > +  kmalloc_node\|kzalloc_node\|kmalloc_array\|
> > +  kmalloc_array_node\|kcalloc_node\)(...)@kok
> …
>
> How do you think about the possibility for any adjustments according to the 
> order
> of the mentioned function names in proposed disjunctions for the semantic 
> patch language?

Please think about this for 5 seconds.  Maybe there are 2000 calls to
these allocation functions, and maybe there are a million function calls
in the files that contain these calls.  Microscopically optimizing the
treatment of 2000 calls is not going to do anything to help the overall
runtime, which depends on matching all of the above function names against
the one million overall calls.

> Can any additional identifiers become relevant?

If you have other names to suggest, please do.  If you don't have other
names to suggest, then please stop asking such rhetorical questions.

julia___
Cocci mailing list
Cocci@systeme.lip6.fr
https://systeme.lip6.fr/mailman/listinfo/cocci


Re: [Cocci] [PATCH v8] coccinelle: api: add kfree_mismatch script

2020-10-16 Thread Markus Elfring
…
> +E = \(kmalloc\|kzalloc\|krealloc\|kcalloc\|
> +  kmalloc_node\|kzalloc_node\|kmalloc_array\|
> +  kmalloc_array_node\|kcalloc_node\)(...)@kok
…

How do you think about the possibility for any adjustments according to the 
order
of the mentioned function names in proposed disjunctions for the semantic patch 
language?

Can any additional identifiers become relevant?

Regards,
Markus


___
Cocci mailing list
Cocci@systeme.lip6.fr
https://systeme.lip6.fr/mailman/listinfo/cocci


[Cocci] [PATCH v8] coccinelle: api: add kfree_mismatch script

2020-10-16 Thread Denis Efremov
Check that alloc and free types of functions match each other.

Signed-off-by: Denis Efremov 
---
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
Changes in v4:
 - missing msg argument to print_todo fixed
Changes in v5:
 - fix position p in kfree rule
 - move @kok and @v positions in choice rule after the arguments
 - remove kvmalloc suggestions
Changes in v6:
 - more asterisks added in context mode
 - second @kok added to the choice rule
Changes in v7:
 - file renamed to kfree_mismatch.cocci
 - python function relevant() removed
 - additional rule for filtering free positions added
 - btrfs false-positive fixed
 - confidence level changed to high
 - kvfree_switch rule added
 - names for position variables changed to @a (alloc) and @f (free)
Changes in v8:
 - kzfree() replaced with kfree_sensitive()
 - "position f != free.fok;" simplified to "position f;" in patch
   and kvfree_switch rules

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

diff --git a/scripts/coccinelle/api/kfree_mismatch.cocci 
b/scripts/coccinelle/api/kfree_mismatch.cocci
new file mode 100644
index ..843b794fac7b
--- /dev/null
+++ b/scripts/coccinelle/api/kfree_mismatch.cocci
@@ -0,0 +1,229 @@
+// 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;