forked from mirrors/linux
		
	scripts/coccinelle: improve the coverage of some semantic patches
This patch ensures that all semantic patches in the scripts/coccinelle directory provide the report option. Report messages that include line numbers now have the line number preceded by "line" for easier subsequent processing. Signed-off-by: Julia Lawall <Julia.Lawall@lip6.fr> Signed-off-by: Michal Marek <mmarek@suse.cz>
This commit is contained in:
		
							parent
							
								
									fb3f8af4ff
								
							
						
					
					
						commit
						29a36d4dec
					
				
					 11 changed files with 351 additions and 76 deletions
				
			
		| 
						 | 
				
			
			@ -1,16 +1,19 @@
 | 
			
		|||
/// Use kstrdup rather than duplicating its implementation
 | 
			
		||||
///
 | 
			
		||||
// Confidence: High
 | 
			
		||||
// Copyright: (C) 2010 Nicolas Palix, DIKU.  GPLv2.
 | 
			
		||||
// Copyright: (C) 2010 Julia Lawall, DIKU.  GPLv2.
 | 
			
		||||
// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6.  GPLv2.
 | 
			
		||||
// Copyright: (C) 2010-2012 Nicolas Palix.  GPLv2.
 | 
			
		||||
// Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6.  GPLv2.
 | 
			
		||||
// Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6.  GPLv2.
 | 
			
		||||
// URL: http://coccinelle.lip6.fr/
 | 
			
		||||
// Comments:
 | 
			
		||||
// Options: -no_includes -include_headers
 | 
			
		||||
 | 
			
		||||
virtual patch
 | 
			
		||||
virtual context
 | 
			
		||||
virtual org
 | 
			
		||||
virtual report
 | 
			
		||||
 | 
			
		||||
@@
 | 
			
		||||
@depends on patch@
 | 
			
		||||
expression from,to;
 | 
			
		||||
expression flag,E1,E2;
 | 
			
		||||
statement S;
 | 
			
		||||
| 
						 | 
				
			
			@ -23,7 +26,7 @@ statement S;
 | 
			
		|||
   ... when != \(from = E2 \| to = E2 \)
 | 
			
		||||
-  strcpy(to, from);
 | 
			
		||||
 | 
			
		||||
@@
 | 
			
		||||
@depends on patch@
 | 
			
		||||
expression x,from,to;
 | 
			
		||||
expression flag,E1,E2,E3;
 | 
			
		||||
statement S;
 | 
			
		||||
| 
						 | 
				
			
			@ -37,3 +40,65 @@ statement S;
 | 
			
		|||
    if (to==NULL || ...) S
 | 
			
		||||
    ... when != \(x = E3 \| from = E3 \| to = E3 \)
 | 
			
		||||
-   memcpy(to, from, x);
 | 
			
		||||
 | 
			
		||||
// ---------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
@r1 depends on !patch exists@
 | 
			
		||||
expression from,to;
 | 
			
		||||
expression flag,E1,E2;
 | 
			
		||||
statement S;
 | 
			
		||||
position p1,p2;
 | 
			
		||||
@@
 | 
			
		||||
 | 
			
		||||
*  to = kmalloc@p1(strlen(from) + 1,flag);
 | 
			
		||||
   ... when != \(from = E1 \| to = E1 \)
 | 
			
		||||
   if (to==NULL || ...) S
 | 
			
		||||
   ... when != \(from = E2 \| to = E2 \)
 | 
			
		||||
*  strcpy@p2(to, from);
 | 
			
		||||
 | 
			
		||||
@r2 depends on !patch exists@
 | 
			
		||||
expression x,from,to;
 | 
			
		||||
expression flag,E1,E2,E3;
 | 
			
		||||
statement S;
 | 
			
		||||
position p1,p2;
 | 
			
		||||
@@
 | 
			
		||||
 | 
			
		||||
*   x = strlen(from) + 1;
 | 
			
		||||
    ... when != \( x = E1 \| from = E1 \)
 | 
			
		||||
*   to = \(kmalloc@p1\|kzalloc@p2\)(x,flag);
 | 
			
		||||
    ... when != \(x = E2 \| from = E2 \| to = E2 \)
 | 
			
		||||
    if (to==NULL || ...) S
 | 
			
		||||
    ... when != \(x = E3 \| from = E3 \| to = E3 \)
 | 
			
		||||
*   memcpy@p2(to, from, x);
 | 
			
		||||
 | 
			
		||||
@script:python depends on org@
 | 
			
		||||
p1 << r1.p1;
 | 
			
		||||
p2 << r1.p2;
 | 
			
		||||
@@
 | 
			
		||||
 | 
			
		||||
cocci.print_main("WARNING opportunity for kstrdep",p1)
 | 
			
		||||
cocci.print_secs("strcpy",p2)
 | 
			
		||||
 | 
			
		||||
