Commit f66179ca authored by Linus Torvalds's avatar Linus Torvalds
Browse files
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
Loading
Loading
Loading
Loading
+14 −3
Original line number Diff line number Diff line
@@ -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 4 ] ; then
		NPROC=$((NPROC/2))
	fi
    else
        NPROC="$J"
    fi
@@ -99,7 +104,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=<mode>"'
	echo 'Note however that some modes are not implemented by some semantic patches.'
    fi
@@ -126,8 +131,14 @@ run_cmd_parmap() {
	if [ $VERBOSE -ne 0 ] ; then
		echo "Running ($NPROC in parallel): $@"
	fi
	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"
+13 −3
Original line number Diff line number Diff line
@@ -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)

//-----------------------------------------------------------------
+228 −0
Original line number Diff line number Diff line
// 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)
+17 −18
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
///
/// Use kzfree, kvfree_sensitive rather than memset or
/// memzero_explicit followed by kfree
/// 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: kzfree, kvfree_sensitive
// Keywords: kfree_sensitive, kvfree_sensitive
//

virtual context
@@ -18,7 +18,8 @@ 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'])
filter = frozenset(['kmalloc_oob_in_memset',
		    'kfree_sensitive', 'kvfree_sensitive'])

def relevant(p):
    return not (filter & {el.current_element for el in p})
@@ -56,17 +57,13 @@ 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);
//|
(
- kfree(E)@p;
+ kfree_sensitive(E);
|
- \(vfree\|kvfree\)(E)@p;
+ kvfree_sensitive(E, size);
//)
)

@rp_memset depends on patch@
expression E, size;
@@ -80,7 +77,7 @@ type T;
      when strict
(
- kfree(E)@p;
+ kzfree(E);
+ kfree_sensitive(E);
|
- \(vfree\|kvfree\)(E)@p;
+ kvfree_sensitive(E, size);
@@ -88,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 kzfree/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 kzfree/kvfree_sensitive")
msg = "WARNING opportunity for kfree_sensitive/kvfree_sensitive (memset at line %s)"
coccilib.org.print_todo(p[0], msg % (m[0].line))
+45 −0
Original line number Diff line number Diff 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()")
Loading