mirror of
https://github.com/AetherDroid/android_kernel_samsung_on5xelte.git
synced 2025-09-08 01:08:03 -04:00
Fixed MTP to work with TWRP
This commit is contained in:
commit
f6dfaef42e
50820 changed files with 20846062 additions and 0 deletions
72
scripts/coccinelle/api/alloc/alloc_cast.cocci
Normal file
72
scripts/coccinelle/api/alloc/alloc_cast.cocci
Normal file
|
@ -0,0 +1,72 @@
|
|||
/// Remove casting the values returned by memory allocation functions
|
||||
/// like kmalloc, kzalloc, kmem_cache_alloc, kmem_cache_zalloc etc.
|
||||
///
|
||||
//# This makes an effort to find cases of casting of values returned by
|
||||
//# kmalloc, kzalloc, kcalloc, kmem_cache_alloc, kmem_cache_zalloc,
|
||||
//# kmem_cache_alloc_node, kmalloc_node and kzalloc_node and removes
|
||||
//# the casting as it is not required. The result in the patch case may
|
||||
//#need some reformatting.
|
||||
//
|
||||
// Confidence: High
|
||||
// Copyright: 2014, Himangi Saraogi GPLv2.
|
||||
// Comments:
|
||||
// Options: --no-includes --include-headers
|
||||
//
|
||||
|
||||
virtual context
|
||||
virtual patch
|
||||
virtual org
|
||||
virtual report
|
||||
|
||||
//----------------------------------------------------------
|
||||
// For context mode
|
||||
//----------------------------------------------------------
|
||||
|
||||
@depends on context@
|
||||
type T;
|
||||
@@
|
||||
|
||||
* (T *)
|
||||
\(kmalloc\|kzalloc\|kcalloc\|kmem_cache_alloc\|kmem_cache_zalloc\|
|
||||
kmem_cache_alloc_node\|kmalloc_node\|kzalloc_node\)(...)
|
||||
|
||||
//----------------------------------------------------------
|
||||
// For patch mode
|
||||
//----------------------------------------------------------
|
||||
|
||||
@depends on patch@
|
||||
type T;
|
||||
@@
|
||||
|
||||
- (T *)
|
||||
(\(kmalloc\|kzalloc\|kcalloc\|kmem_cache_alloc\|kmem_cache_zalloc\|
|
||||
kmem_cache_alloc_node\|kmalloc_node\|kzalloc_node\)(...))
|
||||
|
||||
//----------------------------------------------------------
|
||||
// For org and report mode
|
||||
//----------------------------------------------------------
|
||||
|
||||
@r depends on org || report@
|
||||
type T;
|
||||
position p;
|
||||
@@
|
||||
|
||||
(T@p *)\(kmalloc\|kzalloc\|kcalloc\|kmem_cache_alloc\|kmem_cache_zalloc\|
|
||||
kmem_cache_alloc_node\|kmalloc_node\|kzalloc_node\)(...)
|
||||
|
||||
@script:python depends on org@
|
||||
p << r.p;
|
||||
t << r.T;
|
||||
@@
|
||||
|
||||
coccilib.org.print_safe_todo(p[0], t)
|
||||
|
||||
@script:python depends on report@
|
||||
p << r.p;
|
||||
t << r.T;
|
||||
@@
|
||||
|
||||
msg="WARNING: casting value returned by memory allocation function to (%s *) is useless." % (t)
|
||||
coccilib.report.print_report(p[0], msg)
|
||||
|
||||
|
86
scripts/coccinelle/api/alloc/kzalloc-simple.cocci
Normal file
86
scripts/coccinelle/api/alloc/kzalloc-simple.cocci
Normal file
|
@ -0,0 +1,86 @@
|
|||
///
|
||||
/// Use kzalloc rather than kmalloc followed by memset with 0
|
||||
///
|
||||
/// This considers some simple cases that are common and easy to validate
|
||||
/// Note in particular that there are no ...s in the rule, so all of the
|
||||
/// matched code has to be contiguous
|
||||
///
|
||||
// Confidence: High
|
||||
// Copyright: (C) 2009-2010 Julia Lawall, Nicolas Palix, DIKU. GPLv2.
|
||||
// Copyright: (C) 2009-2010 Gilles Muller, INRIA/LiP6. GPLv2.
|
||||
// URL: http://coccinelle.lip6.fr/rules/kzalloc.html
|
||||
// Options: --no-includes --include-headers
|
||||
//
|
||||
// Keywords: kmalloc, kzalloc
|
||||
// Version min: < 2.6.12 kmalloc
|
||||
// Version min: 2.6.14 kzalloc
|
||||
//
|
||||
|
||||
virtual context
|
||||
virtual patch
|
||||
virtual org
|
||||
virtual report
|
||||
|
||||
//----------------------------------------------------------
|
||||
// For context mode
|
||||
//----------------------------------------------------------
|
||||
|
||||
@depends on context@
|
||||
type T, T2;
|
||||
expression x;
|
||||
expression E1,E2;
|
||||
statement S;
|
||||
@@
|
||||
|
||||
* x = (T)kmalloc(E1,E2);
|
||||
if ((x==NULL) || ...) S
|
||||
* memset((T2)x,0,E1);
|
||||
|
||||
//----------------------------------------------------------
|
||||
// For patch mode
|
||||
//----------------------------------------------------------
|
||||
|
||||
@depends on patch@
|
||||
type T, T2;
|
||||
expression x;
|
||||
expression E1,E2;
|
||||
statement S;
|
||||
@@
|
||||
|
||||
- x = (T)kmalloc(E1,E2);
|
||||
+ x = kzalloc(E1,E2);
|
||||
if ((x==NULL) || ...) S
|
||||
- memset((T2)x,0,E1);
|
||||
|
||||
//----------------------------------------------------------
|
||||
// For org mode
|
||||
//----------------------------------------------------------
|
||||
|
||||
@r depends on org || report@
|
||||
type T, T2;
|
||||
expression x;
|
||||
expression E1,E2;
|
||||
statement S;
|
||||
position p;
|
||||
@@
|
||||
|
||||
x = (T)kmalloc@p(E1,E2);
|
||||
if ((x==NULL) || ...) S
|
||||
memset((T2)x,0,E1);
|
||||
|
||||
@script:python depends on org@
|
||||
p << r.p;
|
||||
x << r.x;
|
||||
@@
|
||||
|
||||
msg="%s" % (x)
|
||||
msg_safe=msg.replace("[","@(").replace("]",")")
|
||||
coccilib.org.print_todo(p[0], msg_safe)
|
||||
|
||||
@script:python depends on report@
|
||||
p << r.p;
|
||||
x << r.x;
|
||||
@@
|
||||
|
||||
msg="WARNING: kzalloc should be used for %s, instead of kmalloc/memset" % (x)
|
||||
coccilib.report.print_report(p[0], msg)
|
80
scripts/coccinelle/api/d_find_alias.cocci
Normal file
80
scripts/coccinelle/api/d_find_alias.cocci
Normal file
|
@ -0,0 +1,80 @@
|
|||
/// Make sure calls to d_find_alias() have a corresponding call to dput().
|
||||
//
|
||||
// Keywords: d_find_alias, dput
|
||||
//
|
||||
// Confidence: Moderate
|
||||
// URL: http://coccinelle.lip6.fr/
|
||||
// Options: --include-headers
|
||||
|
||||
virtual context
|
||||
virtual org
|
||||
virtual patch
|
||||
virtual report
|
||||
|
||||
@r exists@
|
||||
local idexpression struct dentry *dent;
|
||||
expression E, E1;
|
||||
statement S1, S2;
|
||||
position p1, p2;
|
||||
@@
|
||||
(
|
||||
if (!(dent@p1 = d_find_alias(...))) S1
|
||||
|
|
||||
dent@p1 = d_find_alias(...)
|
||||
)
|
||||
|
||||
<...when != dput(dent)
|
||||
when != if (...) { <+... dput(dent) ...+> }
|
||||
when != true !dent || ...
|
||||
when != dent = E
|
||||
when != E = dent
|
||||
if (!dent || ...) S2
|
||||
...>
|
||||
(
|
||||
return <+...dent...+>;
|
||||
|
|
||||
return @p2 ...;
|
||||
|
|
||||
dent@p2 = E1;
|
||||
|
|
||||
E1 = dent;
|
||||
)
|
||||
|
||||
@depends on context@
|
||||
local idexpression struct dentry *r.dent;
|
||||
position r.p1,r.p2;
|
||||
@@
|
||||
* dent@p1 = ...
|
||||
...
|
||||
(
|
||||
* return@p2 ...;
|
||||
|
|
||||
* dent@p2
|
||||
)
|
||||
|
||||
|
||||
@script:python depends on org@
|
||||
p1 << r.p1;
|
||||
p2 << r.p2;
|
||||
@@
|
||||
cocci.print_main("Missing call to dput()",p1)
|
||||
cocci.print_secs("",p2)
|
||||
|
||||
@depends on patch@
|
||||
local idexpression struct dentry *r.dent;
|
||||
position r.p2;
|
||||
@@
|
||||
(
|
||||
+ dput(dent);
|
||||
return @p2 ...;
|
||||
|
|
||||
+ dput(dent);
|
||||
dent@p2 = ...;
|
||||
)
|
||||
|
||||
@script:python depends on report@
|
||||
p1 << r.p1;
|
||||
p2 << r.p2;
|
||||
@@
|
||||
msg = "Missing call to dput() at line %s."
|
||||
coccilib.report.print_report(p1[0], msg % (p2[0].line))
|
56
scripts/coccinelle/api/err_cast.cocci
Normal file
56
scripts/coccinelle/api/err_cast.cocci
Normal file
|
@ -0,0 +1,56 @@
|
|||
///
|
||||
/// Use ERR_CAST inlined function instead of ERR_PTR(PTR_ERR(...))
|
||||
///
|
||||
// Confidence: High
|
||||
// Copyright: (C) 2009, 2010 Nicolas Palix, DIKU. GPLv2.
|
||||
// Copyright: (C) 2009, 2010 Julia Lawall, DIKU. GPLv2.
|
||||
// Copyright: (C) 2009, 2010 Gilles Muller, INRIA/LiP6. GPLv2.
|
||||
// URL: http://coccinelle.lip6.fr/
|
||||
// Options:
|
||||
//
|
||||
// Keywords: ERR_PTR, PTR_ERR, ERR_CAST
|
||||
// Version min: 2.6.25
|
||||
//
|
||||
|
||||
virtual context
|
||||
virtual patch
|
||||
virtual org
|
||||
virtual report
|
||||
|
||||
|
||||
@ depends on context && !patch && !org && !report@
|
||||
expression x;
|
||||
@@
|
||||
|
||||
* ERR_PTR(PTR_ERR(x))
|
||||
|
||||
@ depends on !context && patch && !org && !report @
|
||||
expression x;
|
||||
@@
|
||||
|
||||
- ERR_PTR(PTR_ERR(x))
|
||||
+ ERR_CAST(x)
|
||||
|
||||
@r depends on !context && !patch && (org || report)@
|
||||
expression x;
|
||||
position p;
|
||||
@@
|
||||
|
||||
ERR_PTR@p(PTR_ERR(x))
|
||||
|
||||
@script:python depends on org@
|
||||
p << r.p;
|
||||
x << r.x;
|
||||
@@
|
||||
|
||||
msg="WARNING ERR_CAST can be used with %s" % (x)
|
||||
msg_safe=msg.replace("[","@(").replace("]",")")
|
||||
coccilib.org.print_todo(p[0], msg_safe)
|
||||
|
||||
@script:python depends on report@
|
||||
p << r.p;
|
||||
x << r.x;
|
||||
@@
|
||||
|
||||
msg="WARNING: ERR_CAST can be used with %s" % (x)
|
||||
coccilib.report.print_report(p[0], msg)
|
104
scripts/coccinelle/api/kstrdup.cocci
Normal file
104
scripts/coccinelle/api/kstrdup.cocci
Normal file
|
@ -0,0 +1,104 @@
|
|||
/// Use kstrdup rather than duplicating its implementation
|
||||
///
|
||||
// Confidence: High
|
||||
// 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;
|
||||
@@
|
||||
|
||||
- to = kmalloc(strlen(from) + 1,flag);
|
||||
+ to = kstrdup(from, flag);
|
||||
... when != \(from = E1 \| to = E1 \)
|
||||
if (to==NULL || ...) S
|
||||
... when != \(from = E2 \| to = E2 \)
|
||||
- strcpy(to, from);
|
||||
|
||||
@depends on patch@
|
||||
expression x,from,to;
|
||||
expression flag,E1,E2,E3;
|
||||
statement S;
|
||||
@@
|
||||
|
||||
- x = strlen(from) + 1;
|
||||
... when != \( x = E1 \| from = E1 \)
|
||||
- to = \(kmalloc\|kzalloc\)(x,flag);
|
||||
+ to = kstrdup(from, flag);
|
||||
... when != \(x = E2 \| from = E2 \| to = E2 \)
|
||||
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)
|
66
scripts/coccinelle/api/memdup.cocci
Normal file
66
scripts/coccinelle/api/memdup.cocci
Normal file
|
@ -0,0 +1,66 @@
|
|||
/// Use kmemdup rather than duplicating its implementation
|
||||
///
|
||||
// Confidence: High
|
||||
// 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;
|
||||
expression flag;
|
||||
position p;
|
||||
@@
|
||||
|
||||
to = \(kmalloc@p\|kzalloc@p\)(strlen(from) + 1,flag);
|
||||
|
||||
@r2@
|
||||
expression x,from,to;
|
||||
expression flag,E1;
|
||||
position p;
|
||||
@@
|
||||
|
||||
x = strlen(from) + 1;
|
||||
... 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;
|
||||
@@
|
||||
|
||||
- to = \(kmalloc@p\|kzalloc@p\)(size,flag);
|
||||
+ 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")
|
60
scripts/coccinelle/api/memdup_user.cocci
Normal file
60
scripts/coccinelle/api/memdup_user.cocci
Normal file
|
@ -0,0 +1,60 @@
|
|||
/// Use memdup_user rather than duplicating its implementation
|
||||
/// This is a little bit restricted to reduce false positives
|
||||
///
|
||||
// Confidence: High
|
||||
// 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;
|
||||
identifier l1,l2;
|
||||
@@
|
||||
|
||||
- to = \(kmalloc\|kzalloc\)(size,flag);
|
||||
+ to = memdup_user(from,size);
|
||||
if (
|
||||
- to==NULL
|
||||
+ IS_ERR(to)
|
||||
|| ...) {
|
||||
<+... when != goto l1;
|
||||
- -ENOMEM
|
||||
+ PTR_ERR(to)
|
||||
...+>
|
||||
}
|
||||
- if (copy_from_user(to, from, size) != 0) {
|
||||
- <+... when != goto 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 memdup_user")
|
||||
|
||||
@script:python depends on report@
|
||||
p << r.p;
|
||||
@@
|
||||
|
||||
coccilib.report.print_report(p[0], "WARNING opportunity for memdup_user")
|
109
scripts/coccinelle/api/pm_runtime.cocci
Normal file
109
scripts/coccinelle/api/pm_runtime.cocci
Normal file
|
@ -0,0 +1,109 @@
|
|||
/// Make sure pm_runtime_* calls does not use unnecessary IS_ERR_VALUE
|
||||
//
|
||||
// Keywords: pm_runtime
|
||||
// Confidence: Medium
|
||||
// Copyright (C) 2013 Texas Instruments Incorporated - GPLv2.
|
||||
// URL: http://coccinelle.lip6.fr/
|
||||
// Options: --include-headers
|
||||
|
||||
virtual patch
|
||||
virtual context
|
||||
virtual org
|
||||
virtual report
|
||||
|
||||
//----------------------------------------------------------
|
||||
// Detection
|
||||
//----------------------------------------------------------
|
||||
|
||||
@runtime_bad_err_handle exists@
|
||||
expression ret;
|
||||
@@
|
||||
(
|
||||
ret = \(pm_runtime_idle\|
|
||||
pm_runtime_suspend\|
|
||||
pm_runtime_autosuspend\|
|
||||
pm_runtime_resume\|
|
||||
pm_request_idle\|
|
||||
pm_request_resume\|
|
||||
pm_request_autosuspend\|
|
||||
pm_runtime_get\|
|
||||
pm_runtime_get_sync\|
|
||||
pm_runtime_put\|
|
||||
pm_runtime_put_autosuspend\|
|
||||
pm_runtime_put_sync\|
|
||||
pm_runtime_put_sync_suspend\|
|
||||
pm_runtime_put_sync_autosuspend\|
|
||||
pm_runtime_set_active\|
|
||||
pm_schedule_suspend\|
|
||||
pm_runtime_barrier\|
|
||||
pm_generic_runtime_suspend\|
|
||||
pm_generic_runtime_resume\)(...);
|
||||
...
|
||||
IS_ERR_VALUE(ret)
|
||||
...
|
||||
)
|
||||
|
||||
//----------------------------------------------------------
|
||||
// For context mode
|
||||
//----------------------------------------------------------
|
||||
|
||||
@depends on runtime_bad_err_handle && context@
|
||||
identifier pm_runtime_api;
|
||||
expression ret;
|
||||
@@
|
||||
(
|
||||
ret = pm_runtime_api(...);
|
||||
...
|
||||
* IS_ERR_VALUE(ret)
|
||||
...
|
||||
)
|
||||
|
||||
//----------------------------------------------------------
|
||||
// For patch mode
|
||||
//----------------------------------------------------------
|
||||
|
||||
@depends on runtime_bad_err_handle && patch@
|
||||
identifier pm_runtime_api;
|
||||
expression ret;
|
||||
@@
|
||||
(
|
||||
ret = pm_runtime_api(...);
|
||||
...
|
||||
- IS_ERR_VALUE(ret)
|
||||
+ ret < 0
|
||||
...
|
||||
)
|
||||
|
||||
//----------------------------------------------------------
|
||||
// For org and report mode
|
||||
//----------------------------------------------------------
|
||||
|
||||
@r depends on runtime_bad_err_handle exists@
|
||||
position p1, p2;
|
||||
identifier pm_runtime_api;
|
||||
expression ret;
|
||||
@@
|
||||
(
|
||||
ret = pm_runtime_api@p1(...);
|
||||
...
|
||||
IS_ERR_VALUE@p2(ret)
|
||||
...
|
||||
)
|
||||
|
||||
@script:python depends on org@
|
||||
p1 << r.p1;
|
||||
p2 << r.p2;
|
||||
pm_runtime_api << r.pm_runtime_api;
|
||||
@@
|
||||
|
||||
cocci.print_main(pm_runtime_api,p1)
|
||||
cocci.print_secs("IS_ERR_VALUE",p2)
|
||||
|
||||
@script:python depends on report@
|
||||
p1 << r.p1;
|
||||
p2 << r.p2;
|
||||
pm_runtime_api << r.pm_runtime_api;
|
||||
@@
|
||||
|
||||
msg = "%s returns < 0 as error. Unecessary IS_ERR_VALUE at line %s" % (pm_runtime_api, p2[0].line)
|
||||
coccilib.report.print_report(p1[0],msg)
|
96
scripts/coccinelle/api/ptr_ret.cocci
Normal file
96
scripts/coccinelle/api/ptr_ret.cocci
Normal file
|
@ -0,0 +1,96 @@
|
|||
///
|
||||
/// Use PTR_ERR_OR_ZERO rather than if(IS_ERR(...)) + PTR_ERR
|
||||
///
|
||||
// Confidence: High
|
||||
// Copyright: (C) 2012 Julia Lawall, INRIA/LIP6. GPLv2.
|
||||
// Copyright: (C) 2012 Gilles Muller, INRIA/LiP6. GPLv2.
|
||||
// URL: http://coccinelle.lip6.fr/
|
||||
// Options: --no-includes --include-headers
|
||||
//
|
||||
// Keywords: ERR_PTR, PTR_ERR, PTR_ERR_OR_ZERO
|
||||
// Version min: 2.6.39
|
||||
//
|
||||
|
||||
virtual context
|
||||
virtual patch
|
||||
virtual org
|
||||
virtual report
|
||||
|
||||
@depends on patch@
|
||||
expression ptr;
|
||||
@@
|
||||
|
||||
- if (IS_ERR(ptr)) return PTR_ERR(ptr); else return 0;
|
||||
+ return PTR_ERR_OR_ZERO(ptr);
|
||||
|
||||
@depends on patch@
|
||||
expression ptr;
|
||||
@@
|
||||
|
||||
- if (IS_ERR(ptr)) return PTR_ERR(ptr); return 0;
|
||||
+ return PTR_ERR_OR_ZERO(ptr);
|
||||
|
||||
@depends on patch@
|
||||
expression ptr;
|
||||
@@
|
||||
|
||||
- (IS_ERR(ptr) ? PTR_ERR(ptr) : 0)
|
||||
+ PTR_ERR_OR_ZERO(ptr)
|
||||
|
||||
@r1 depends on !patch@
|
||||
expression ptr;
|
||||
position p1;
|
||||
@@
|
||||
|
||||
* if@p1 (IS_ERR(ptr)) return PTR_ERR(ptr); else return 0;
|
||||
|
||||
@r2 depends on !patch@
|
||||
expression ptr;
|
||||
position p2;
|
||||
@@
|
||||
|
||||
* if@p2 (IS_ERR(ptr)) return PTR_ERR(ptr); return 0;
|
||||
|
||||
@r3 depends on !patch@
|
||||
expression ptr;
|
||||
position p3;
|
||||
@@
|
||||
|
||||
* IS_ERR@p3(ptr) ? PTR_ERR(ptr) : 0
|
||||
|
||||
@script:python depends on org@
|
||||
p << r1.p1;
|
||||
@@
|
||||
|
||||
coccilib.org.print_todo(p[0], "WARNING: PTR_ERR_OR_ZERO can be used")
|
||||
|
||||
|
||||
@script:python depends on org@
|
||||
p << r2.p2;
|
||||
@@
|
||||
|
||||
coccilib.org.print_todo(p[0], "WARNING: PTR_ERR_OR_ZERO can be used")
|
||||
|
||||
@script:python depends on org@
|
||||
p << r3.p3;
|
||||
@@
|
||||
|
||||
coccilib.org.print_todo(p[0], "WARNING: PTR_ERR_OR_ZERO can be used")
|
||||
|
||||
@script:python depends on report@
|
||||
p << r1.p1;
|
||||
@@
|
||||
|
||||
coccilib.report.print_report(p[0], "WARNING: PTR_ERR_OR_ZERO can be used")
|
||||
|
||||
@script:python depends on report@
|
||||
p << r2.p2;
|
||||
@@
|
||||
|
||||
coccilib.report.print_report(p[0], "WARNING: PTR_ERR_OR_ZERO can be used")
|
||||
|
||||
@script:python depends on report@
|
||||
p << r3.p3;
|
||||
@@
|
||||
|
||||
coccilib.report.print_report(p[0], "WARNING: PTR_ERR_OR_ZERO can be used")
|
93
scripts/coccinelle/api/resource_size.cocci
Normal file
93
scripts/coccinelle/api/resource_size.cocci
Normal file
|
@ -0,0 +1,93 @@
|
|||
///
|
||||
/// Use resource_size function on resource object
|
||||
/// instead of explicit computation.
|
||||
///
|
||||
// Confidence: High
|
||||
// Copyright: (C) 2009, 2010 Nicolas Palix, DIKU. GPLv2.
|
||||
// Copyright: (C) 2009, 2010 Julia Lawall, DIKU. GPLv2.
|
||||
// Copyright: (C) 2009, 2010 Gilles Muller, INRIA/LiP6. GPLv2.
|
||||
// URL: http://coccinelle.lip6.fr/
|
||||
// Options:
|
||||
//
|
||||
// Keywords: resource_size
|
||||
// Version min: 2.6.27 resource_size
|
||||
//
|
||||
|
||||
virtual context
|
||||
virtual patch
|
||||
virtual org
|
||||
virtual report
|
||||
|
||||
//----------------------------------------------------------
|
||||
// For context mode
|
||||
//----------------------------------------------------------
|
||||
|
||||
@r_context depends on context && !patch && !org@
|
||||
struct resource *res;
|
||||
@@
|
||||
|
||||
* (res->end - res->start) + 1
|
||||
|
||||
//----------------------------------------------------------
|
||||
// For patch mode
|
||||
//----------------------------------------------------------
|
||||
|
||||
@r_patch depends on !context && patch && !org@
|
||||
struct resource *res;
|
||||
@@
|
||||
|
||||
- (res->end - res->start) + 1
|
||||
+ resource_size(res)
|
||||
|
||||
//----------------------------------------------------------
|
||||
// For org mode
|
||||
//----------------------------------------------------------
|
||||
|
||||
|
||||
@r_org depends on !context && !patch && (org || report)@
|
||||
struct resource *res;
|
||||
position p;
|
||||
@@
|
||||
|
||||
(res->end@p - res->start) + 1
|
||||
|
||||
@rbad_org depends on !context && !patch && (org || report)@
|
||||
struct resource *res;
|
||||
position p != r_org.p;
|
||||
@@
|
||||
|
||||
res->end@p - res->start
|
||||
|
||||
@script:python depends on org@
|
||||
p << r_org.p;
|
||||
x << r_org.res;
|
||||
@@
|
||||
|
||||
msg="ERROR with %s" % (x)
|
||||
msg_safe=msg.replace("[","@(").replace("]",")")
|
||||
coccilib.org.print_todo(p[0], msg_safe)
|
||||
|
||||
@script:python depends on report@
|
||||
p << r_org.p;
|
||||
x << r_org.res;
|
||||
@@
|
||||
|
||||
msg="ERROR: Missing resource_size with %s" % (x)
|
||||
coccilib.report.print_report(p[0], msg)
|
||||
|
||||
@script:python depends on org@
|
||||
p << rbad_org.p;
|
||||
x << rbad_org.res;
|
||||
@@
|
||||
|
||||
msg="WARNING with %s" % (x)
|
||||
msg_safe=msg.replace("[","@(").replace("]",")")
|
||||
coccilib.org.print_todo(p[0], msg_safe)
|
||||
|
||||
@script:python depends on report@
|
||||
p << rbad_org.p;
|
||||
x << rbad_org.res;
|
||||
@@
|
||||
|
||||
msg="WARNING: Suspicious code. resource_size is maybe missing with %s" % (x)
|
||||
coccilib.report.print_report(p[0], msg)
|
70
scripts/coccinelle/api/simple_open.cocci
Normal file
70
scripts/coccinelle/api/simple_open.cocci
Normal file
|
@ -0,0 +1,70 @@
|
|||
/// This removes an open coded simple_open() function
|
||||
/// and replaces file operations references to the function
|
||||
/// with simple_open() instead.
|
||||
///
|
||||
// Confidence: High
|
||||
// Comments:
|
||||
// Options: --no-includes --include-headers
|
||||
|
||||
virtual patch
|
||||
virtual report
|
||||
|
||||
@ open depends on patch @
|
||||
identifier open_f != simple_open;
|
||||
identifier i, f;
|
||||
@@
|
||||
-int open_f(struct inode *i, struct file *f)
|
||||
-{
|
||||
(
|
||||
-if (i->i_private)
|
||||
-f->private_data = i->i_private;
|
||||
|
|
||||
-f->private_data = i->i_private;
|
||||
)
|
||||
-return 0;
|
||||
-}
|
||||
|
||||
@ has_open depends on open @
|
||||
identifier fops;
|
||||
identifier open.open_f;
|
||||
@@
|
||||
struct file_operations fops = {
|
||||
...,
|
||||
-.open = open_f,
|
||||
+.open = simple_open,
|
||||
...
|
||||
};
|
||||
|
||||
@ openr depends on report @
|
||||
identifier open_f != simple_open;
|
||||
identifier i, f;
|
||||
position p;
|
||||
@@
|
||||
int open_f@p(struct inode *i, struct file *f)
|
||||
{
|
||||
(
|
||||
if (i->i_private)
|
||||
f->private_data = i->i_private;
|
||||
|
|
||||
f->private_data = i->i_private;
|
||||
)
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ has_openr depends on openr @
|
||||
identifier fops;
|
||||
identifier openr.open_f;
|
||||
position p;
|
||||
@@
|
||||
struct file_operations fops = {
|
||||
...,
|
||||
.open = open_f@p,
|
||||
...
|
||||
};
|
||||
|
||||
@script:python@
|
||||
pf << openr.p;
|
||||
ps << has_openr.p;
|
||||
@@
|
||||
|
||||
coccilib.report.print_report(pf[0],"WARNING opportunity for simple_open, see also structure on line %s"%(ps[0].line))
|
67
scripts/coccinelle/free/clk_put.cocci
Normal file
67
scripts/coccinelle/free/clk_put.cocci
Normal file
|
@ -0,0 +1,67 @@
|
|||
/// Find missing clk_puts.
|
||||
///
|
||||
//# This only signals a missing clk_put when there is a clk_put later
|
||||
//# in the same function.
|
||||
//# False positives can be due to loops.
|
||||
//
|
||||
// Confidence: Moderate
|
||||
// Copyright: (C) 2012 Julia Lawall, INRIA/LIP6. GPLv2.
|
||||
// Copyright: (C) 2012 Gilles Muller, INRIA/LiP6. GPLv2.
|
||||
// URL: http://coccinelle.lip6.fr/
|
||||
// Comments:
|
||||
// Options:
|
||||
|
||||
virtual context
|
||||
virtual org
|
||||
virtual report
|
||||
|
||||
@clk@
|
||||
expression e;
|
||||
statement S,S1;
|
||||
int ret;
|
||||
position p1,p2,p3;
|
||||
@@
|
||||
|
||||
e = clk_get@p1(...)
|
||||
... when != clk_put(e)
|
||||
if (<+...e...+>) S
|
||||
... when any
|
||||
when != clk_put(e)
|
||||
when != if (...) { ... clk_put(e); ... }
|
||||
(
|
||||
if (ret == 0) S1
|
||||
|
|
||||
if (...)
|
||||
{ ...
|
||||
return 0; }
|
||||
|
|
||||
if (...)
|
||||
{ ...
|
||||
return <+...e...+>; }
|
||||
|
|
||||
*if@p2 (...)
|
||||
{ ... when != clk_put(e)
|
||||
when forall
|
||||
return@p3 ...; }
|
||||
)
|
||||
... when any
|
||||
clk_put(e);
|
||||
|
||||
@script:python depends on org@
|
||||
p1 << clk.p1;
|
||||
p2 << clk.p2;
|
||||
p3 << clk.p3;
|
||||
@@
|
||||
|
||||
cocci.print_main("clk_get",p1)
|
||||
cocci.print_secs("if",p2)
|
||||
cocci.print_secs("needed clk_put",p3)
|
||||
|
||||
@script:python depends on report@
|
||||
p1 << clk.p1;
|
||||
p2 << clk.p2;
|
||||
p3 << clk.p3;
|
||||
@@
|
||||
|
||||
msg = "ERROR: missing clk_put; clk_get on line %s and execution via conditional on line %s" % (p1[0].line,p2[0].line)
|
||||
coccilib.report.print_report(p3[0],msg)
|
71
scripts/coccinelle/free/devm_free.cocci
Normal file
71
scripts/coccinelle/free/devm_free.cocci
Normal file
|
@ -0,0 +1,71 @@
|
|||
/// Find uses of standard freeing functons on values allocated using devm_
|
||||
/// functions. Values allocated using the devm_functions are freed when
|
||||
/// the device is detached, and thus the use of the standard freeing
|
||||
/// function would cause a double free.
|
||||
/// See Documentation/driver-model/devres.txt for more information.
|
||||
///
|
||||
/// A difficulty of detecting this problem is that the standard freeing
|
||||
/// function might be called from a different function than the one
|
||||
/// containing the allocation function. It is thus necessary to make the
|
||||
/// connection between the allocation function and the freeing function.
|
||||
/// Here this is done using the specific argument text, which is prone to
|
||||
/// false positives. There is no rule for the request_region and
|
||||
/// request_mem_region variants because this heuristic seems to be a bit
|
||||
/// less reliable in these cases.
|
||||
///
|
||||
// Confidence: Moderate
|
||||
// Copyright: (C) 2011 Julia Lawall, INRIA/LIP6. GPLv2.
|
||||
// Copyright: (C) 2011 Gilles Muller, INRIA/LiP6. GPLv2.
|
||||
// URL: http://coccinelle.lip6.fr/
|
||||
// Comments:
|
||||
// Options: --no-includes --include-headers
|
||||
|
||||
virtual org
|
||||
virtual report
|
||||
virtual context
|
||||
|
||||
@r depends on context || org || report@
|
||||
expression x;
|
||||
@@
|
||||
|
||||
(
|
||||
x = devm_kzalloc(...)
|
||||
|
|
||||
x = devm_request_irq(...)
|
||||
|
|
||||
x = devm_ioremap(...)
|
||||
|
|
||||
x = devm_ioremap_nocache(...)
|
||||
|
|
||||
x = devm_ioport_map(...)
|
||||
)
|
||||
|
||||
@pb@
|
||||
expression r.x;
|
||||
position p;
|
||||
@@
|
||||
|
||||
(
|
||||
* kfree@p(x)
|
||||
|
|
||||
* free_irq@p(x)
|
||||
|
|
||||
* iounmap@p(x)
|
||||
|
|
||||
* ioport_unmap@p(x)
|
||||
)
|
||||
|
||||
@script:python depends on org@
|
||||
p << pb.p;
|
||||
@@
|
||||
|
||||
msg="WARNING: invalid free of devm_ allocated data"
|
||||
coccilib.org.print_todo(p[0], msg)
|
||||
|
||||
@script:python depends on report@
|
||||
p << pb.p;
|
||||
@@
|
||||
|
||||
msg="WARNING: invalid free of devm_ allocated data"
|
||||
coccilib.report.print_report(p[0], msg)
|
||||
|
53
scripts/coccinelle/free/ifnullfree.cocci
Normal file
53
scripts/coccinelle/free/ifnullfree.cocci
Normal file
|
@ -0,0 +1,53 @@
|
|||
/// NULL check before some freeing functions is not needed.
|
||||
///
|
||||
/// Based on checkpatch warning
|
||||
/// "kfree(NULL) is safe this check is probably not required"
|
||||
/// and kfreeaddr.cocci by Julia Lawall.
|
||||
///
|
||||
// Copyright: (C) 2014 Fabian Frederick. GPLv2.
|
||||
// Comments: -
|
||||
// Options: --no-includes --include-headers
|
||||
|
||||
virtual patch
|
||||
virtual org
|
||||
virtual report
|
||||
virtual context
|
||||
|
||||
@r2 depends on patch@
|
||||
expression E;
|
||||
@@
|
||||
- if (E)
|
||||
(
|
||||
- kfree(E);
|
||||
+ kfree(E);
|
||||
|
|
||||
- debugfs_remove(E);
|
||||
+ debugfs_remove(E);
|
||||
|
|
||||
- debugfs_remove_recursive(E);
|
||||
+ debugfs_remove_recursive(E);
|
||||
|
|
||||
- usb_free_urb(E);
|
||||
+ usb_free_urb(E);
|
||||
)
|
||||
|
||||
@r depends on context || report || org @
|
||||
expression E;
|
||||
position p;
|
||||
@@
|
||||
|
||||
* if (E)
|
||||
* \(kfree@p\|debugfs_remove@p\|debugfs_remove_recursive@p\|usb_free_urb\)(E);
|
||||
|
||||
@script:python depends on org@
|
||||
p << r.p;
|
||||
@@
|
||||
|
||||
cocci.print_main("NULL check before that freeing function is not needed", p)
|
||||
|
||||
@script:python depends on report@
|
||||
p << r.p;
|
||||
@@
|
||||
|
||||
msg = "WARNING: NULL check before freeing functions like kfree, debugfs_remove, debugfs_remove_recursive or usb_free_urb is not needed. Maybe consider reorganizing relevant code to avoid passing NULL values."
|
||||
coccilib.report.print_report(p[0], msg)
|
67
scripts/coccinelle/free/iounmap.cocci
Normal file
67
scripts/coccinelle/free/iounmap.cocci
Normal file
|
@ -0,0 +1,67 @@
|
|||
/// Find missing iounmaps.
|
||||
///
|
||||
//# This only signals a missing iounmap when there is an iounmap later
|
||||
//# in the same function.
|
||||
//# False positives can be due to loops.
|
||||
//
|
||||
// Confidence: Moderate
|
||||
// Copyright: (C) 2012 Julia Lawall, INRIA/LIP6. GPLv2.
|
||||
// Copyright: (C) 2012 Gilles Muller, INRIA/LiP6. GPLv2.
|
||||
// URL: http://coccinelle.lip6.fr/
|
||||
// Comments:
|
||||
// Options:
|
||||
|
||||
virtual context
|
||||
virtual org
|
||||
virtual report
|
||||
|
||||
@iom@
|
||||
expression e;
|
||||
statement S,S1;
|
||||
int ret;
|
||||
position p1,p2,p3;
|
||||
@@
|
||||
|
||||
e = \(ioremap@p1\|ioremap_nocache@p1\)(...)
|
||||
... when != iounmap(e)
|
||||
if (<+...e...+>) S
|
||||
... when any
|
||||
when != iounmap(e)
|
||||
when != if (...) { ... iounmap(e); ... }
|
||||
(
|
||||
if (ret == 0) S1
|
||||
|
|
||||
if (...)
|
||||
{ ...
|
||||
return 0; }
|
||||
|
|
||||
if (...)
|
||||
{ ...
|
||||
return <+...e...+>; }
|
||||
|
|
||||
*if@p2 (...)
|
||||
{ ... when != iounmap(e)
|
||||
when forall
|
||||
return@p3 ...; }
|
||||
)
|
||||
... when any
|
||||
iounmap(e);
|
||||
|
||||
@script:python depends on org@
|
||||
p1 << iom.p1;
|
||||
p2 << iom.p2;
|
||||
p3 << iom.p3;
|
||||
@@
|
||||
|
||||
cocci.print_main("ioremap",p1)
|
||||
cocci.print_secs("if",p2)
|
||||
cocci.print_secs("needed iounmap",p3)
|
||||
|
||||
@script:python depends on report@
|
||||
p1 << iom.p1;
|
||||
p2 << iom.p2;
|
||||
p3 << iom.p3;
|
||||
@@
|
||||
|
||||
msg = "ERROR: missing iounmap; ioremap on line %s and execution via conditional on line %s" % (p1[0].line,p2[0].line)
|
||||
coccilib.report.print_report(p3[0],msg)
|
121
scripts/coccinelle/free/kfree.cocci
Normal file
121
scripts/coccinelle/free/kfree.cocci
Normal file
|
@ -0,0 +1,121 @@
|
|||
/// Find a use after free.
|
||||
//# Values of variables may imply that some
|
||||
//# execution paths are not possible, resulting in false positives.
|
||||
//# Another source of false positives are macros such as
|
||||
//# SCTP_DBG_OBJCNT_DEC that do not actually evaluate their argument
|
||||
///
|
||||
// Confidence: Moderate
|
||||
// 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 org
|
||||
virtual report
|
||||
|
||||
@free@
|
||||
expression E;
|
||||
position p1;
|
||||
@@
|
||||
|
||||
kfree@p1(E)
|
||||
|
||||
@print expression@
|
||||
constant char [] c;
|
||||
expression free.E,E2;
|
||||
type T;
|
||||
position p;
|
||||
identifier f;
|
||||
@@
|
||||
|
||||
(
|
||||
f(...,c,...,(T)E@p,...)
|
||||
|
|
||||
E@p == E2
|
||||
|
|
||||
E@p != E2
|
||||
|
|
||||
E2 == E@p
|
||||
|
|
||||
E2 != E@p
|
||||
|
|
||||
!E@p
|
||||
|
|
||||
E@p || ...
|
||||
)
|
||||
|
||||
@sz@
|
||||
expression free.E;
|
||||
position p;
|
||||
@@
|
||||
|
||||
sizeof(<+...E@p...+>)
|
||||
|
||||
@loop exists@
|
||||
expression E;
|
||||
identifier l;
|
||||
position ok;
|
||||
@@
|
||||
|
||||
while (1) { ...
|
||||
kfree@ok(E)
|
||||
... when != break;
|
||||
when != goto l;
|
||||
when forall
|
||||
}
|
||||
|
||||
@r exists@
|
||||
expression free.E, subE<=free.E, E2;
|
||||
expression E1;
|
||||
iterator iter;
|
||||
statement S;
|
||||
position free.p1!=loop.ok,p2!={print.p,sz.p};
|
||||
@@
|
||||
|
||||
kfree@p1(E,...)
|
||||
...
|
||||
(
|
||||
iter(...,subE,...) S // no use
|
||||
|
|
||||
list_remove_head(E1,subE,...)
|
||||
|
|
||||
subE = E2
|
||||
|
|
||||
subE++
|
||||
|
|
||||
++subE
|
||||
|
|
||||
--subE
|
||||
|
|
||||
subE--
|
||||
|
|
||||
&subE
|
||||
|
|
||||
BUG(...)
|
||||
|
|
||||
BUG_ON(...)
|
||||
|
|
||||
return_VALUE(...)
|
||||
|
|
||||
return_ACPI_STATUS(...)
|
||||
|
|
||||
E@p2 // bad use
|
||||
)
|
||||
|
||||
@script:python depends on org@
|
||||
p1 << free.p1;
|
||||
p2 << r.p2;
|
||||
@@
|
||||
|
||||
cocci.print_main("kfree",p1)
|
||||
cocci.print_secs("ref",p2)
|
||||
|
||||
@script:python depends on report@
|
||||
p1 << free.p1;
|
||||
p2 << r.p2;
|
||||
@@
|
||||
|
||||
msg = "ERROR: reference preceded by free on line %s" % (p1[0].line)
|
||||
coccilib.report.print_report(p2[0],msg)
|
32
scripts/coccinelle/free/kfreeaddr.cocci
Normal file
32
scripts/coccinelle/free/kfreeaddr.cocci
Normal file
|
@ -0,0 +1,32 @@
|
|||
/// Free of a structure field
|
||||
///
|
||||
// Confidence: High
|
||||
// Copyright: (C) 2013 Julia Lawall, INRIA/LIP6. GPLv2.
|
||||
// URL: http://coccinelle.lip6.fr/
|
||||
// Comments:
|
||||
// Options: --no-includes --include-headers
|
||||
|
||||
virtual org
|
||||
virtual report
|
||||
virtual context
|
||||
|
||||
@r depends on context || report || org @
|
||||
expression e;
|
||||
identifier f;
|
||||
position p;
|
||||
@@
|
||||
|
||||
* kfree@p(&e->f)
|
||||
|
||||
@script:python depends on org@
|
||||
p << r.p;
|
||||
@@
|
||||
|
||||
cocci.print_main("kfree",p)
|
||||
|
||||
@script:python depends on report@
|
||||
p << r.p;
|
||||
@@
|
||||
|
||||
msg = "ERROR: kfree of structure field"
|
||||
coccilib.report.print_report(p[0],msg)
|
52
scripts/coccinelle/free/pci_free_consistent.cocci
Normal file
52
scripts/coccinelle/free/pci_free_consistent.cocci
Normal file
|
@ -0,0 +1,52 @@
|
|||
/// Find missing pci_free_consistent for every pci_alloc_consistent.
|
||||
///
|
||||
// Confidence: Moderate
|
||||
// Copyright: (C) 2013 Petr Strnad. GPLv2.
|
||||
// URL: http://coccinelle.lip6.fr/
|
||||
// Keywords: pci_free_consistent, pci_alloc_consistent
|
||||
// Options: --no-includes --include-headers
|
||||
|
||||
virtual report
|
||||
virtual org
|
||||
|
||||
@search@
|
||||
local idexpression id;
|
||||
expression x,y,z,e;
|
||||
position p1,p2;
|
||||
type T;
|
||||
@@
|
||||
|
||||
id = pci_alloc_consistent@p1(x,y,&z)
|
||||
... when != e = id
|
||||
if (id == NULL || ...) { ... return ...; }
|
||||
... when != pci_free_consistent(x,y,id,z)
|
||||
when != if (id) { ... pci_free_consistent(x,y,id,z) ... }
|
||||
when != if (y) { ... pci_free_consistent(x,y,id,z) ... }
|
||||
when != e = (T)id
|
||||
when exists
|
||||
(
|
||||
return 0;
|
||||
|
|
||||
return 1;
|
||||
|
|
||||
return id;
|
||||
|
|
||||
return@p2 ...;
|
||||
)
|
||||
|
||||
@script:python depends on report@
|
||||
p1 << search.p1;
|
||||
p2 << search.p2;
|
||||
@@
|
||||
|
||||
msg = "ERROR: missing pci_free_consistent; pci_alloc_consistent on line %s and return without freeing on line %s" % (p1[0].line,p2[0].line)
|
||||
coccilib.report.print_report(p2[0],msg)
|
||||
|
||||
@script:python depends on org@
|
||||
p1 << search.p1;
|
||||
p2 << search.p2;
|
||||
@@
|
||||
|
||||
msg = "ERROR: missing pci_free_consistent; pci_alloc_consistent on line %s and return without freeing on line %s" % (p1[0].line,p2[0].line)
|
||||
cocci.print_main(msg,p1)
|
||||
cocci.print_secs("",p2)
|
123
scripts/coccinelle/iterators/fen.cocci
Normal file
123
scripts/coccinelle/iterators/fen.cocci
Normal file
|
@ -0,0 +1,123 @@
|
|||
/// These iterators only exit normally when the loop cursor is NULL, so there
|
||||
/// is no point to call of_node_put on the final value.
|
||||
///
|
||||
// Confidence: High
|
||||
// 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;
|
||||
@@
|
||||
|
||||
for_each_node_by_name(np,...) {
|
||||
... when != break;
|
||||
when != goto l;
|
||||
}
|
||||
... when != np = E
|
||||
- of_node_put(np);
|
||||
|
||||
@depends on patch@
|
||||
iterator name for_each_node_by_type;
|
||||
expression np,E;
|
||||
identifier l;
|
||||
@@
|
||||
|
||||
for_each_node_by_type(np,...) {
|
||||
... when != break;
|
||||
when != goto l;
|
||||
}
|
||||
... when != np = E
|
||||
- of_node_put(np);
|
||||
|
||||
@depends on patch@
|
||||
iterator name for_each_compatible_node;
|
||||
expression np,E;
|
||||
identifier l;
|
||||
@@
|
||||
|
||||
for_each_compatible_node(np,...) {
|
||||
... when != break;
|
||||
when != goto l;
|
||||
}
|
||||
... when != np = E
|
||||
- of_node_put(np);
|
||||
|
||||
@depends on patch@
|
||||
iterator name for_each_matching_node;
|
||||
expression np,E;
|
||||
identifier l;
|
||||
@@
|
||||
|
||||
for_each_matching_node(np,...) {
|
||||
... when != break;
|
||||
when != goto l;
|
||||
}
|
||||
... 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)
|
94
scripts/coccinelle/iterators/itnull.cocci
Normal file
94
scripts/coccinelle/iterators/itnull.cocci
Normal file
|
@ -0,0 +1,94 @@
|
|||
/// 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).
|
||||
///
|
||||
// Confidence: Moderate
|
||||
// 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;
|
||||
@@
|
||||
|
||||
I(x,...) { <...
|
||||
(
|
||||
- if (x == NULL && ...) S
|
||||
|
|
||||
- if (x != NULL || ...)
|
||||
S
|
||||
|
|
||||
- (x == NULL) ||
|
||||
E
|
||||
|
|
||||
- (x != NULL) &&
|
||||
E
|
||||
|
|
||||
- (x == NULL && ...) ? E1 :
|
||||
E2
|
||||
|
|
||||
- (x != NULL || ...) ?
|
||||
E1
|
||||
- : E2
|
||||
|
|
||||
- if (x == NULL && ...) S1 else
|
||||
S2
|
||||
|
|
||||
- if (x != NULL || ...)
|
||||
S1
|
||||
- else S2
|
||||
|
|
||||
+ BAD(
|
||||
x == NULL
|
||||
+ )
|
||||
|
|
||||
+ BAD(
|
||||
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)
|
62
scripts/coccinelle/iterators/list_entry_update.cocci
Normal file
62
scripts/coccinelle/iterators/list_entry_update.cocci
Normal file
|
@ -0,0 +1,62 @@
|
|||
/// list_for_each_entry uses its first argument to get from one element of
|
||||
/// the list to the next, so it is usually not a good idea to reassign it.
|
||||
/// The first rule finds such a reassignment and the second rule checks
|
||||
/// that there is a path from the reassignment back to the top of the loop.
|
||||
///
|
||||
// Confidence: High
|
||||
// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2.
|
||||
// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2.
|
||||
// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2.
|
||||
// URL: http://coccinelle.lip6.fr/
|
||||
// Comments:
|
||||
// Options: --no-includes --include-headers
|
||||
|
||||
virtual context
|
||||
virtual org
|
||||
virtual report
|
||||
|
||||
@r@
|
||||
iterator name list_for_each_entry;
|
||||
expression x,E;
|
||||
position p1,p2;
|
||||
@@
|
||||
|
||||
list_for_each_entry@p1(x,...) { <... x =@p2 E ...> }
|
||||
|
||||
@depends on context && !org && !report@
|
||||
expression x,E;
|
||||
position r.p1,r.p2;
|
||||
statement S;
|
||||
@@
|
||||
|
||||
*x =@p2 E
|
||||
...
|
||||
list_for_each_entry@p1(x,...) S
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
@back depends on (org || report) && !context exists@
|
||||
expression x,E;
|
||||
position r.p1,r.p2;
|
||||
statement S;
|
||||
@@
|
||||
|
||||
x =@p2 E
|
||||
...
|
||||
list_for_each_entry@p1(x,...) S
|
||||
|
||||
@script:python depends on back && org@
|
||||
p1 << r.p1;
|
||||
p2 << r.p2;
|
||||
@@
|
||||
|
||||
cocci.print_main("iterator",p1)
|
||||
cocci.print_secs("update",p2)
|
||||
|
||||
@script:python depends on back && report@
|
||||
p1 << r.p1;
|
||||
p2 << r.p2;
|
||||
@@
|
||||
|
||||
msg = "iterator with update on line %s" % (p2[0].line)
|
||||
coccilib.report.print_report(p1[0],msg)
|
147
scripts/coccinelle/iterators/use_after_iter.cocci
Normal file
147
scripts/coccinelle/iterators/use_after_iter.cocci
Normal file
|
@ -0,0 +1,147 @@
|
|||
/// If list_for_each_entry, etc complete a traversal of the list, the iterator
|
||||
/// variable ends up pointing to an address at an offset from the list head,
|
||||
/// and not a meaningful structure. Thus this value should not be used after
|
||||
/// the end of the iterator.
|
||||
//#False positives arise when there is a goto in the iterator and the
|
||||
//#reported reference is at the label of this goto. Some flag tests
|
||||
//#may also cause a report to be a false positive.
|
||||
///
|
||||
// Confidence: Moderate
|
||||
// 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 context
|
||||
virtual org
|
||||
virtual report
|
||||
|
||||
@r exists@
|
||||
identifier c,member;
|
||||
expression E,x;
|
||||
iterator name list_for_each_entry;
|
||||
iterator name list_for_each_entry_reverse;
|
||||
iterator name list_for_each_entry_continue;
|
||||
iterator name list_for_each_entry_continue_reverse;
|
||||
iterator name list_for_each_entry_from;
|
||||
iterator name list_for_each_entry_safe;
|
||||
iterator name list_for_each_entry_safe_continue;
|
||||
iterator name list_for_each_entry_safe_from;
|
||||
iterator name list_for_each_entry_safe_reverse;
|
||||
iterator name hlist_for_each_entry;
|
||||
iterator name hlist_for_each_entry_continue;
|
||||
iterator name hlist_for_each_entry_from;
|
||||
iterator name hlist_for_each_entry_safe;
|
||||
statement S;
|
||||
position p1,p2;
|
||||
@@
|
||||
|
||||
(
|
||||
list_for_each_entry@p1(c,...,member) { ... when != break;
|
||||
when forall
|
||||
when strict
|
||||
}
|
||||
|
|
||||
list_for_each_entry_reverse@p1(c,...,member) { ... when != break;
|
||||
when forall
|
||||
when strict
|
||||
}
|
||||
|
|
||||
list_for_each_entry_continue@p1(c,...,member) { ... when != break;
|
||||
when forall
|
||||
when strict
|
||||
}
|
||||
|
|
||||
list_for_each_entry_continue_reverse@p1(c,...,member) { ... when != break;
|
||||
when forall
|
||||
when strict
|
||||
}
|
||||
|
|
||||
list_for_each_entry_from@p1(c,...,member) { ... when != break;
|
||||
when forall
|
||||
when strict
|
||||
}
|
||||
|
|
||||
list_for_each_entry_safe@p1(c,...,member) { ... when != break;
|
||||
when forall
|
||||
when strict
|
||||
}
|
||||
|
|
||||
list_for_each_entry_safe_continue@p1(c,...,member) { ... when != break;
|
||||
when forall
|
||||
when strict
|
||||
}
|
||||
|
|
||||
list_for_each_entry_safe_from@p1(c,...,member) { ... when != break;
|
||||
when forall
|
||||
when strict
|
||||
}
|
||||
|
|
||||
list_for_each_entry_safe_reverse@p1(c,...,member) { ... when != break;
|
||||
when forall
|
||||
when strict
|
||||
}
|
||||
)
|
||||
...
|
||||
(
|
||||
list_for_each_entry(c,...) S
|
||||
|
|
||||
list_for_each_entry_reverse(c,...) S
|
||||
|
|
||||
list_for_each_entry_continue(c,...) S
|
||||
|
|
||||
list_for_each_entry_continue_reverse(c,...) S
|
||||
|
|
||||
list_for_each_entry_from(c,...) S
|
||||
|
|
||||
list_for_each_entry_safe(c,...) S
|
||||
|
|
||||
list_for_each_entry_safe(x,c,...) S
|
||||
|
|
||||
list_for_each_entry_safe_continue(c,...) S
|
||||
|
|
||||
list_for_each_entry_safe_continue(x,c,...) S
|
||||
|
|
||||
list_for_each_entry_safe_from(c,...) S
|
||||
|
|
||||
list_for_each_entry_safe_from(x,c,...) S
|
||||
|
|
||||
list_for_each_entry_safe_reverse(c,...) S
|
||||
|
|
||||
list_for_each_entry_safe_reverse(x,c,...) S
|
||||
|
|
||||
hlist_for_each_entry(c,...) S
|
||||
|
|
||||
hlist_for_each_entry_continue(c,...) S
|
||||
|
|
||||
hlist_for_each_entry_from(c,...) S
|
||||
|
|
||||
hlist_for_each_entry_safe(c,...) S
|
||||
|
|
||||
list_remove_head(x,c,...)
|
||||
|
|
||||
sizeof(<+...c...+>)
|
||||
|
|
||||
&c->member
|
||||
|
|
||||
c = E
|
||||
|
|
||||
*c@p2
|
||||
)
|
||||
|
||||
@script:python depends on org@
|
||||
p1 << r.p1;
|
||||
p2 << r.p2;
|
||||
@@
|
||||
|
||||
cocci.print_main("invalid iterator index reference",p2)
|
||||
cocci.print_secs("iterator",p1)
|
||||
|
||||
@script:python depends on report@
|
||||
p1 << r.p1;
|
||||
p2 << r.p2;
|
||||
@@
|
||||
|
||||
msg = "ERROR: invalid reference to the index variable of the iterator on line %s" % (p1[0].line)
|
||||
coccilib.report.print_report(p2[0], msg)
|
105
scripts/coccinelle/locks/call_kern.cocci
Normal file
105
scripts/coccinelle/locks/call_kern.cocci
Normal file
|
@ -0,0 +1,105 @@
|
|||
/// 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.
|
||||
///
|
||||
// Confidence: Moderate
|
||||
// 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;
|
||||
position p;
|
||||
@@
|
||||
|
||||
fn(...) {
|
||||
... when != read_unlock_irq(...)
|
||||
when != write_unlock_irq(...)
|
||||
when != read_unlock_irqrestore(...)
|
||||
when != write_unlock_irqrestore(...)
|
||||
when != spin_unlock(...)
|
||||
when != spin_unlock_irq(...)
|
||||
when != spin_unlock_irqrestore(...)
|
||||
when != local_irq_enable(...)
|
||||
when any
|
||||
GFP_KERNEL@p
|
||||
... when any
|
||||
}
|
||||
|
||||
@locked exists@
|
||||
identifier gfp.fn;
|
||||
position p1,p2;
|
||||
@@
|
||||
|
||||
(
|
||||
read_lock_irq@p1
|
||||
|
|
||||
write_lock_irq@p1
|
||||
|
|
||||
read_lock_irqsave@p1
|
||||
|
|
||||
write_lock_irqsave@p1
|
||||
|
|
||||
spin_lock@p1
|
||||
|
|
||||
spin_trylock@p1
|
||||
|
|
||||
spin_lock_irq@p1
|
||||
|
|
||||
spin_lock_irqsave@p1
|
||||
|
|
||||
local_irq_disable@p1
|
||||
)
|
||||
(...)
|
||||
... when != read_unlock_irq(...)
|
||||
when != write_unlock_irq(...)
|
||||
when != read_unlock_irqrestore(...)
|
||||
when != write_unlock_irqrestore(...)
|
||||
when != spin_unlock(...)
|
||||
when != spin_unlock_irq(...)
|
||||
when != spin_unlock_irqrestore(...)
|
||||
when != local_irq_enable(...)
|
||||
fn@p2(...)
|
||||
|
||||
@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)
|
92
scripts/coccinelle/locks/double_lock.cocci
Normal file
92
scripts/coccinelle/locks/double_lock.cocci
Normal file
|
@ -0,0 +1,92 @@
|
|||
/// Find double locks. False positives may occur when some paths cannot
|
||||
/// occur at execution, due to the values of variables, and when there is
|
||||
/// an intervening 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.
|
||||
// URL: http://coccinelle.lip6.fr/
|
||||
// Comments:
|
||||
// Options: --no-includes --include-headers
|
||||
|
||||
virtual org
|
||||
virtual report
|
||||
|
||||
@locked@
|
||||
position p1;
|
||||
expression E1;
|
||||
position p;
|
||||
@@
|
||||
|
||||
(
|
||||
mutex_lock@p1
|
||||
|
|
||||
mutex_trylock@p1
|
||||
|
|
||||
spin_lock@p1
|
||||
|
|
||||
spin_trylock@p1
|
||||
|
|
||||
read_lock@p1
|
||||
|
|
||||
read_trylock@p1
|
||||
|
|
||||
write_lock@p1
|
||||
|
|
||||
write_trylock@p1
|
||||
) (E1@p,...);
|
||||
|
||||
@balanced@
|
||||
position p1 != locked.p1;
|
||||
position locked.p;
|
||||
identifier lock,unlock;
|
||||
expression x <= locked.E1;
|
||||
expression E,locked.E1;
|
||||
expression E2;
|
||||
@@
|
||||
|
||||
if (E) {
|
||||
<+... when != E1
|
||||
lock(E1@p,...)
|
||||
...+>
|
||||
}
|
||||
... when != E1
|
||||
when != \(x = E2\|&x\)
|
||||
when forall
|
||||
if (E) {
|
||||
<+... when != E1
|
||||
unlock@p1(E1,...)
|
||||
...+>
|
||||
}
|
||||
|
||||
@r depends on !balanced exists@
|
||||
expression x <= locked.E1;
|
||||
expression locked.E1;
|
||||
expression E2;
|
||||
identifier lock;
|
||||
position locked.p,p1,p2;
|
||||
@@
|
||||
|
||||
lock@p1 (E1@p,...);
|
||||
... when != E1
|
||||
when != \(x = E2\|&x\)
|
||||
lock@p2 (E1,...);
|
||||
|
||||
@script:python depends on org@
|
||||
p1 << r.p1;
|
||||
p2 << r.p2;
|
||||
lock << r.lock;
|
||||
@@
|
||||
|
||||
cocci.print_main(lock,p1)
|
||||
cocci.print_secs("second lock",p2)
|
||||
|
||||
@script:python depends on report@
|
||||
p1 << r.p1;
|
||||
p2 << r.p2;
|
||||
lock << r.lock;
|
||||
@@
|
||||
|
||||
msg = "second lock on line %s" % (p2[0].line)
|
||||
coccilib.report.print_report(p1[0],msg)
|
80
scripts/coccinelle/locks/flags.cocci
Normal file
80
scripts/coccinelle/locks/flags.cocci
Normal file
|
@ -0,0 +1,80 @@
|
|||
/// Find nested lock+irqsave functions that use the same flags variables
|
||||
///
|
||||
// Confidence: High
|
||||
// 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
|
||||
|
||||
@r exists@
|
||||
expression lock1,lock2,flags;
|
||||
position p1,p2;
|
||||
@@
|
||||
|
||||
(
|
||||
spin_lock_irqsave@p1(lock1,flags)
|
||||
|
|
||||
read_lock_irqsave@p1(lock1,flags)
|
||||
|
|
||||
write_lock_irqsave@p1(lock1,flags)
|
||||
)
|
||||
... when != flags
|
||||
(
|
||||
spin_lock_irqsave(lock1,flags)
|
||||
|
|
||||
read_lock_irqsave(lock1,flags)
|
||||
|
|
||||
write_lock_irqsave(lock1,flags)
|
||||
|
|
||||
spin_lock_irqsave@p2(lock2,flags)
|
||||
|
|
||||
read_lock_irqsave@p2(lock2,flags)
|
||||
|
|
||||
write_lock_irqsave@p2(lock2,flags)
|
||||
)
|
||||
|
||||
@d exists@
|
||||
expression f <= r.flags;
|
||||
expression lock1,lock2,flags;
|
||||
position r.p1, r.p2;
|
||||
@@
|
||||
|
||||
(
|
||||
*spin_lock_irqsave@p1(lock1,flags)
|
||||
|
|
||||
*read_lock_irqsave@p1(lock1,flags)
|
||||
|
|
||||
*write_lock_irqsave@p1(lock1,flags)
|
||||
)
|
||||
... when != f
|
||||
(
|
||||
*spin_lock_irqsave@p2(lock2,flags)
|
||||
|
|
||||
*read_lock_irqsave@p2(lock2,flags)
|
||||
|
|
||||
*write_lock_irqsave@p2(lock2,flags)
|
||||
)
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
@script:python depends on d && org@
|
||||
p1 << r.p1;
|
||||
p2 << r.p2;
|
||||
@@
|
||||
|
||||
cocci.print_main("original lock",p1)
|
||||
cocci.print_secs("nested lock+irqsave that reuses flags",p2)
|
||||
|
||||
@script:python depends on d && report@
|
||||
p1 << r.p1;
|
||||
p2 << r.p2;
|
||||
@@
|
||||
|
||||
msg="ERROR: nested lock+irqsave that reuses flags from line %s." % (p1[0].line)
|
||||
coccilib.report.print_report(p2[0], msg)
|
96
scripts/coccinelle/locks/mini_lock.cocci
Normal file
96
scripts/coccinelle/locks/mini_lock.cocci
Normal file
|
@ -0,0 +1,96 @@
|
|||
/// Find missing unlocks. This semantic match considers the specific case
|
||||
/// where the unlock is missing from an if branch, and there is a lock
|
||||
/// before the if and an unlock after the if. False positives are due to
|
||||
/// cases where the if branch represents a case where the function is
|
||||
/// supposed to exit with the lock held, or where there is some preceding
|
||||
/// function call that releases the lock.
|
||||
///
|
||||
// Confidence: Moderate
|
||||
// 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
|
||||
|
||||
@prelocked@
|
||||
position p1,p;
|
||||
expression E1;
|
||||
@@
|
||||
|
||||
(
|
||||
mutex_lock@p1
|
||||
|
|
||||
mutex_trylock@p1
|
||||
|
|
||||
spin_lock@p1
|
||||
|
|
||||
spin_trylock@p1
|
||||
|
|
||||
read_lock@p1
|
||||
|
|
||||
read_trylock@p1
|
||||
|
|
||||
write_lock@p1
|
||||
|
|
||||
write_trylock@p1
|
||||
|
|
||||
read_lock_irq@p1
|
||||
|
|
||||
write_lock_irq@p1
|
||||
|
|
||||
read_lock_irqsave@p1
|
||||
|
|
||||
write_lock_irqsave@p1
|
||||
|
|
||||
spin_lock_irq@p1
|
||||
|
|
||||
spin_lock_irqsave@p1
|
||||
) (E1@p,...);
|
||||
|
||||
@looped@
|
||||
position r;
|
||||
@@
|
||||
|
||||
for(...;...;...) { <+... return@r ...; ...+> }
|
||||
|
||||
@err exists@
|
||||
expression E1;
|
||||
position prelocked.p;
|
||||
position up != prelocked.p1;
|
||||
position r!=looped.r;
|
||||
identifier lock,unlock;
|
||||
@@
|
||||
|
||||
*lock(E1@p,...);
|
||||
<+... when != E1
|
||||
if (...) {
|
||||
... when != E1
|
||||
* return@r ...;
|
||||
}
|
||||
...+>
|
||||
*unlock@up(E1,...);
|
||||
|
||||
@script:python depends on org@
|
||||
p << prelocked.p1;
|
||||
lock << err.lock;
|
||||
unlock << err.unlock;
|
||||
p2 << err.r;
|
||||
@@
|
||||
|
||||
cocci.print_main(lock,p)
|
||||
cocci.print_secs(unlock,p2)
|
||||
|
||||
@script:python depends on report@
|
||||
p << prelocked.p1;
|
||||
lock << err.lock;
|
||||
unlock << err.unlock;
|
||||
p2 << err.r;
|
||||
@@
|
||||
|
||||
msg = "preceding lock on line %s" % (p[0].line)
|
||||
coccilib.report.print_report(p2[0],msg)
|
87
scripts/coccinelle/misc/array_size.cocci
Normal file
87
scripts/coccinelle/misc/array_size.cocci
Normal file
|
@ -0,0 +1,87 @@
|
|||
/// Use ARRAY_SIZE instead of dividing sizeof array with sizeof an element
|
||||
///
|
||||
//# This makes an effort to find cases where ARRAY_SIZE can be used such as
|
||||
//# where there is a division of sizeof the array by the sizeof its first
|
||||
//# element or by any indexed element or the element type. It replaces the
|
||||
//# division of the two sizeofs by ARRAY_SIZE.
|
||||
//
|
||||
// Confidence: High
|
||||
// Copyright: (C) 2014 Himangi Saraogi. GPLv2.
|
||||
// Comments:
|
||||
// Options: --no-includes --include-headers
|
||||
|
||||
virtual patch
|
||||
virtual context
|
||||
virtual org
|
||||
virtual report
|
||||
|
||||
@i@
|
||||
@@
|
||||
|
||||
#include <linux/kernel.h>
|
||||
|
||||
//----------------------------------------------------------
|
||||
// For context mode
|
||||
//----------------------------------------------------------
|
||||
|
||||
@depends on i&&context@
|
||||
type T;
|
||||
T[] E;
|
||||
@@
|
||||
(
|
||||
* (sizeof(E)/sizeof(*E))
|
||||
|
|
||||
* (sizeof(E)/sizeof(E[...]))
|
||||
|
|
||||
* (sizeof(E)/sizeof(T))
|
||||
)
|
||||
|
||||
//----------------------------------------------------------
|
||||
// For patch mode
|
||||
//----------------------------------------------------------
|
||||
|
||||
@depends on i&&patch@
|
||||
type T;
|
||||
T[] E;
|
||||
@@
|
||||
(
|
||||
- (sizeof(E)/sizeof(*E))
|
||||
+ ARRAY_SIZE(E)
|
||||
|
|
||||
- (sizeof(E)/sizeof(E[...]))
|
||||
+ ARRAY_SIZE(E)
|
||||
|
|
||||
- (sizeof(E)/sizeof(T))
|
||||
+ ARRAY_SIZE(E)
|
||||
)
|
||||
|
||||
//----------------------------------------------------------
|
||||
// For org and report mode
|
||||
//----------------------------------------------------------
|
||||
|
||||
@r@
|
||||
type T;
|
||||
T[] E;
|
||||
position p;
|
||||
@@
|
||||
(
|
||||
(sizeof(E)@p /sizeof(*E))
|
||||
|
|
||||
(sizeof(E)@p /sizeof(E[...]))
|
||||
|
|
||||
(sizeof(E)@p /sizeof(T))
|
||||
)
|
||||
|
||||
@script:python depends on i&&org@
|
||||
p << r.p;
|
||||
@@
|
||||
|
||||
coccilib.org.print_todo(p[0], "WARNING should use ARRAY_SIZE")
|
||||
|
||||
@script:python depends on i&&report@
|
||||
p << r.p;
|
||||
@@
|
||||
|
||||
msg="WARNING: Use ARRAY_SIZE"
|
||||
coccilib.report.print_report(p[0], msg)
|
||||
|
76
scripts/coccinelle/misc/badty.cocci
Normal file
76
scripts/coccinelle/misc/badty.cocci
Normal file
|
@ -0,0 +1,76 @@
|
|||
/// Use ARRAY_SIZE instead of dividing sizeof array with sizeof an element
|
||||
///
|
||||
//# This makes an effort to find cases where the argument to sizeof is wrong
|
||||
//# in memory allocation functions by checking the type of the allocated memory
|
||||
//# when it is a double pointer and ensuring the sizeof argument takes a pointer
|
||||
//# to the the memory being allocated. There are false positives in cases the
|
||||
//# sizeof argument is not used in constructing the return value. The result
|
||||
//# may need some reformatting.
|
||||
//
|
||||
// Confidence: Moderate
|
||||
// Copyright: (C) 2014 Himangi Saraogi. GPLv2.
|
||||
// Comments:
|
||||
// Options:
|
||||
|
||||
virtual patch
|
||||
virtual context
|
||||
virtual org
|
||||
virtual report
|
||||
|
||||
//----------------------------------------------------------
|
||||
// For context mode
|
||||
//----------------------------------------------------------
|
||||
|
||||
@depends on context disable sizeof_type_expr@
|
||||
type T;
|
||||
T **x;
|
||||
@@
|
||||
|
||||
x =
|
||||
<+...sizeof(
|
||||
* T
|
||||
)...+>
|
||||
|
||||
//----------------------------------------------------------
|
||||
// For patch mode
|
||||
//----------------------------------------------------------
|
||||
|
||||
@depends on patch disable sizeof_type_expr@
|
||||
type T;
|
||||
T **x;
|
||||
@@
|
||||
|
||||
x =
|
||||
<+...sizeof(
|
||||
- T
|
||||
+ *x
|
||||
)...+>
|
||||
|
||||
//----------------------------------------------------------
|
||||
// For org and report mode
|
||||
//----------------------------------------------------------
|
||||
|
||||
@r disable sizeof_type_expr@
|
||||
type T;
|
||||
T **x;
|
||||
position p;
|
||||
@@
|
||||
|
||||
x =
|
||||
<+...sizeof(
|
||||
T@p
|
||||
)...+>
|
||||
|
||||
@script:python depends on org@
|
||||
p << r.p;
|
||||
@@
|
||||
|
||||
coccilib.org.print_todo(p[0], "WARNING sizeof argument should be pointer type, not structure type")
|
||||
|
||||
@script:python depends on report@
|
||||
p << r.p;
|
||||
@@
|
||||
|
||||
msg="WARNING: Use correct pointer type argument for sizeof"
|
||||
coccilib.report.print_report(p[0], msg)
|
||||
|
178
scripts/coccinelle/misc/boolinit.cocci
Normal file
178
scripts/coccinelle/misc/boolinit.cocci
Normal file
|
@ -0,0 +1,178 @@
|
|||
/// Bool initializations should use true and false. Bool tests don't need
|
||||
/// comparisons. Based on contributions from Joe Perches, Rusty Russell
|
||||
/// and Bruce W Allan.
|
||||
///
|
||||
// Confidence: High
|
||||
// Copyright: (C) 2012 Julia Lawall, INRIA/LIP6. GPLv2.
|
||||
// Copyright: (C) 2012 Gilles Muller, INRIA/LiP6. GPLv2.
|
||||
// URL: http://coccinelle.lip6.fr/
|
||||
// Options: --include-headers
|
||||
|
||||
virtual patch
|
||||
virtual context
|
||||
virtual org
|
||||
virtual report
|
||||
|
||||
@depends on patch@
|
||||
bool t;
|
||||
symbol true;
|
||||
symbol false;
|
||||
@@
|
||||
|
||||
(
|
||||
- t == true
|
||||
+ t
|
||||
|
|
||||
- true == t
|
||||
+ t
|
||||
|
|
||||
- t != true
|
||||
+ !t
|
||||
|
|
||||
- true != t
|
||||
+ !t
|
||||
|
|
||||
- t == false
|
||||
+ !t
|
||||
|
|
||||
- false == t
|
||||
+ !t
|
||||
|
|
||||
- t != false
|
||||
+ t
|
||||
|
|
||||
- false != t
|
||||
+ t
|
||||
)
|
||||
|
||||
@depends on patch disable is_zero, isnt_zero@
|
||||
bool t;
|
||||
@@
|
||||
|
||||
(
|
||||
- t == 1
|
||||
+ t
|
||||
|
|
||||
- t != 1
|
||||
+ !t
|
||||
|
|
||||
- t == 0
|
||||
+ !t
|
||||
|
|
||||
- t != 0
|
||||
+ t
|
||||
)
|
||||
|
||||
@depends on patch@
|
||||
bool b;
|
||||
@@
|
||||
(
|
||||
b =
|
||||
- 0
|
||||
+ false
|
||||
|
|
||||
b =
|
||||
- 1
|
||||
+ true
|
||||
)
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
@r1 depends on !patch@
|
||||
bool t;
|
||||
position p;
|
||||
@@
|
||||
|
||||
(
|
||||
* t@p == true
|
||||
|
|
||||
* true == t@p
|
||||
|
|
||||
* t@p != true
|
||||
|
|
||||
* true != t@p
|
||||
|
|
||||
* t@p == false
|
||||
|
|
||||
* false == t@p
|
||||
|
|
||||
* t@p != false
|
||||
|
|
||||
* false != t@p
|
||||
)
|
||||
|
||||
@r2 depends on !patch disable is_zero, isnt_zero@
|
||||
bool t;
|
||||
position p;
|
||||
@@
|
||||
|
||||
(
|
||||
* t@p == 1
|
||||
|
|
||||
* t@p != 1
|
||||
|
|
||||
* t@p == 0
|
||||
|
|
||||
* t@p != 0
|
||||
)
|
||||
|
||||
@r3 depends on !patch@
|
||||
bool b;
|
||||
position p1,p2;
|
||||
constant c;
|
||||
@@
|
||||
(
|
||||
*b@p1 = 0
|
||||
|
|
||||
*b@p1 = 1
|
||||
|
|
||||
*b@p2 = c
|
||||
)
|
||||
|
||||
@script:python depends on org@
|
||||
p << r1.p;
|
||||
@@
|
||||
|
||||
cocci.print_main("WARNING: Comparison to bool",p)
|
||||
|
||||
@script:python depends on org@
|
||||
p << r2.p;
|
||||
@@
|
||||
|
||||
cocci.print_main("WARNING: Comparison of bool to 0/1",p)
|
||||
|
||||
@script:python depends on org@
|
||||
p1 << r3.p1;
|
||||
@@
|
||||
|
||||
cocci.print_main("WARNING: Assignment of bool to 0/1",p1)
|
||||
|
||||
@script:python depends on org@
|
||||
p2 << r3.p2;
|
||||
@@
|
||||
|
||||
cocci.print_main("ERROR: Assignment of bool to non-0/1 constant",p2)
|
||||
|
||||
@script:python depends on report@
|
||||
p << r1.p;
|
||||
@@
|
||||
|
||||
coccilib.report.print_report(p[0],"WARNING: Comparison to bool")
|
||||
|
||||
@script:python depends on report@
|
||||
p << r2.p;
|
||||
@@
|
||||
|
||||
coccilib.report.print_report(p[0],"WARNING: Comparison of bool to 0/1")
|
||||
|
||||
@script:python depends on report@
|
||||
p1 << r3.p1;
|
||||
@@
|
||||
|
||||
coccilib.report.print_report(p1[0],"WARNING: Assignment of bool to 0/1")
|
||||
|
||||
@script:python depends on report@
|
||||
p2 << r3.p2;
|
||||
@@
|
||||
|
||||
coccilib.report.print_report(p2[0],"ERROR: Assignment of bool to non-0/1 constant")
|
58
scripts/coccinelle/misc/boolreturn.cocci
Normal file
58
scripts/coccinelle/misc/boolreturn.cocci
Normal file
|
@ -0,0 +1,58 @@
|
|||
/// Return statements in functions returning bool should use
|
||||
/// true/false instead of 1/0.
|
||||
//
|
||||
// Confidence: High
|
||||
// Options: --no-includes --include-headers
|
||||
|
||||
virtual patch
|
||||
virtual report
|
||||
virtual context
|
||||
|
||||
@r1 depends on patch@
|
||||
identifier fn;
|
||||
typedef bool;
|
||||
symbol false;
|
||||
symbol true;
|
||||
@@
|
||||
|
||||
bool fn ( ... )
|
||||
{
|
||||
<...
|
||||
return
|
||||
(
|
||||
- 0
|
||||
+ false
|
||||
|
|
||||
- 1
|
||||
+ true
|
||||
)
|
||||
;
|
||||
...>
|
||||
}
|
||||
|
||||
@r2 depends on report || context@
|
||||
identifier fn;
|
||||
position p;
|
||||
@@
|
||||
|
||||
bool fn ( ... )
|
||||
{
|
||||
<...
|
||||
return
|
||||
(
|
||||
* 0@p
|
||||
|
|
||||
* 1@p
|
||||
)
|
||||
;
|
||||
...>
|
||||
}
|
||||
|
||||
|
||||
@script:python depends on report@
|
||||
p << r2.p;
|
||||
fn << r2.fn;
|
||||
@@
|
||||
|
||||
msg = "WARNING: return of 0/1 in function '%s' with return type bool" % fn
|
||||
coccilib.report.print_report(p[0], msg)
|
62
scripts/coccinelle/misc/bugon.cocci
Normal file
62
scripts/coccinelle/misc/bugon.cocci
Normal file
|
@ -0,0 +1,62 @@
|
|||
/// Use BUG_ON instead of a if condition followed by BUG.
|
||||
///
|
||||
//# This makes an effort to find cases where BUG() follows an if
|
||||
//# condition on an expression and replaces the if condition and BUG()
|
||||
//# with a BUG_ON having the conditional expression of the if statement
|
||||
//# as argument.
|
||||
//
|
||||
// Confidence: High
|
||||
// Copyright: (C) 2014 Himangi Saraogi. GPLv2.
|
||||
// Comments:
|
||||
// Options: --no-includes --include-headers
|
||||
|
||||
virtual patch
|
||||
virtual context
|
||||
virtual org
|
||||
virtual report
|
||||
|
||||
//----------------------------------------------------------
|
||||
// For context mode
|
||||
//----------------------------------------------------------
|
||||
|
||||
@depends on context@
|
||||
expression e;
|
||||
@@
|
||||
|
||||
*if (e) BUG();
|
||||
|
||||
//----------------------------------------------------------
|
||||
// For patch mode
|
||||
//----------------------------------------------------------
|
||||
|
||||
@depends on patch@
|
||||
expression e;
|
||||
@@
|
||||
|
||||
-if (e) BUG();
|
||||
+BUG_ON(e);
|
||||
|
||||
//----------------------------------------------------------
|
||||
// For org and report mode
|
||||
//----------------------------------------------------------
|
||||
|
||||
@r@
|
||||
expression e;
|
||||
position p;
|
||||
@@
|
||||
|
||||
if (e) BUG@p ();
|
||||
|
||||
@script:python depends on org@
|
||||
p << r.p;
|
||||
@@
|
||||
|
||||
coccilib.org.print_todo(p[0], "WARNING use BUG_ON")
|
||||
|
||||
@script:python depends on report@
|
||||
p << r.p;
|
||||
@@
|
||||
|
||||
msg="WARNING: Use BUG_ON"
|
||||
coccilib.report.print_report(p[0], msg)
|
||||
|
41
scripts/coccinelle/misc/cstptr.cocci
Normal file
41
scripts/coccinelle/misc/cstptr.cocci
Normal file
|
@ -0,0 +1,41 @@
|
|||
/// PTR_ERR should be applied before its argument is reassigned, typically
|
||||
/// to NULL
|
||||
///
|
||||
// Confidence: High
|
||||
// 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 org
|
||||
virtual report
|
||||
virtual context
|
||||
|
||||
@r exists@
|
||||
expression e,e1;
|
||||
constant c;
|
||||
position p1,p2;
|
||||
@@
|
||||
|
||||
*e@p1 = c
|
||||
... when != e = e1
|
||||
when != &e
|
||||
when != true IS_ERR(e)
|
||||
*PTR_ERR@p2(e)
|
||||
|
||||
@script:python depends on org@
|
||||
p1 << r.p1;
|
||||
p2 << r.p2;
|
||||
@@
|
||||
|
||||
cocci.print_main("PTR_ERR",p2)
|
||||
cocci.print_secs("assignment",p1)
|
||||
|
||||
@script:python depends on report@
|
||||
p1 << r.p1;
|
||||
p2 << r.p2;
|
||||
@@
|
||||
|
||||
msg = "ERROR: PTR_ERR applied after initialization to constant on line %s" % (p1[0].line)
|
||||
coccilib.report.print_report(p2[0],msg)
|
53
scripts/coccinelle/misc/doubleinit.cocci
Normal file
53
scripts/coccinelle/misc/doubleinit.cocci
Normal file
|
@ -0,0 +1,53 @@
|
|||
/// Find duplicate field initializations. This has a high rate of false
|
||||
/// positives due to #ifdefs, which Coccinelle is not aware of in a structure
|
||||
/// initialization.
|
||||
///
|
||||
// Confidence: Low
|
||||
// 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
|
||||
|
||||
virtual org
|
||||
virtual report
|
||||
|
||||
@r@
|
||||
identifier I, s, fld;
|
||||
position p0,p;
|
||||
expression E;
|
||||
@@
|
||||
|
||||
struct I s =@p0 { ..., .fld@p = E, ...};
|
||||
|
||||
@s@
|
||||
identifier I, s, r.fld;
|
||||
position r.p0,p;
|
||||
expression E;
|
||||
@@
|
||||
|
||||
struct I s =@p0 { ..., .fld@p = E, ...};
|
||||
|
||||
@script:python depends on org@
|
||||
p0 << r.p0;
|
||||
fld << r.fld;
|
||||
ps << s.p;
|
||||
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)):
|
||||
cocci.print_main(fld,p0)
|
||||
cocci.print_secs("s",ps)
|
||||
cocci.print_secs("r",pr)
|
||||
|
||||
@script:python depends on report@
|
||||
p0 << r.p0;
|
||||
fld << r.fld;
|
||||
ps << s.p;
|
||||
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 line %s, second occurrence line %s" % (fld,ps[0].line,pr[0].line)
|
||||
coccilib.report.print_report(p0[0],msg)
|
35
scripts/coccinelle/misc/ifaddr.cocci
Normal file
35
scripts/coccinelle/misc/ifaddr.cocci
Normal file
|
@ -0,0 +1,35 @@
|
|||
/// the address of a variable or field is non-zero is likely always to bo
|
||||
/// non-zero
|
||||
///
|
||||
// Confidence: High
|
||||
// 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 org
|
||||
virtual report
|
||||
virtual context
|
||||
|
||||
@r@
|
||||
expression x;
|
||||
statement S1,S2;
|
||||
position p;
|
||||
@@
|
||||
|
||||
*if@p (&x)
|
||||
S1 else S2
|
||||
|
||||
@script:python depends on org@
|
||||
p << r.p;
|
||||
@@
|
||||
|
||||
cocci.print_main("test of a variable/field address",p)
|
||||
|
||||
@script:python depends on report@
|
||||
p << r.p;
|
||||
@@
|
||||
|
||||
msg = "ERROR: test of a variable/field address"
|
||||
coccilib.report.print_report(p[0],msg)
|
48
scripts/coccinelle/misc/ifcol.cocci
Normal file
48
scripts/coccinelle/misc/ifcol.cocci
Normal file
|
@ -0,0 +1,48 @@
|
|||
/// Find confusingly indented code in or after an if. An if branch should
|
||||
/// be indented. The code following an if should not be indented.
|
||||
/// Sometimes, code after an if that is indented is actually intended to be
|
||||
/// part of the if branch.
|
||||
///
|
||||
/// This has a high rate of false positives, because Coccinelle's column
|
||||
/// calculation does not distinguish between spaces and tabs, so code that
|
||||
/// is not visually aligned may be considered to be in the same column.
|
||||
///
|
||||
// Confidence: Low
|
||||
// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2.
|
||||
// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2.
|
||||
// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2.
|
||||
// URL: http://coccinelle.lip6.fr/
|
||||
// Comments:
|
||||
// Options: --no-includes --include-headers
|
||||
|
||||
virtual org
|
||||
virtual report
|
||||
|
||||
@r disable braces4@
|
||||
position p1,p2;
|
||||
statement S1,S2;
|
||||
@@
|
||||
|
||||
(
|
||||
if (...) { ... }
|
||||
|
|
||||
if (...) S1@p1 S2@p2
|
||||
)
|
||||
|
||||
@script:python depends on org@
|
||||
p1 << r.p1;
|
||||
p2 << r.p2;
|
||||
@@
|
||||
|
||||
if (p1[0].column == p2[0].column):
|
||||
cocci.print_main("branch",p1)
|
||||
cocci.print_secs("after",p2)
|
||||
|
||||
@script:python depends on report@
|
||||
p1 << r.p1;
|
||||
p2 << r.p2;
|
||||
@@
|
||||
|
||||
if (p1[0].column == p2[0].column):
|
||||
msg = "code aligned with following code on line %s" % (p2[0].line)
|
||||
coccilib.report.print_report(p1[0],msg)
|
65
scripts/coccinelle/misc/irqf_oneshot.cocci
Normal file
65
scripts/coccinelle/misc/irqf_oneshot.cocci
Normal file
|
@ -0,0 +1,65 @@
|
|||
/// Make sure threaded IRQs without a primary handler are always request with
|
||||
/// IRQF_ONESHOT
|
||||
///
|
||||
//
|
||||
// Confidence: Good
|
||||
// Comments:
|
||||
// Options: --no-includes
|
||||
|
||||
virtual patch
|
||||
virtual context
|
||||
virtual org
|
||||
virtual report
|
||||
|
||||
@r1@
|
||||
expression irq;
|
||||
expression thread_fn;
|
||||
expression flags;
|
||||
position p;
|
||||
@@
|
||||
request_threaded_irq@p(irq, NULL, thread_fn,
|
||||
(
|
||||
flags | IRQF_ONESHOT
|
||||
|
|
||||
IRQF_ONESHOT
|
||||
)
|
||||
, ...)
|
||||
|
||||
@depends on patch@
|
||||
expression irq;
|
||||
expression thread_fn;
|
||||
expression flags;
|
||||
position p != r1.p;
|
||||
@@
|
||||
request_threaded_irq@p(irq, NULL, thread_fn,
|
||||
(
|
||||
-0
|
||||
+IRQF_ONESHOT
|
||||
|
|
||||
-flags
|
||||
+flags | IRQF_ONESHOT
|
||||
)
|
||||
, ...)
|
||||
|
||||
@depends on context@
|
||||
position p != r1.p;
|
||||
@@
|
||||
*request_threaded_irq@p(...)
|
||||
|
||||
@match depends on report || org@
|
||||
expression irq;
|
||||
position p != r1.p;
|
||||
@@
|
||||
request_threaded_irq@p(irq, NULL, ...)
|
||||
|
||||
@script:python depends on org@
|
||||
p << match.p;
|
||||
@@
|
||||
msg = "ERROR: Threaded IRQ with no primary handler requested without IRQF_ONESHOT"
|
||||
coccilib.org.print_todo(p[0],msg)
|
||||
|
||||
@script:python depends on report@
|
||||
p << match.p;
|
||||
@@
|
||||
msg = "ERROR: Threaded IRQ with no primary handler requested without IRQF_ONESHOT"
|
||||
coccilib.report.print_report(p[0],msg)
|
65
scripts/coccinelle/misc/noderef.cocci
Normal file
65
scripts/coccinelle/misc/noderef.cocci
Normal file
|
@ -0,0 +1,65 @@
|
|||
/// sizeof when applied to a pointer typed expression gives the size of
|
||||
/// the pointer
|
||||
///
|
||||
// Confidence: High
|
||||
// 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 org
|
||||
virtual report
|
||||
virtual context
|
||||
virtual patch
|
||||
|
||||
@depends on patch@
|
||||
expression *x;
|
||||
expression f;
|
||||
type T;
|
||||
@@
|
||||
|
||||
(
|
||||
x = <+... sizeof(
|
||||
- x
|
||||
+ *x
|
||||
) ...+>
|
||||
|
|
||||
f(...,(T)(x),...,sizeof(
|
||||
- x
|
||||
+ *x
|
||||
),...)
|
||||
|
|
||||
f(...,sizeof(x),...,(T)(
|
||||
- x
|
||||
+ *x
|
||||
),...)
|
||||
)
|
||||
|
||||
@r depends on !patch@
|
||||
expression *x;
|
||||
expression f;
|
||||
position p;
|
||||
type T;
|
||||
@@
|
||||
|
||||
(
|
||||
*x = <+... sizeof@p(x) ...+>
|
||||
|
|
||||
*f(...,(T)(x),...,sizeof@p(x),...)
|
||||
|
|
||||
*f(...,sizeof@p(x),...,(T)(x),...)
|
||||
)
|
||||
|
||||
@script:python depends on org@
|
||||
p << r.p;
|
||||
@@
|
||||
|
||||
cocci.print_main("application of sizeof to pointer",p)
|
||||
|
||||
@script:python depends on report@
|
||||
p << r.p;
|
||||
@@
|
||||
|
||||
msg = "ERROR: application of sizeof to pointer"
|
||||
coccilib.report.print_report(p[0],msg)
|
62
scripts/coccinelle/misc/of_table.cocci
Normal file
62
scripts/coccinelle/misc/of_table.cocci
Normal file
|
@ -0,0 +1,62 @@
|
|||
/// Make sure of_device_id tables are NULL terminated
|
||||
//
|
||||
// Keywords: of_table
|
||||
// Confidence: Medium
|
||||
// Options: --include-headers
|
||||
|
||||
virtual patch
|
||||
virtual context
|
||||
virtual org
|
||||
virtual report
|
||||
|
||||
@depends on context@
|
||||
identifier var, arr;
|
||||
expression E;
|
||||
@@
|
||||
struct of_device_id arr[] = {
|
||||
...,
|
||||
{
|
||||
.var = E,
|
||||
* }
|
||||
};
|
||||
|
||||
@depends on patch@
|
||||
identifier var, arr;
|
||||
expression E;
|
||||
@@
|
||||
struct of_device_id arr[] = {
|
||||
...,
|
||||
{
|
||||
.var = E,
|
||||
- }
|
||||
+ },
|
||||
+ { }
|
||||
};
|
||||
|
||||
@r depends on org || report@
|
||||
position p1;
|
||||
identifier var, arr;
|
||||
expression E;
|
||||
@@
|
||||
struct of_device_id arr[] = {
|
||||
...,
|
||||
{
|
||||
.var = E,
|
||||
}
|
||||
@p1
|
||||
};
|
||||
|
||||
@script:python depends on org@
|
||||
p1 << r.p1;
|
||||
arr << r.arr;
|
||||
@@
|
||||
|
||||
cocci.print_main(arr,p1)
|
||||
|
||||
@script:python depends on report@
|
||||
p1 << r.p1;
|
||||
arr << r.arr;
|
||||
@@
|
||||
|
||||
msg = "%s is not NULL terminated at line %s" % (arr, p1[0].line)
|
||||
coccilib.report.print_report(p1[0],msg)
|
55
scripts/coccinelle/misc/orplus.cocci
Normal file
55
scripts/coccinelle/misc/orplus.cocci
Normal file
|
@ -0,0 +1,55 @@
|
|||
/// Check for constants that are added but are used elsewhere as bitmasks
|
||||
/// The results should be checked manually to ensure that the nonzero
|
||||
/// bits in the two constants are actually disjoint.
|
||||
///
|
||||
// Confidence: Moderate
|
||||
// Copyright: (C) 2013 Julia Lawall, INRIA/LIP6. GPLv2.
|
||||
// Copyright: (C) 2013 Gilles Muller, INRIA/LIP6. GPLv2.
|
||||
// URL: http://coccinelle.lip6.fr/
|
||||
// Comments:
|
||||
// Options: --no-includes --include-headers
|
||||
|
||||
virtual org
|
||||
virtual report
|
||||
virtual context
|
||||
|
||||
@r@
|
||||
constant c;
|
||||
identifier i;
|
||||
expression e;
|
||||
@@
|
||||
|
||||
(
|
||||
e | c@i
|
||||
|
|
||||
e & c@i
|
||||
|
|
||||
e |= c@i
|
||||
|
|
||||
e &= c@i
|
||||
)
|
||||
|
||||
@s@
|
||||
constant r.c,c1;
|
||||
identifier i1;
|
||||
position p;
|
||||
@@
|
||||
|
||||
(
|
||||
c1 + c - 1
|
||||
|
|
||||
*c1@i1 +@p c
|
||||
)
|
||||
|
||||
@script:python depends on org@
|
||||
p << s.p;
|
||||
@@
|
||||
|
||||
cocci.print_main("sum of probable bitmasks, consider |",p)
|
||||
|
||||
@script:python depends on report@
|
||||
p << s.p;
|
||||
@@
|
||||
|
||||
msg = "WARNING: sum of probable bitmasks, consider |"
|
||||
coccilib.report.print_report(p[0],msg)
|
66
scripts/coccinelle/misc/returnvar.cocci
Normal file
66
scripts/coccinelle/misc/returnvar.cocci
Normal file
|
@ -0,0 +1,66 @@
|
|||
///
|
||||
/// Removes unneeded variable used to store return value.
|
||||
///
|
||||
// Confidence: Moderate
|
||||
// Copyright: (C) 2012 Peter Senna Tschudin, INRIA/LIP6. GPLv2.
|
||||
// URL: http://coccinelle.lip6.fr/
|
||||
// Comments: Comments on code can be deleted if near code that is removed.
|
||||
// "when strict" can be removed to get more hits, but adds false
|
||||
// positives
|
||||
// Options: --no-includes --include-headers
|
||||
|
||||
virtual patch
|
||||
virtual report
|
||||
virtual context
|
||||
virtual org
|
||||
|
||||
@depends on patch@
|
||||
type T;
|
||||
constant C;
|
||||
identifier ret;
|
||||
@@
|
||||
- T ret = C;
|
||||
... when != ret
|
||||
when strict
|
||||
return
|
||||
- ret
|
||||
+ C
|
||||
;
|
||||
|
||||
@depends on context@
|
||||
type T;
|
||||
constant C;
|
||||
identifier ret;
|
||||
@@
|
||||
* T ret = C;
|
||||
... when != ret
|
||||
when strict
|
||||
* return ret;
|
||||
|
||||
@r1 depends on report || org@
|
||||
type T;
|
||||
constant C;
|
||||
identifier ret;
|
||||
position p1, p2;
|
||||
@@
|
||||
T ret@p1 = C;
|
||||
... when != ret
|
||||
when strict
|
||||
return ret@p2;
|
||||
|
||||
@script:python depends on report@
|
||||
p1 << r1.p1;
|
||||
p2 << r1.p2;
|
||||
C << r1.C;
|
||||
ret << r1.ret;
|
||||
@@
|
||||
coccilib.report.print_report(p1[0], "Unneeded variable: \"" + ret + "\". Return \"" + C + "\" on line " + p2[0].line)
|
||||
|
||||
@script:python depends on org@
|
||||
p1 << r1.p1;
|
||||
p2 << r1.p2;
|
||||
C << r1.C;
|
||||
ret << r1.ret;
|
||||
@@
|
||||
cocci.print_main("unneeded \"" + ret + "\" variable", p1)
|
||||
cocci.print_sec("return " + C + " here", p2)
|
83
scripts/coccinelle/misc/semicolon.cocci
Normal file
83
scripts/coccinelle/misc/semicolon.cocci
Normal file
|
@ -0,0 +1,83 @@
|
|||
///
|
||||
/// Removes unneeded semicolon.
|
||||
///
|
||||
// Confidence: Moderate
|
||||
// Copyright: (C) 2012 Peter Senna Tschudin, INRIA/LIP6. GPLv2.
|
||||
// URL: http://coccinelle.lip6.fr/
|
||||
// Comments: Some false positives on empty default cases in switch statements.
|
||||
// Options: --no-includes --include-headers
|
||||
|
||||
virtual patch
|
||||
virtual report
|
||||
virtual context
|
||||
virtual org
|
||||
|
||||
@r_default@
|
||||
position p;
|
||||
@@
|
||||
switch (...)
|
||||
{
|
||||
default: ...;@p
|
||||
}
|
||||
|
||||
@r_case@
|
||||
position p;
|
||||
@@
|
||||
(
|
||||
switch (...)
|
||||
{
|
||||
case ...:;@p
|
||||
}
|
||||
|
|
||||
switch (...)
|
||||
{
|
||||
case ...:...
|
||||
case ...:;@p
|
||||
}
|
||||
|
|
||||
switch (...)
|
||||
{
|
||||
case ...:...
|
||||
case ...:
|
||||
case ...:;@p
|
||||
}
|
||||
)
|
||||
|
||||
@r1@
|
||||
statement S;
|
||||
position p1;
|
||||
position p != {r_default.p, r_case.p};
|
||||
identifier label;
|
||||
@@
|
||||
(
|
||||
label:;
|
||||
|
|
||||
S@p1;@p
|
||||
)
|
||||
|
||||
@script:python@
|
||||
p << r1.p;
|
||||
p1 << r1.p1;
|
||||
@@
|
||||
if p[0].line != p1[0].line_end:
|
||||
cocci.include_match(False)
|
||||
|
||||
@depends on patch@
|
||||
position r1.p;
|
||||
@@
|
||||
-;@p
|
||||
|
||||
@script:python depends on report@
|
||||
p << r1.p;
|
||||
@@
|
||||
coccilib.report.print_report(p[0],"Unneeded semicolon")
|
||||
|
||||
@depends on context@
|
||||
position r1.p;
|
||||
@@
|
||||
*;@p
|
||||
|
||||
@script:python depends on org@
|
||||
p << r1.p;
|
||||
@@
|
||||
cocci.print_main("Unneeded semicolon",p)
|
180
scripts/coccinelle/misc/simple_return.cocci
Normal file
180
scripts/coccinelle/misc/simple_return.cocci
Normal file
|
@ -0,0 +1,180 @@
|
|||
/// Simplify a trivial if-return sequence. Possibly combine with a
|
||||
/// preceding function call.
|
||||
//
|
||||
// Confidence: High
|
||||
// Copyright: (C) 2014 Julia Lawall, INRIA/LIP6. GPLv2.
|
||||
// Copyright: (C) 2014 Gilles Muller, INRIA/LiP6. GPLv2.
|
||||
// URL: http://coccinelle.lip6.fr/
|
||||
// Comments:
|
||||
// Options: --no-includes --include-headers
|
||||
|
||||
virtual patch
|
||||
virtual context
|
||||
virtual org
|
||||
virtual report
|
||||
|
||||
@r depends on patch@
|
||||
local idexpression e;
|
||||
identifier i,f,fn;
|
||||
@@
|
||||
|
||||
fn(...) { <...
|
||||
- e@i =
|
||||
+ return
|
||||
f(...);
|
||||
-if (i != 0) return i;
|
||||
-return 0;
|
||||
...> }
|
||||
|
||||
@depends on patch@
|
||||
identifier r.i;
|
||||
type t;
|
||||
@@
|
||||
|
||||
-t i;
|
||||
... when != i
|
||||
|
||||
@depends on patch@
|
||||
expression e;
|
||||
@@
|
||||
|
||||
-if (e != 0)
|
||||
return e;
|
||||
-return 0;
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
@s1 depends on context || org || report@
|
||||
local idexpression e;
|
||||
identifier i,f,fn;
|
||||
position p,p1,p2;
|
||||
@@
|
||||
|
||||
fn(...) { <...
|
||||
* e@i@p = f(...);
|
||||
if (\(i@p1 != 0\|i@p2 < 0\))
|
||||
return i;
|
||||
return 0;
|
||||
...> }
|
||||
|
||||
@s2 depends on context || org || report forall@
|
||||
identifier s1.i;
|
||||
type t;
|
||||
position q,s1.p;
|
||||
expression e,f;
|
||||
@@
|
||||
|
||||
* t i@q;
|
||||
... when != i
|
||||
e@p = f(...);
|
||||
|
||||
@s3 depends on context || org || report@
|
||||
expression e;
|
||||
position p1!=s1.p1;
|
||||
position p2!=s1.p2;
|
||||
@@
|
||||
|
||||
*if (\(e@p1 != 0\|e@p2 < 0\))
|
||||
return e;
|
||||
return 0;
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
@script:python depends on org@
|
||||
p << s1.p;
|
||||
p1 << s1.p1;
|
||||
q << s2.q;
|
||||
@@
|
||||
|
||||
cocci.print_main("decl",q)
|
||||
cocci.print_secs("use",p)
|
||||
cocci.include_match(False)
|
||||
|
||||
@script:python depends on org@
|
||||
p << s1.p;
|
||||
p2 << s1.p2;
|
||||
q << s2.q;
|
||||
@@
|
||||
|
||||
cocci.print_main("decl",q)
|
||||
cocci.print_secs("use with questionable test",p)
|
||||
cocci.include_match(False)
|
||||
|
||||
@script:python depends on org@
|
||||
p << s1.p;
|
||||
p1 << s1.p1;
|
||||
@@
|
||||
|
||||
cocci.print_main("use",p)
|
||||
|
||||
@script:python depends on org@
|
||||
p << s1.p;
|
||||
p2 << s1.p2;
|
||||
@@
|
||||
|
||||
cocci.print_main("use with questionable test",p)
|
||||
|
||||
@script:python depends on org@
|
||||
p << s3.p1;
|
||||
@@
|
||||
|
||||
cocci.print_main("test",p)
|
||||
|
||||
@script:python depends on org@
|
||||
p << s3.p2;
|
||||
@@
|
||||
|
||||
cocci.print_main("questionable test",p)
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
@script:python depends on report@
|
||||
p << s1.p;
|
||||
p1 << s1.p1;
|
||||
q << s2.q;
|
||||
@@
|
||||
|
||||
msg = "WARNING: end returns can be simpified and declaration on line %s can be dropped" % (q[0].line)
|
||||
coccilib.report.print_report(p[0],msg)
|
||||
cocci.include_match(False)
|
||||
|
||||
@script:python depends on report@
|
||||
p << s1.p;
|
||||
p1 << s1.p1;
|
||||
q << s2.q
|
||||
;
|
||||
@@
|
||||
|
||||
msg = "WARNING: end returns may be simpified if negative or 0 value and declaration on line %s can be dropped" % (q[0].line)
|
||||
coccilib.report.print_report(p[0],msg)
|
||||
cocci.include_match(False)
|
||||
|
||||
@script:python depends on report@
|
||||
p << s1.p;
|
||||
p1 << s1.p1;
|
||||
@@
|
||||
|
||||
msg = "WARNING: end returns can be simpified"
|
||||
coccilib.report.print_report(p[0],msg)
|
||||
|
||||
@script:python depends on report@
|
||||
p << s1.p;
|
||||
p2 << s1.p2;
|
||||
@@
|
||||
|
||||
msg = "WARNING: end returns can be simpified if negative or 0 value"
|
||||
coccilib.report.print_report(p[0],msg)
|
||||
|
||||
@script:python depends on report@
|
||||
p << s3.p1;
|
||||
@@
|
||||
|
||||
msg = "WARNING: end returns can be simpified"
|
||||
coccilib.report.print_report(p[0],msg)
|
||||
|
||||
@script:python depends on report@
|
||||
p << s3.p2;
|
||||
@@
|
||||
|
||||
msg = "WARNING: end returns can be simpified if tested value is negative or 0"
|
||||
coccilib.report.print_report(p[0],msg)
|
109
scripts/coccinelle/misc/warn.cocci
Normal file
109
scripts/coccinelle/misc/warn.cocci
Normal file
|
@ -0,0 +1,109 @@
|
|||
/// Use WARN(1,...) rather than printk followed by WARN_ON(1)
|
||||
///
|
||||
// Confidence: High
|
||||
// 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
|
||||
|
||||
@bad1@
|
||||
position p;
|
||||
@@
|
||||
|
||||
printk(...);
|
||||
printk@p(...);
|
||||
WARN_ON(1);
|
||||
|
||||
@r1 depends on context || report || org@
|
||||
position p != bad1.p;
|
||||
@@
|
||||
|
||||
printk@p(...);
|
||||
*WARN_ON(1);
|
||||
|
||||
@script:python depends on org@
|
||||
p << r1.p;
|
||||
@@
|
||||
|
||||
cocci.print_main("printk + WARN_ON can be just WARN",p)
|
||||
|
||||
@script:python depends on report@
|
||||
p << r1.p;
|
||||
@@
|
||||
|
||||
msg = "SUGGESTION: printk + WARN_ON can be just WARN"
|
||||
coccilib.report.print_report(p[0],msg)
|
||||
|
||||
@ok1 depends on patch@
|
||||
expression list es;
|
||||
position p != bad1.p;
|
||||
@@
|
||||
|
||||
-printk@p(
|
||||
+WARN(1,
|
||||
es);
|
||||
-WARN_ON(1);
|
||||
|
||||
@depends on patch@
|
||||
expression list ok1.es;
|
||||
@@
|
||||
|
||||
if (...)
|
||||
- {
|
||||
WARN(1,es);
|
||||
- }
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
@bad2@
|
||||
position p;
|
||||
@@
|
||||
|
||||
printk(...);
|
||||
printk@p(...);
|
||||
WARN_ON_ONCE(1);
|
||||
|
||||
@r2 depends on context || report || org@
|
||||
position p != bad1.p;
|
||||
@@
|
||||
|
||||
printk@p(...);
|
||||
*WARN_ON_ONCE(1);
|
||||
|
||||
@script:python depends on org@
|
||||
p << r2.p;
|
||||
@@
|
||||
|
||||
cocci.print_main("printk + WARN_ON_ONCE can be just WARN_ONCE",p)
|
||||
|
||||
@script:python depends on report@
|
||||
p << r2.p;
|
||||
@@
|
||||
|
||||
msg = "SUGGESTION: printk + WARN_ON_ONCE can be just WARN_ONCE"
|
||||
coccilib.report.print_report(p[0],msg)
|
||||
|
||||
@ok2 depends on patch@
|
||||
expression list es;
|
||||
position p != bad2.p;
|
||||
@@
|
||||
|
||||
-printk@p(
|
||||
+WARN_ONCE(1,
|
||||
es);
|
||||
-WARN_ON_ONCE(1);
|
||||
|
||||
@depends on patch@
|
||||
expression list ok2.es;
|
||||
@@
|
||||
|
||||
if (...)
|
||||
- {
|
||||
WARN_ONCE(1,es);
|
||||
- }
|
238
scripts/coccinelle/null/badzero.cocci
Normal file
238
scripts/coccinelle/null/badzero.cocci
Normal file
|
@ -0,0 +1,238 @@
|
|||
/// Compare pointer-typed values to NULL rather than 0
|
||||
///
|
||||
//# This makes an effort to choose between !x and x == NULL. !x is used
|
||||
//# if it has previously been used with the function used to initialize x.
|
||||
//# This relies on type information. More type information can be obtained
|
||||
//# using the option -all_includes and the option -I to specify an
|
||||
//# include path.
|
||||
//
|
||||
// Confidence: High
|
||||
// Copyright: (C) 2012 Julia Lawall, INRIA/LIP6. GPLv2.
|
||||
// Copyright: (C) 2012 Gilles Muller, INRIA/LiP6. GPLv2.
|
||||
// URL: http://coccinelle.lip6.fr/
|
||||
// Comments: Requires Coccinelle version 1.0.0-rc20 or later
|
||||
// Options:
|
||||
|
||||
virtual patch
|
||||
virtual context
|
||||
virtual org
|
||||
virtual report
|
||||
|
||||
@initialize:ocaml@
|
||||
@@
|
||||
let negtable = Hashtbl.create 101
|
||||
|
||||
@depends on patch@
|
||||
expression *E;
|
||||
identifier f;
|
||||
@@
|
||||
|
||||
(
|
||||
(E = f(...)) ==
|
||||
- 0
|
||||
+ NULL
|
||||
|
|
||||
(E = f(...)) !=
|
||||
- 0
|
||||
+ NULL
|
||||
|
|
||||
- 0
|
||||
+ NULL
|
||||
== (E = f(...))
|
||||
|
|
||||
- 0
|
||||
+ NULL
|
||||
!= (E = f(...))
|
||||
)
|
||||
|
||||
|
||||
@t1 depends on !patch@
|
||||
expression *E;
|
||||
identifier f;
|
||||
position p;
|
||||
@@
|
||||
|
||||
(
|
||||
(E = f(...)) ==
|
||||
* 0@p
|
||||
|
|
||||
(E = f(...)) !=
|
||||
* 0@p
|
||||
|
|
||||
* 0@p
|
||||
== (E = f(...))
|
||||
|
|
||||
* 0@p
|
||||
!= (E = f(...))
|
||||
)
|
||||
|
||||
@script:python depends on org@
|
||||
p << t1.p;
|
||||
@@
|
||||
|
||||
coccilib.org.print_todo(p[0], "WARNING comparing pointer to 0")
|
||||
|
||||
@script:python depends on report@
|
||||
p << t1.p;
|
||||
@@
|
||||
|
||||
coccilib.report.print_report(p[0], "WARNING comparing pointer to 0")
|
||||
|
||||
// Tests of returned values
|
||||
|
||||
@s@
|
||||
identifier f;
|
||||
expression E,E1;
|
||||
@@
|
||||
|
||||
E = f(...)
|
||||
... when != E = E1
|
||||
!E
|
||||
|
||||
@script:ocaml depends on s@
|
||||
f << s.f;
|
||||
@@
|
||||
|
||||
try let _ = Hashtbl.find negtable f in ()
|
||||
with Not_found -> Hashtbl.add negtable f ()
|
||||
|
||||
@ r disable is_zero,isnt_zero exists @
|
||||
expression *E;
|
||||
identifier f;
|
||||
@@
|
||||
|
||||
E = f(...)
|
||||
...
|
||||
(E == 0
|
||||
|E != 0
|
||||
|0 == E
|
||||
|0 != E
|
||||
)
|
||||
|
||||
@script:ocaml@
|
||||
f << r.f;
|
||||
@@
|
||||
|
||||
try let _ = Hashtbl.find negtable f in ()
|
||||
with Not_found -> include_match false
|
||||
|
||||
// This rule may lead to inconsistent path problems, if E is defined in two
|
||||
// places
|
||||
@ depends on patch disable is_zero,isnt_zero @
|
||||
expression *E;
|
||||
expression E1;
|
||||
identifier r.f;
|
||||
@@
|
||||
|
||||
E = f(...)
|
||||
<...
|
||||
(
|
||||
- E == 0
|
||||
+ !E
|
||||
|
|
||||
- E != 0
|
||||
+ E
|
||||
|
|
||||
- 0 == E
|
||||
+ !E
|
||||
|
|
||||
- 0 != E
|
||||
+ E
|
||||
)
|
||||
...>
|
||||
?E = E1
|
||||
|
||||
@t2 depends on !patch disable is_zero,isnt_zero @
|
||||
expression *E;
|
||||
expression E1;
|
||||
identifier r.f;
|
||||
position p1;
|
||||
position p2;
|
||||
@@
|
||||
|
||||
E = f(...)
|
||||
<...
|
||||
(
|
||||
* E == 0@p1
|
||||
|
|
||||
* E != 0@p2
|
||||
|
|
||||
* 0@p1 == E
|
||||
|
|
||||
* 0@p1 != E
|
||||
)
|
||||
...>
|
||||
?E = E1
|
||||
|
||||
@script:python depends on org@
|
||||
p << t2.p1;
|
||||
@@
|
||||
|
||||
coccilib.org.print_todo(p[0], "WARNING comparing pointer to 0, suggest !E")
|
||||
|
||||
@script:python depends on org@
|
||||
p << t2.p2;
|
||||
@@
|
||||
|
||||
coccilib.org.print_todo(p[0], "WARNING comparing pointer to 0")
|
||||
|
||||
@script:python depends on report@
|
||||
p << t2.p1;
|
||||
@@
|
||||
|
||||
coccilib.report.print_report(p[0], "WARNING comparing pointer to 0, suggest !E")
|
||||
|
||||
@script:python depends on report@
|
||||
p << t2.p2;
|
||||
@@
|
||||
|
||||
coccilib.report.print_report(p[0], "WARNING comparing pointer to 0")
|
||||
|
||||
@ depends on patch disable is_zero,isnt_zero @
|
||||
expression *E;
|
||||
@@
|
||||
|
||||
(
|
||||
E ==
|
||||
- 0
|
||||
+ NULL
|
||||
|
|
||||
E !=
|
||||
- 0
|
||||
+ NULL
|
||||
|
|
||||
- 0
|
||||
+ NULL
|
||||
== E
|
||||
|
|
||||
- 0
|
||||
+ NULL
|
||||
!= E
|
||||
)
|
||||
|
||||
@ t3 depends on !patch disable is_zero,isnt_zero @
|
||||
expression *E;
|
||||
position p;
|
||||
@@
|
||||
|
||||
(
|
||||
* E == 0@p
|
||||
|
|
||||
* E != 0@p
|
||||
|
|
||||
* 0@p == E
|
||||
|
|
||||
* 0@p != E
|
||||
)
|
||||
|
||||
@script:python depends on org@
|
||||
p << t3.p;
|
||||
@@
|
||||
|
||||
coccilib.org.print_todo(p[0], "WARNING comparing pointer to 0")
|
||||
|
||||
@script:python depends on report@
|
||||
p << t3.p;
|
||||
@@
|
||||
|
||||
coccilib.report.print_report(p[0], "WARNING comparing pointer to 0")
|
282
scripts/coccinelle/null/deref_null.cocci
Normal file
282
scripts/coccinelle/null/deref_null.cocci
Normal file
|
@ -0,0 +1,282 @@
|
|||
///
|
||||
/// A variable is dereference under a NULL test.
|
||||
/// Even though it is know to be NULL.
|
||||
///
|
||||
// Confidence: Moderate
|
||||
// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2.
|
||||
// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2.
|
||||
// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2.
|
||||
// URL: http://coccinelle.lip6.fr/
|
||||
// Comments: -I ... -all_includes can give more complete results
|
||||
// Options:
|
||||
|
||||
virtual context
|
||||
virtual org
|
||||
virtual report
|
||||
|
||||
@ifm@
|
||||
expression *E;
|
||||
statement S1,S2;
|
||||
position p1;
|
||||
@@
|
||||
|
||||
if@p1 ((E == NULL && ...) || ...) S1 else S2
|
||||
|
||||
// The following two rules are separate, because both can match a single
|
||||
// expression in different ways
|
||||
@pr1 expression@
|
||||
expression *ifm.E;
|
||||
identifier f;
|
||||
position p1;
|
||||
@@
|
||||
|
||||
(E != NULL && ...) ? <+...E->f@p1...+> : ...
|
||||
|
||||
@pr2 expression@
|
||||
expression *ifm.E;
|
||||
identifier f;
|
||||
position p2;
|
||||
@@
|
||||
|
||||
(
|
||||
(E != NULL) && ... && <+...E->f@p2...+>
|
||||
|
|
||||
(E == NULL) || ... || <+...E->f@p2...+>
|
||||
|
|
||||
sizeof(<+...E->f@p2...+>)
|
||||
)
|
||||
|
||||
// For org and report modes
|
||||
|
||||
@r depends on !context && (org || report) exists@
|
||||
expression subE <= ifm.E;
|
||||
expression *ifm.E;
|
||||
expression E1,E2;
|
||||
identifier f;
|
||||
statement S1,S2,S3,S4;
|
||||
iterator iter;
|
||||
position p!={pr1.p1,pr2.p2};
|
||||
position ifm.p1;
|
||||
@@
|
||||
|
||||
if@p1 ((E == NULL && ...) || ...)
|
||||
{
|
||||
... when != if (...) S1 else S2
|
||||
(
|
||||
iter(subE,...) S4 // no use
|
||||
|
|
||||
list_remove_head(E2,subE,...)
|
||||
|
|
||||
subE = E1
|
||||
|
|
||||
for(subE = E1;...;...) S4
|
||||
|
|
||||
subE++
|
||||
|
|
||||
++subE
|
||||
|
|
||||
--subE
|
||||
|
|
||||
subE--
|
||||
|
|
||||
&subE
|
||||
|
|
||||
E->f@p // bad use
|
||||
)
|
||||
... when any
|
||||
return ...;
|
||||
}
|
||||
else S3
|
||||
|
||||
@script:python depends on !context && !org && report@
|
||||
p << r.p;
|
||||
p1 << ifm.p1;
|
||||
x << ifm.E;
|
||||
@@
|
||||
|
||||
msg="ERROR: %s is NULL but dereferenced." % (x)
|
||||
coccilib.report.print_report(p[0], msg)
|
||||
cocci.include_match(False)
|
||||
|
||||
@script:python depends on !context && org && !report@
|
||||
p << r.p;
|
||||
p1 << ifm.p1;
|
||||
x << ifm.E;
|
||||
@@
|
||||
|
||||
msg="ERROR: %s is NULL but dereferenced." % (x)
|
||||
msg_safe=msg.replace("[","@(").replace("]",")")
|
||||
cocci.print_main(msg_safe,p)
|
||||
cocci.include_match(False)
|
||||
|
||||
@s depends on !context && (org || report) exists@
|
||||
expression subE <= ifm.E;
|
||||
expression *ifm.E;
|
||||
expression E1,E2;
|
||||
identifier f;
|
||||
statement S1,S2,S3,S4;
|
||||
iterator iter;
|
||||
position p!={pr1.p1,pr2.p2};
|
||||
position ifm.p1;
|
||||
@@
|
||||
|
||||
if@p1 ((E == NULL && ...) || ...)
|
||||
{
|
||||
... when != if (...) S1 else S2
|
||||
(
|
||||
iter(subE,...) S4 // no use
|
||||
|
|
||||
list_remove_head(E2,subE,...)
|
||||
|
|
||||
subE = E1
|
||||
|
|
||||
for(subE = E1;...;...) S4
|
||||
|
|
||||
subE++
|
||||
|
|
||||
++subE
|
||||
|
|
||||
--subE
|
||||
|
|
||||
subE--
|
||||
|
|
||||
&subE
|
||||
|
|
||||
E->f@p // bad use
|
||||
)
|
||||
... when any
|
||||
}
|
||||
else S3
|
||||
|
||||
@script:python depends on !context && !org && report@
|
||||
p << s.p;
|
||||
p1 << ifm.p1;
|
||||
x << ifm.E;
|
||||
@@
|
||||
|
||||
msg="ERROR: %s is NULL but dereferenced." % (x)
|
||||
coccilib.report.print_report(p[0], msg)
|
||||
|
||||
@script:python depends on !context && org && !report@
|
||||
p << s.p;
|
||||
p1 << ifm.p1;
|
||||
x << ifm.E;
|
||||
@@
|
||||
|
||||
msg="ERROR: %s is NULL but dereferenced." % (x)
|
||||
msg_safe=msg.replace("[","@(").replace("]",")")
|
||||
cocci.print_main(msg_safe,p)
|
||||
|
||||
// For context mode
|
||||
|
||||
@depends on context && !org && !report exists@
|
||||
expression subE <= ifm.E;
|
||||
expression *ifm.E;
|
||||
expression E1,E2;
|
||||
identifier f;
|
||||
statement S1,S2,S3,S4;
|
||||
iterator iter;
|
||||
position p!={pr1.p1,pr2.p2};
|
||||
position ifm.p1;
|
||||
@@
|
||||
|
||||
if@p1 ((E == NULL && ...) || ...)
|
||||
{
|
||||
... when != if (...) S1 else S2
|
||||
(
|
||||
iter(subE,...) S4 // no use
|
||||
|
|
||||
list_remove_head(E2,subE,...)
|
||||
|
|
||||
subE = E1
|
||||
|
|
||||
for(subE = E1;...;...) S4
|
||||
|
|
||||
subE++
|
||||
|
|
||||
++subE
|
||||
|
|
||||
--subE
|
||||
|
|
||||
subE--
|
||||
|
|
||||
&subE
|
||||
|
|
||||
* E->f@p // bad use
|
||||
)
|
||||
... when any
|
||||
return ...;
|
||||
}
|
||||
else S3
|
||||
|
||||
// The following three rules are duplicates of ifm, pr1 and pr2 respectively.
|
||||
// It is need because the previous rule as already made a "change".
|
||||
|
||||
@ifm1@
|
||||
expression *E;
|
||||
statement S1,S2;
|
||||
position p1;
|
||||
@@
|
||||
|
||||
if@p1 ((E == NULL && ...) || ...) S1 else S2
|
||||
|
||||
@pr11 expression@
|
||||
expression *ifm1.E;
|
||||
identifier f;
|
||||
position p1;
|
||||
@@
|
||||
|
||||
(E != NULL && ...) ? <+...E->f@p1...+> : ...
|
||||
|
||||
@pr12 expression@
|
||||
expression *ifm1.E;
|
||||
identifier f;
|
||||
position p2;
|
||||
@@
|
||||
|
||||
(
|
||||
(E != NULL) && ... && <+...E->f@p2...+>
|
||||
|
|
||||
(E == NULL) || ... || <+...E->f@p2...+>
|
||||
|
|
||||
sizeof(<+...E->f@p2...+>)
|
||||
)
|
||||
|
||||
@depends on context && !org && !report exists@
|
||||
expression subE <= ifm1.E;
|
||||
expression *ifm1.E;
|
||||
expression E1,E2;
|
||||
identifier f;
|
||||
statement S1,S2,S3,S4;
|
||||
iterator iter;
|
||||
position p!={pr11.p1,pr12.p2};
|
||||
position ifm1.p1;
|
||||
@@
|
||||
|
||||
if@p1 ((E == NULL && ...) || ...)
|
||||
{
|
||||
... when != if (...) S1 else S2
|
||||
(
|
||||
iter(subE,...) S4 // no use
|
||||
|
|
||||
list_remove_head(E2,subE,...)
|
||||
|
|
||||
subE = E1
|
||||
|
|
||||
for(subE = E1;...;...) S4
|
||||
|
|
||||
subE++
|
||||
|
|
||||
++subE
|
||||
|
|
||||
--subE
|
||||
|
|
||||
subE--
|
||||
|
|
||||
&subE
|
||||
|
|
||||
* E->f@p // bad use
|
||||
)
|
||||
... when any
|
||||
}
|
||||
else S3
|
48
scripts/coccinelle/null/eno.cocci
Normal file
48
scripts/coccinelle/null/eno.cocci
Normal file
|
@ -0,0 +1,48 @@
|
|||
/// The various basic memory allocation functions don't return ERR_PTR
|
||||
///
|
||||
// Confidence: High
|
||||
// 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;
|
||||
@@
|
||||
|
||||
x = \(kmalloc\|kzalloc\|kcalloc\|kmem_cache_alloc\|kmem_cache_zalloc\|kmem_cache_alloc_node\|kmalloc_node\|kzalloc_node\)(...)
|
||||
... 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)
|
72
scripts/coccinelle/null/kmerr.cocci
Normal file
72
scripts/coccinelle/null/kmerr.cocci
Normal file
|
@ -0,0 +1,72 @@
|
|||
/// This semantic patch looks for kmalloc etc that are not followed by a
|
||||
/// NULL check. It only gives a report in the case where there is some
|
||||
/// error handling code later in the function, which may be helpful
|
||||
/// in determining what the error handling code for the call to kmalloc etc
|
||||
/// should be.
|
||||
///
|
||||
// Confidence: High
|
||||
// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2.
|
||||
// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2.
|
||||
// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2.
|
||||
// URL: http://coccinelle.lip6.fr/
|
||||
// Comments:
|
||||
// Options: --no-includes --include-headers
|
||||
|
||||
virtual context
|
||||
virtual org
|
||||
virtual report
|
||||
|
||||
@withtest@
|
||||
expression x;
|
||||
position p;
|
||||
identifier f,fld;
|
||||
@@
|
||||
|
||||
x@p = f(...);
|
||||
... when != x->fld
|
||||
\(x == NULL \| x != NULL\)
|
||||
|
||||
@fixed depends on context && !org && !report@
|
||||
expression x,x1;
|
||||
position p1 != withtest.p;
|
||||
statement S;
|
||||
position any withtest.p;
|
||||
identifier f;
|
||||
@@
|
||||
|
||||
*x@p1 = \(kmalloc\|kzalloc\|kcalloc\)(...);
|
||||
...
|
||||
*x1@p = f(...);
|
||||
if (!x1) S
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
@rfixed depends on (org || report) && !context exists@
|
||||
expression x,x1;
|
||||
position p1 != withtest.p;
|
||||
position p2;
|
||||
statement S;
|
||||
position any withtest.p;
|
||||
identifier f;
|
||||
@@
|
||||
|
||||
x@p1 = \(kmalloc\|kzalloc\|kcalloc\)(...);
|
||||
...
|
||||
x1@p = f@p2(...);
|
||||
if (!x1) S
|
||||
|
||||
@script:python depends on org@
|
||||
p1 << rfixed.p1;
|
||||
p2 << rfixed.p2;
|
||||
@@
|
||||
|
||||
cocci.print_main("alloc call",p1)
|
||||
cocci.print_secs("possible model",p2)
|
||||
|
||||
@script:python depends on report@
|
||||
p1 << rfixed.p1;
|
||||
p2 << rfixed.p2;
|
||||
@@
|
||||
|
||||
msg = "alloc with no test, possible model on line %s" % (p2[0].line)
|
||||
coccilib.report.print_report(p1[0],msg)
|
54
scripts/coccinelle/tests/doublebitand.cocci
Normal file
54
scripts/coccinelle/tests/doublebitand.cocci
Normal file
|
@ -0,0 +1,54 @@
|
|||
/// Find bit operations that include the same argument more than once
|
||||
//# One source of false positives is when the argument performs a side
|
||||
//# effect. Another source of false positives is when a neutral value
|
||||
//# such as 0 for | is used to indicate no information, to maintain the
|
||||
//# same structure as other similar expressions
|
||||
///
|
||||
// Confidence: Moderate
|
||||
// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2.
|
||||
// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2.
|
||||
// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2.
|
||||
// URL: http://coccinelle.lip6.fr/
|
||||
// Comments:
|
||||
// Options: --no-includes --include-headers
|
||||
|
||||
virtual context
|
||||
virtual org
|
||||
virtual report
|
||||
|
||||
@r expression@
|
||||
expression E;
|
||||
position p;
|
||||
@@
|
||||
|
||||
(
|
||||
* E@p
|
||||
& ... & E
|
||||
|
|
||||
* E@p
|
||||
| ... | E
|
||||
|
|
||||
* E@p
|
||||
& ... & !E
|
||||
|
|
||||
* E@p
|
||||
| ... | !E
|
||||
|
|
||||
* !E@p
|
||||
& ... & E
|
||||
|
|
||||
* !E@p
|
||||
| ... | E
|
||||
)
|
||||
|
||||
@script:python depends on org@
|
||||
p << r.p;
|
||||
@@
|
||||
|
||||
cocci.print_main("duplicated argument to & or |",p)
|
||||
|
||||
@script:python depends on report@
|
||||
p << r.p;
|
||||
@@
|
||||
|
||||
coccilib.report.print_report(p[0],"duplicated argument to & or |")
|
40
scripts/coccinelle/tests/doubletest.cocci
Normal file
40
scripts/coccinelle/tests/doubletest.cocci
Normal file
|
@ -0,0 +1,40 @@
|
|||
/// Find &&/|| operations that include the same argument more than once
|
||||
//# A common source of false positives is when the argument performs a side
|
||||
//# effect.
|
||||
///
|
||||
// Confidence: Moderate
|
||||
// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2.
|
||||
// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2.
|
||||
// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2.
|
||||
// URL: http://coccinelle.lip6.fr/
|
||||
// Comments:
|
||||
// Options: --no-includes --include-headers
|
||||
|
||||
virtual context
|
||||
virtual org
|
||||
virtual report
|
||||
|
||||
@r expression@
|
||||
expression E;
|
||||
position p;
|
||||
@@
|
||||
|
||||
(
|
||||
* E@p
|
||||
|| ... || E
|
||||
|
|
||||
* E@p
|
||||
&& ... && E
|
||||
)
|
||||
|
||||
@script:python depends on org@
|
||||
p << r.p;
|
||||
@@
|
||||
|
||||
cocci.print_main("duplicated argument to && or ||",p)
|
||||
|
||||
@script:python depends on report@
|
||||
p << r.p;
|
||||
@@
|
||||
|
||||
coccilib.report.print_report(p[0],"duplicated argument to && or ||")
|
65
scripts/coccinelle/tests/odd_ptr_err.cocci
Normal file
65
scripts/coccinelle/tests/odd_ptr_err.cocci
Normal file
|
@ -0,0 +1,65 @@
|
|||
/// PTR_ERR should access the value just tested by IS_ERR
|
||||
//# There can be false positives in the patch case, where it is the call
|
||||
//# IS_ERR that is wrong.
|
||||
///
|
||||
// Confidence: High
|
||||
// Copyright: (C) 2012 Julia Lawall, INRIA. GPLv2.
|
||||
// Copyright: (C) 2012 Gilles Muller, INRIA. GPLv2.
|
||||
// URL: http://coccinelle.lip6.fr/
|
||||
// Comments:
|
||||
// Options: --no-includes --include-headers
|
||||
|
||||
virtual patch
|
||||
virtual context
|
||||
virtual org
|
||||
virtual report
|
||||
|
||||
@depends on patch@
|
||||
expression e,e1;
|
||||
@@
|
||||
|
||||
(
|
||||
if (IS_ERR(e)) { ... PTR_ERR(e) ... }
|
||||
|
|
||||
if (IS_ERR(e=e1)) { ... PTR_ERR(e) ... }
|
||||
|
|
||||
if (IS_ERR(e))
|
||||
{ ...
|
||||
PTR_ERR(
|
||||
- e1
|
||||
+ e
|
||||
)
|
||||
... }
|
||||
)
|
||||
|
||||
@r depends on !patch@
|
||||
expression e,e1;
|
||||
position p1,p2;
|
||||
@@
|
||||
|
||||
(
|
||||
if (IS_ERR(e)) { ... PTR_ERR(e) ... }
|
||||
|
|
||||
if (IS_ERR(e=e1)) { ... PTR_ERR(e) ... }
|
||||
|
|
||||
*if (IS_ERR@p1(e))
|
||||
{ ...
|
||||
* PTR_ERR@p2(e1)
|
||||
... }
|
||||
)
|
||||
|
||||
@script:python depends on org@
|
||||
p1 << r.p1;
|
||||
p2 << r.p2;
|
||||
@@
|
||||
|
||||
cocci.print_main("inconsistent IS_ERR and PTR_ERR",p1)
|
||||
cocci.print_secs("PTR_ERR",p2)
|
||||
|
||||
@script:python depends on report@
|
||||
p1 << r.p1;
|
||||
p2 << r.p2;
|
||||
@@
|
||||
|
||||
msg = "inconsistent IS_ERR and PTR_ERR, PTR_ERR on line %s" % (p2[0].line)
|
||||
coccilib.report.print_report(p1[0],msg)
|
Loading…
Add table
Add a link
Reference in a new issue