@script:python depends on org@
 | 
			
		||||
p1 << r2.p1;
 | 
			
		||||
p2 << r2.p2;
 | 
			
		||||
@@
 | 
			
		||||
 | 
			
		||||
cocci.print_main("WARNING opportunity for kstrdep",p1)
 | 
			
		||||
cocci.print_secs("memcpy",p2)
 | 
			
		||||
 | 
			
		||||
@script:python depends on report@
 | 
			
		||||
p1 << r1.p1;
 | 
			
		||||
p2 << r1.p2;
 | 
			
		||||
@@
 | 
			
		||||
 | 
			
		||||
msg = "WARNING opportunity for kstrdep (strcpy on line %s)" % (p2[0].line)
 | 
			
		||||
coccilib.report.print_report(p1[0], msg)
 | 
			
		||||
 | 
			
		||||
@script:python depends on report@
 | 
			
		||||
p1 << r2.p1;
 | 
			
		||||
p2 << r2.p2;
 | 
			
		||||
@@
 | 
			
		||||
 | 
			
		||||
msg = "WARNING opportunity for kstrdep (memcpy on line %s)" % (p2[0].line)
 | 
			
		||||
coccilib.report.print_report(p1[0], msg)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,14 +1,17 @@
 | 
			
		|||
/// Use kmemdup rather than duplicating its implementation
 | 
			
		||||
///
 | 
			
		||||
// Confidence: High
 | 
			
		||||
// Copyright: (C) 2010 Nicolas Palix, DIKU.  GPLv2.
 | 
			
		||||
// Copyright: (C) 2010 Julia Lawall, DIKU.  GPLv2.
 | 
			
		||||
// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6.  GPLv2.
 | 
			
		||||
// Copyright: (C) 2010-2012 Nicolas Palix.  GPLv2.
 | 
			
		||||
// Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6.  GPLv2.
 | 
			
		||||
// Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6.  GPLv2.
 | 
			
		||||
// URL: http://coccinelle.lip6.fr/
 | 
			
		||||
// Comments:
 | 
			
		||||
// Options: -no_includes -include_headers
 | 
			
		||||
 | 
			
		||||
virtual patch
 | 
			
		||||
virtual context
 | 
			
		||||
virtual org
 | 
			
		||||
virtual report
 | 
			
		||||
 | 
			
		||||
@r1@
 | 
			
		||||
expression from,to;
 | 
			
		||||
| 
						 | 
				
			
			@ -28,7 +31,7 @@ position p;
 | 
			
		|||
    ... when != \( x = E1 \| from = E1 \)
 | 
			
		||||
    to = \(kmalloc@p\|kzalloc@p\)(x,flag);
 | 
			
		||||
 | 
			
		||||
@@
 | 
			
		||||
@depends on patch@
 | 
			
		||||
expression from,to,size,flag;
 | 
			
		||||
position p != {r1.p,r2.p};
 | 
			
		||||
statement S;
 | 
			
		||||
| 
						 | 
				
			
			@ -38,3 +41,26 @@ statement S;
 | 
			
		|||
+  to = kmemdup(from,size,flag);
 | 
			
		||||
   if (to==NULL || ...) S
 | 
			
		||||
-  memcpy(to, from, size);
 | 
			
		||||
 | 
			
		||||
@r depends on !patch@
 | 
			
		||||
expression from,to,size,flag;
 | 
			
		||||
position p != {r1.p,r2.p};
 | 
			
		||||
statement S;
 | 
			
		||||
@@
 | 
			
		||||
 | 
			
		||||
*  to = \(kmalloc@p\|kzalloc@p\)(size,flag);
 | 
			
		||||
   to = kmemdup(from,size,flag);
 | 
			
		||||
   if (to==NULL || ...) S
 | 
			
		||||
*  memcpy(to, from, size);
 | 
			
		||||
 | 
			
		||||
@script:python depends on org@
 | 
			
		||||
p << r.p;
 | 
			
		||||
@@
 | 
			
		||||
 | 
			
		||||
coccilib.org.print_todo(p[0], "WARNING opportunity for kmemdep")
 | 
			
		||||
 | 
			
		||||
@script:python depends on report@
 | 
			
		||||
p << r.p;
 | 
			
		||||
@@
 | 
			
		||||
 | 
			
		||||
coccilib.report.print_report(p[0], "WARNING opportunity for kmemdep")
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,23 +1,25 @@
 | 
			
		|||
/// Use kmemdup_user rather than duplicating its implementation
 | 
			
		||||
/// Use memdup_user rather than duplicating its implementation
 | 
			
		||||
/// This is a little bit restricted to reduce false positives
 | 
			
		||||
///
 | 
			
		||||
// Confidence: High
 | 
			
		||||
// Copyright: (C) 2010 Nicolas Palix, DIKU.  GPLv2.
 | 
			
		||||
// Copyright: (C) 2010 Julia Lawall, DIKU.  GPLv2.
 | 
			
		||||
// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6.  GPLv2.
 | 
			
		||||
// Copyright: (C) 2010-2012 Nicolas Palix.  GPLv2.
 | 
			
		||||
// Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6.  GPLv2.
 | 
			
		||||
// Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6.  GPLv2.
 | 
			
		||||
// URL: http://coccinelle.lip6.fr/
 | 
			
		||||
// Comments:
 | 
			
		||||
// Options: -no_includes -include_headers
 | 
			
		||||
 | 
			
		||||
virtual patch
 | 
			
		||||
virtual context
 | 
			
		||||
virtual org
 | 
			
		||||
virtual report
 | 
			
		||||
 | 
			
		||||
@@
 | 
			
		||||
@depends on patch@
 | 
			
		||||
expression from,to,size,flag;
 | 
			
		||||
position p;
 | 
			
		||||
identifier l1,l2;
 | 
			
		||||
@@
 | 
			
		||||
 | 
			
		||||
-  to = \(kmalloc@p\|kzalloc@p\)(size,flag);
 | 
			
		||||
-  to = \(kmalloc\|kzalloc\)(size,flag);
 | 
			
		||||
+  to = memdup_user(from,size);
 | 
			
		||||
   if (
 | 
			
		||||
-      to==NULL
 | 
			
		||||
| 
						 | 
				
			
			@ -33,3 +35,26 @@ identifier l1,l2;
 | 
			
		|||
-    -EFAULT
 | 
			
		||||
-    ...+>
 | 
			
		||||
-  }
 | 
			
		||||
 | 
			
		||||
@r depends on !patch@
 | 
			
		||||
expression from,to,size,flag;
 | 
			
		||||
position p;
 | 
			
		||||
statement S1,S2;
 | 
			
		||||
@@
 | 
			
		||||
 | 
			
		||||
*  to = \(kmalloc@p\|kzalloc@p\)(size,flag);
 | 
			
		||||
   if (to==NULL || ...) S1
 | 
			
		||||
   if (copy_from_user(to, from, size) != 0)
 | 
			
		||||
   S2
 | 
			
		||||
 | 
			
		||||
@script:python depends on org@
 | 
			
		||||
p << r.p;
 | 
			
		||||
@@
 | 
			
		||||
 | 
			
		||||
coccilib.org.print_todo(p[0], "WARNING opportunity for memdep_user")
 | 
			
		||||
 | 
			
		||||
@script:python depends on report@
 | 
			
		||||
p << r.p;
 | 
			
		||||
@@
 | 
			
		||||
 | 
			
		||||
coccilib.report.print_report(p[0], "WARNING opportunity for memdep_user")
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5,9 +5,9 @@
 | 
			
		|||
//# SCTP_DBG_OBJCNT_DEC that do not actually evaluate their argument
 | 
			
		||||
///
 | 
			
		||||
// Confidence: Moderate
 | 
			
		||||
// Copyright: (C) 2010 Nicolas Palix, DIKU.  GPLv2.
 | 
			
		||||
// Copyright: (C) 2010 Julia Lawall, DIKU.  GPLv2.
 | 
			
		||||
// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6.  GPLv2.
 | 
			
		||||
// Copyright: (C) 2010-2012 Nicolas Palix.  GPLv2.
 | 
			
		||||
// Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6.  GPLv2.
 | 
			
		||||
// Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6.  GPLv2.
 | 
			
		||||
// URL: http://coccinelle.lip6.fr/
 | 
			
		||||
// Comments:
 | 
			
		||||
// Options: -no_includes -include_headers
 | 
			
		||||
| 
						 | 
				
			
			@ -23,7 +23,7 @@ position p1;
 | 
			
		|||
kfree@p1(E)
 | 
			
		||||
 | 
			
		||||
@print expression@
 | 
			
		||||
constant char *c;
 | 
			
		||||
constant char [] c;
 | 
			
		||||
expression free.E,E2;
 | 
			
		||||
type T;
 | 
			
		||||
position p;
 | 
			
		||||
| 
						 | 
				
			
			@ -36,6 +36,10 @@ identifier f;
 | 
			
		|||
 E@p == E2
 | 
			
		||||
|
 | 
			
		||||
 E@p != E2
 | 
			
		||||
|
 | 
			
		||||
 E2 == E@p
 | 
			
		||||
|
 | 
			
		||||
 E2 != E@p
 | 
			
		||||
|
 | 
			
		||||
 !E@p
 | 
			
		||||
|
 | 
			
		||||
| 
						 | 
				
			
			@ -113,5 +117,5 @@ p1 << free.p1;
 | 
			
		|||
p2 << r.p2;
 | 
			
		||||
@@
 | 
			
		||||
 | 
			
		||||
msg = "reference preceded by free on line %s" % (p1[0].line)
 | 
			
		||||
msg = "ERROR: reference preceded by free on line %s" % (p1[0].line)
 | 
			
		||||
coccilib.report.print_report(p2[0],msg)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,16 +2,19 @@
 | 
			
		|||
/// is no point to call of_node_put on the final value.
 | 
			
		||||
///
 | 
			
		||||
// Confidence: High
 | 
			
		||||
// Copyright: (C) 2010 Nicolas Palix, DIKU.  GPLv2.
 | 
			
		||||
// Copyright: (C) 2010 Julia Lawall, DIKU.  GPLv2.
 | 
			
		||||
// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6.  GPLv2.
 | 
			
		||||
// Copyright: (C) 2010-2012 Nicolas Palix.  GPLv2.
 | 
			
		||||
// Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6.  GPLv2.
 | 
			
		||||
// Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6.  GPLv2.
 | 
			
		||||
// URL: http://coccinelle.lip6.fr/
 | 
			
		||||
// Comments:
 | 
			
		||||
// Options: -no_includes -include_headers
 | 
			
		||||
 | 
			
		||||
virtual patch
 | 
			
		||||
virtual context
 | 
			
		||||
virtual org
 | 
			
		||||
virtual report
 | 
			
		||||
 | 
			
		||||
@@
 | 
			
		||||
@depends on patch@
 | 
			
		||||
iterator name for_each_node_by_name;
 | 
			
		||||
expression np,E;
 | 
			
		||||
identifier l;
 | 
			
		||||
| 
						 | 
				
			
			@ -24,7 +27,7 @@ for_each_node_by_name(np,...) {
 | 
			
		|||
... when != np = E
 | 
			
		||||
- of_node_put(np);
 | 
			
		||||
 | 
			
		||||
@@
 | 
			
		||||
@depends on patch@
 | 
			
		||||
iterator name for_each_node_by_type;
 | 
			
		||||
expression np,E;
 | 
			
		||||
identifier l;
 | 
			
		||||
| 
						 | 
				
			
			@ -37,7 +40,7 @@ for_each_node_by_type(np,...) {
 | 
			
		|||
... when != np = E
 | 
			
		||||
- of_node_put(np);
 | 
			
		||||
 | 
			
		||||
@@
 | 
			
		||||
@depends on patch@
 | 
			
		||||
iterator name for_each_compatible_node;
 | 
			
		||||
expression np,E;
 | 
			
		||||
identifier l;
 | 
			
		||||
| 
						 | 
				
			
			@ -50,7 +53,7 @@ for_each_compatible_node(np,...) {
 | 
			
		|||
... when != np = E
 | 
			
		||||
- of_node_put(np);
 | 
			
		||||
 | 
			
		||||
@@
 | 
			
		||||
@depends on patch@
 | 
			
		||||
iterator name for_each_matching_node;
 | 
			
		||||
expression np,E;
 | 
			
		||||
identifier l;
 | 
			
		||||
| 
						 | 
				
			
			@ -62,3 +65,59 @@ for_each_matching_node(np,...) {
 | 
			
		|||
}
 | 
			
		||||
... when != np = E
 | 
			
		||||
- of_node_put(np);
 | 
			
		||||
 | 
			
		||||
// ----------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
@r depends on !patch forall@
 | 
			
		||||
//iterator name for_each_node_by_name;
 | 
			
		||||
//iterator name for_each_node_by_type;
 | 
			
		||||
//iterator name for_each_compatible_node;
 | 
			
		||||
//iterator name for_each_matching_node;
 | 
			
		||||
expression np,E;
 | 
			
		||||
identifier l;
 | 
			
		||||
position p1,p2;
 | 
			
		||||
@@
 | 
			
		||||
 | 
			
		||||
(
 | 
			
		||||
*for_each_node_by_name@p1(np,...)
 | 
			
		||||
{
 | 
			
		||||
  ... when != break;
 | 
			
		||||
      when != goto l;
 | 
			
		||||
}
 | 
			
		||||
|
 | 
			
		||||
*for_each_node_by_type@p1(np,...)
 | 
			
		||||
{
 | 
			
		||||
  ... when != break;
 | 
			
		||||
      when != goto l;
 | 
			
		||||
}
 | 
			
		||||
|
 | 
			
		||||
*for_each_compatible_node@p1(np,...)
 | 
			
		||||
{
 | 
			
		||||
  ... when != break;
 | 
			
		||||
      when != goto l;
 | 
			
		||||
}
 | 
			
		||||
|
 | 
			
		||||
*for_each_matching_node@p1(np,...)
 | 
			
		||||
{
 | 
			
		||||
  ... when != break;
 | 
			
		||||
      when != goto l;
 | 
			
		||||
}
 | 
			
		||||
)
 | 
			
		||||
... when != np = E
 | 
			
		||||
* of_node_put@p2(np);
 | 
			
		||||
 | 
			
		||||
@script:python depends on org@
 | 
			
		||||
p1 << r.p1;
 | 
			
		||||
p2 << r.p2;
 | 
			
		||||
@@
 | 
			
		||||
 | 
			
		||||
cocci.print_main("unneeded of_node_put",p2)
 | 
			
		||||
cocci.print_secs("iterator",p1)
 | 
			
		||||
 | 
			
		||||
@script:python depends on report@
 | 
			
		||||
p1 << r.p1;
 | 
			
		||||
p2 << r.p2;
 | 
			
		||||
@@
 | 
			
		||||
 | 
			
		||||
msg = "ERROR: of_node_put not needed after iterator on line %s" % (p1[0].line)
 | 
			
		||||
coccilib.report.print_report(p2[0], msg)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,20 +1,24 @@
 | 
			
		|||
/// Many iterators have the property that the first argument is always bound
 | 
			
		||||
/// to a real list element, never NULL.  False positives arise for some
 | 
			
		||||
/// iterators that do not have this property, or in cases when the loop
 | 
			
		||||
/// cursor is reassigned.  The latter should only happen when the matched
 | 
			
		||||
/// code is on the way to a loop exit (break, goto, or return).
 | 
			
		||||
/// to a real list element, never NULL.
 | 
			
		||||
//# False positives arise for some iterators that do not have this property,
 | 
			
		||||
//# or in cases when the loop cursor is reassigned.  The latter should only
 | 
			
		||||
//# happen when the matched code is on the way to a loop exit (break, goto,
 | 
			
		||||
//# or return).
 | 
			
		||||
///
 | 
			
		||||
// Confidence: Moderate
 | 
			
		||||
// Copyright: (C) 2010 Nicolas Palix, DIKU.  GPLv2.
 | 
			
		||||
// Copyright: (C) 2010 Julia Lawall, DIKU.  GPLv2.
 | 
			
		||||
// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6.  GPLv2.
 | 
			
		||||
// Copyright: (C) 2010-2012 Nicolas Palix.  GPLv2.
 | 
			
		||||
// Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6.  GPLv2.
 | 
			
		||||
// Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6.  GPLv2.
 | 
			
		||||
// URL: http://coccinelle.lip6.fr/
 | 
			
		||||
// Comments:
 | 
			
		||||
// Options: -no_includes -include_headers
 | 
			
		||||
 | 
			
		||||
virtual patch
 | 
			
		||||
virtual context
 | 
			
		||||
virtual org
 | 
			
		||||
virtual report
 | 
			
		||||
 | 
			
		||||
@@
 | 
			
		||||
@depends on patch@
 | 
			
		||||
iterator I;
 | 
			
		||||
expression x,E,E1,E2;
 | 
			
		||||
statement S,S1,S2;
 | 
			
		||||
| 
						 | 
				
			
			@ -55,4 +59,36 @@ I(x,...) { <...
 | 
			
		|||
  x != NULL
 | 
			
		||||
+ )
 | 
			
		||||
)
 | 
			
		||||
  ...> }
 | 
			
		||||
  ...> }
 | 
			
		||||
 | 
			
		||||
@r depends on !patch exists@
 | 
			
		||||
iterator I;
 | 
			
		||||
expression x,E;
 | 
			
		||||
position p1,p2;
 | 
			
		||||
@@
 | 
			
		||||
 | 
			
		||||
*I@p1(x,...)
 | 
			
		||||
{ ... when != x = E
 | 
			
		||||
(
 | 
			
		||||
*  x@p2 == NULL
 | 
			
		||||
|
 | 
			
		||||
*  x@p2 != NULL
 | 
			
		||||
)
 | 
			
		||||
  ... when any
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@script:python depends on org@
 | 
			
		||||
p1 << r.p1;
 | 
			
		||||
p2 << r.p2;
 | 
			
		||||
@@
 | 
			
		||||
 | 
			
		||||
cocci.print_main("iterator-bound variable",p1)
 | 
			
		||||
cocci.print_secs("useless NULL test",p2)
 | 
			
		||||
 | 
			
		||||
@script:python depends on report@
 | 
			
		||||
p1 << r.p1;
 | 
			
		||||
p2 << r.p2;
 | 
			
		||||
@@
 | 
			
		||||
 | 
			
		||||
msg = "ERROR: iterator variable bound on line %s cannot be NULL" % (p1[0].line)
 | 
			
		||||
coccilib.report.print_report(p2[0], msg)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,17 +1,20 @@
 | 
			
		|||
/// Find functions that refer to GFP_KERNEL but are called with locks held.
 | 
			
		||||
/// The proposed change of converting the GFP_KERNEL is not necessarily the
 | 
			
		||||
/// correct one.  It may be desired to unlock the lock, or to not call the
 | 
			
		||||
/// function under the lock in the first place.
 | 
			
		||||
//# The proposed change of converting the GFP_KERNEL is not necessarily the
 | 
			
		||||
//# correct one.  It may be desired to unlock the lock, or to not call the
 | 
			
		||||
//# function under the lock in the first place.
 | 
			
		||||
///
 | 
			
		||||
// Confidence: Moderate
 | 
			
		||||
// Copyright: (C) 2010 Nicolas Palix, DIKU.  GPLv2.
 | 
			
		||||
// Copyright: (C) 2010 Julia Lawall, DIKU.  GPLv2.
 | 
			
		||||
// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6.  GPLv2.
 | 
			
		||||
// Copyright: (C) 2012 Nicolas Palix.  GPLv2.
 | 
			
		||||
// Copyright: (C) 2012 Julia Lawall, INRIA/LIP6.  GPLv2.
 | 
			
		||||
// Copyright: (C) 2012 Gilles Muller, INRIA/LiP6.  GPLv2.
 | 
			
		||||
// URL: http://coccinelle.lip6.fr/
 | 
			
		||||
// Comments:
 | 
			
		||||
// Options: -no_includes -include_headers
 | 
			
		||||
 | 
			
		||||
virtual patch
 | 
			
		||||
virtual context
 | 
			
		||||
virtual org
 | 
			
		||||
virtual report
 | 
			
		||||
 | 
			
		||||
@gfp exists@
 | 
			
		||||
identifier fn;
 | 
			
		||||
| 
						 | 
				
			
			@ -32,28 +35,29 @@ fn(...) {
 | 
			
		|||
 ... when any
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@locked@
 | 
			
		||||
@locked exists@
 | 
			
		||||
identifier gfp.fn;
 | 
			
		||||
position p1,p2;
 | 
			
		||||
@@
 | 
			
		||||
 | 
			
		||||
(
 | 
			
		||||
read_lock_irq
 | 
			
		||||
read_lock_irq@p1
 | 
			
		||||
|
 | 
			
		||||
write_lock_irq
 | 
			
		||||
write_lock_irq@p1
 | 
			
		||||
|
 | 
			
		||||
read_lock_irqsave
 | 
			
		||||
read_lock_irqsave@p1
 | 
			
		||||
|
 | 
			
		||||
write_lock_irqsave
 | 
			
		||||
write_lock_irqsave@p1
 | 
			
		||||
|
 | 
			
		||||
spin_lock
 | 
			
		||||
spin_lock@p1
 | 
			
		||||
|
 | 
			
		||||
spin_trylock
 | 
			
		||||
spin_trylock@p1
 | 
			
		||||
|
 | 
			
		||||
spin_lock_irq
 | 
			
		||||
spin_lock_irq@p1
 | 
			
		||||
|
 | 
			
		||||
spin_lock_irqsave
 | 
			
		||||
spin_lock_irqsave@p1
 | 
			
		||||
|
 | 
			
		||||
local_irq_disable
 | 
			
		||||
local_irq_disable@p1
 | 
			
		||||
)
 | 
			
		||||
 (...)
 | 
			
		||||
...  when != read_unlock_irq(...)
 | 
			
		||||
| 
						 | 
				
			
			@ -64,11 +68,38 @@ local_irq_disable
 | 
			
		|||
     when != spin_unlock_irq(...)
 | 
			
		||||
     when != spin_unlock_irqrestore(...)
 | 
			
		||||
     when != local_irq_enable(...)
 | 
			
		||||
fn(...)
 | 
			
		||||
fn@p2(...)
 | 
			
		||||
 | 
			
		||||
@depends on locked@
 | 
			
		||||
@depends on locked && patch@
 | 
			
		||||
position gfp.p;
 | 
			
		||||
@@
 | 
			
		||||
 | 
			
		||||
- GFP_KERNEL@p
 | 
			
		||||
+ GFP_ATOMIC
 | 
			
		||||
 | 
			
		||||
@depends on locked && !patch@
 | 
			
		||||
position gfp.p;
 | 
			
		||||
@@
 | 
			
		||||
 | 
			
		||||
* GFP_KERNEL@p
 | 
			
		||||
 | 
			
		||||
@script:python depends on !patch && org@
 | 
			
		||||
p << gfp.p;
 | 
			
		||||
fn << gfp.fn;
 | 
			
		||||
p1 << locked.p1;
 | 
			
		||||
p2 << locked.p2;
 | 
			
		||||
@@
 | 
			
		||||
 | 
			
		||||
cocci.print_main("lock",p1)
 | 
			
		||||
cocci.print_secs("call",p2)
 | 
			
		||||
cocci.print_secs("GFP_KERNEL",p)
 | 
			
		||||
 | 
			
		||||
@script:python depends on !patch && report@
 | 
			
		||||
p << gfp.p;
 | 
			
		||||
fn << gfp.fn;
 | 
			
		||||
p1 << locked.p1;
 | 
			
		||||
p2 << locked.p2;
 | 
			
		||||
@@
 | 
			
		||||
 | 
			
		||||
msg = "ERROR: function %s called on line %s inside lock on line %s but uses GFP_KERNEL" % (fn,p2[0].line,p1[0].line)
 | 
			
		||||
coccilib.report.print_report(p[0], msg)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,9 +1,9 @@
 | 
			
		|||
/// Find nested lock+irqsave functions that use the same flags variables
 | 
			
		||||
///
 | 
			
		||||
// Confidence: High
 | 
			
		||||
// Copyright: (C) 2010 Nicolas Palix, DIKU.  GPLv2.
 | 
			
		||||
// Copyright: (C) 2010 Julia Lawall, DIKU.  GPLv2.
 | 
			
		||||
// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6.  GPLv2.
 | 
			
		||||
// Copyright: (C) 2010-2012 Nicolas Palix.  GPLv2.
 | 
			
		||||
// Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6.  GPLv2.
 | 
			
		||||
// Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6.  GPLv2.
 | 
			
		||||
// URL: http://coccinelle.lip6.fr/
 | 
			
		||||
// Comments:
 | 
			
		||||
// Options: -no_includes -include_headers
 | 
			
		||||
| 
						 | 
				
			
			@ -12,7 +12,7 @@ virtual context
 | 
			
		|||
virtual org
 | 
			
		||||
virtual report
 | 
			
		||||
 | 
			
		||||
@r@
 | 
			
		||||
@r exists@
 | 
			
		||||
expression lock1,lock2,flags;
 | 
			
		||||
position p1,p2;
 | 
			
		||||
@@
 | 
			
		||||
| 
						 | 
				
			
			@ -39,7 +39,7 @@ read_lock_irqsave@p2(lock2,flags)
 | 
			
		|||
write_lock_irqsave@p2(lock2,flags)
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
@d@
 | 
			
		||||
@d exists@
 | 
			
		||||
expression f <= r.flags;
 | 
			
		||||
expression lock1,lock2,flags;
 | 
			
		||||
position r.p1, r.p2;
 | 
			
		||||
| 
						 | 
				
			
			@ -76,5 +76,5 @@ p1 << r.p1;
 | 
			
		|||
p2 << r.p2;
 | 
			
		||||
@@
 | 
			
		||||
 | 
			
		||||
msg="ERROR: nested lock+irqsave that reuses flags from %s." % (p1[0].line)
 | 
			
		||||
msg="ERROR: nested lock+irqsave that reuses flags from line %s." % (p1[0].line)
 | 
			
		||||
coccilib.report.print_report(p2[0], msg)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -6,13 +6,14 @@
 | 
			
		|||
/// function call that releases the lock.
 | 
			
		||||
///
 | 
			
		||||
// Confidence: Moderate
 | 
			
		||||
// Copyright: (C) 2010 Nicolas Palix, DIKU.  GPLv2.
 | 
			
		||||
// Copyright: (C) 2010 Julia Lawall, DIKU.  GPLv2.
 | 
			
		||||
// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6.  GPLv2.
 | 
			
		||||
// Copyright: (C) 2010-2012 Nicolas Palix.  GPLv2.
 | 
			
		||||
// Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6.  GPLv2.
 | 
			
		||||
// Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6.  GPLv2.
 | 
			
		||||
// URL: http://coccinelle.lip6.fr/
 | 
			
		||||
// Comments:
 | 
			
		||||
// Options: -no_includes -include_headers
 | 
			
		||||
 | 
			
		||||
virtual context
 | 
			
		||||
virtual org
 | 
			
		||||
virtual report
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -57,7 +58,7 @@ position r;
 | 
			
		|||
 | 
			
		||||
for(...;...;...) { <+... return@r ...; ...+> }
 | 
			
		||||
 | 
			
		||||
@err@
 | 
			
		||||
@err exists@
 | 
			
		||||
expression E1;
 | 
			
		||||
position prelocked.p;
 | 
			
		||||
position up != prelocked.p1;
 | 
			
		||||
| 
						 | 
				
			
			@ -65,14 +66,14 @@ position r!=looped.r;
 | 
			
		|||
identifier lock,unlock;
 | 
			
		||||
@@
 | 
			
		||||
 | 
			
		||||
lock(E1@p,...);
 | 
			
		||||
*lock(E1@p,...);
 | 
			
		||||
<+... when != E1
 | 
			
		||||
if (...) {
 | 
			
		||||
  ... when != E1
 | 
			
		||||
  return@r ...;
 | 
			
		||||
*  return@r ...;
 | 
			
		||||
}
 | 
			
		||||
...+>
 | 
			
		||||
unlock@up(E1,...);
 | 
			
		||||
*unlock@up(E1,...);
 | 
			
		||||
 | 
			
		||||
@script:python depends on org@
 | 
			
		||||
p << prelocked.p1;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,9 +3,9 @@
 | 
			
		|||
/// initialization.
 | 
			
		||||
///
 | 
			
		||||
// Confidence: Low
 | 
			
		||||
// Copyright: (C) 2010 Nicolas Palix, DIKU.  GPLv2.
 | 
			
		||||
// Copyright: (C) 2010 Julia Lawall, DIKU.  GPLv2.
 | 
			
		||||
// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6.  GPLv2.
 | 
			
		||||
// Copyright: (C) 2010-2012 Nicolas Palix.  GPLv2.
 | 
			
		||||
// Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6.  GPLv2.
 | 
			
		||||
// Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6.  GPLv2.
 | 
			
		||||
// URL: http://coccinelle.lip6.fr/
 | 
			
		||||
// Comments: requires at least Coccinelle 0.2.4, lex or parse error otherwise
 | 
			
		||||
// Options: -no_includes -include_headers
 | 
			
		||||
| 
						 | 
				
			
			@ -49,5 +49,5 @@ pr << r.p;
 | 
			
		|||
@@
 | 
			
		||||
 | 
			
		||||
if int(ps[0].line) < int(pr[0].line) or (int(ps[0].line) == int(pr[0].line) and int(ps[0].column) < int(pr[0].column)):
 | 
			
		||||
  msg = "%s: first occurrence %s, second occurrence %s" % (fld,ps[0].line,pr[0].line)
 | 
			
		||||
  msg = "%s: first occurrence line %s, second occurrence line %s" % (fld,ps[0].line,pr[0].line)
 | 
			
		||||
  coccilib.report.print_report(p0[0],msg)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,16 +1,19 @@
 | 
			
		|||
/// The various basic memory allocation functions don't return ERR_PTR
 | 
			
		||||
///
 | 
			
		||||
// Confidence: High
 | 
			
		||||
// Copyright: (C) 2010 Nicolas Palix, DIKU.  GPLv2.
 | 
			
		||||
// Copyright: (C) 2010 Julia Lawall, DIKU.  GPLv2.
 | 
			
		||||
// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6.  GPLv2.
 | 
			
		||||
// Copyright: (C) 2010-2012 Nicolas Palix.  GPLv2.
 | 
			
		||||
// Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6.  GPLv2.
 | 
			
		||||
// Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6.  GPLv2.
 | 
			
		||||
// URL: http://coccinelle.lip6.fr/
 | 
			
		||||
// Comments:
 | 
			
		||||
// Options: -no_includes -include_headers
 | 
			
		||||
 | 
			
		||||
virtual patch
 | 
			
		||||
virtual context
 | 
			
		||||
virtual org
 | 
			
		||||
virtual report
 | 
			
		||||
 | 
			
		||||
@@
 | 
			
		||||
@depends on patch@
 | 
			
		||||
expression x,E;
 | 
			
		||||
@@
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -18,3 +21,28 @@ x = \(kmalloc\|kzalloc\|kcalloc\|kmem_cache_alloc\|kmem_cache_zalloc\|kmem_cache
 | 
			
		|||
... when != x = E
 | 
			
		||||
- IS_ERR(x)
 | 
			
		||||
+ !x
 | 
			
		||||
 | 
			
		||||
@r depends on !patch exists@
 | 
			
		||||
expression x,E;
 | 
			
		||||
position p1,p2;
 | 
			
		||||
@@
 | 
			
		||||
 | 
			
		||||
*x = \(kmalloc@p1\|kzalloc@p1\|kcalloc@p1\|kmem_cache_alloc@p1\|kmem_cache_zalloc@p1\|kmem_cache_alloc_node@p1\|kmalloc_node@p1\|kzalloc_node@p1\)(...)
 | 
			
		||||
... when != x = E
 | 
			
		||||
* IS_ERR@p2(x)
 | 
			
		||||
 | 
			
		||||
@script:python depends on org@
 | 
			
		||||
p1 << r.p1;
 | 
			
		||||
p2 << r.p2;
 | 
			
		||||
@@
 | 
			
		||||
 | 
			
		||||
cocci.print_main("alloc call",p1)
 | 
			
		||||
cocci.print_secs("IS_ERR that should be NULL tests",p2)
 | 
			
		||||
 | 
			
		||||
@script:python depends on report@
 | 
			
		||||
p1 << r.p1;
 | 
			
		||||
p2 << r.p2;
 | 
			
		||||
@@
 | 
			
		||||
 | 
			
		||||
msg = "ERROR: allocation function on line %s returns NULL not ERR_PTR on failure" % (p1[0].line)
 | 
			
		||||
coccilib.report.print_report(p2[0], msg)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue