1
0

Merge branch 'kbuild/coccinelle' into kbuild/misc

This commit is contained in:
Michal Marek
2010-06-12 00:01:31 +02:00
10 changed files with 923 additions and 3 deletions

3
scripts/Makefile.help Normal file
View File

@@ -0,0 +1,3 @@
checker-help:
@echo ' coccicheck - Check with Coccinelle.'

54
scripts/coccicheck Executable file
View File

@@ -0,0 +1,54 @@
#!/bin/sh
SPATCH="`which ${SPATCH:=spatch}`"
if [ ! -x "$SPATCH" ]; then
echo 'spatch is part of the Coccinelle project and is available at http://coccinelle.lip6.fr/'
exit 1
fi
if [ "$MODE" = "" ] ; then
echo 'You have not explicitly specify the mode to use. Fallback to "report".'
echo 'You can specify the mode with "make coccicheck MODE=<mode>"'
echo 'Available modes are: report, patch, context, org'
MODE="report"
fi
echo ''
echo 'Please check for false positives in the output before submitting a patch.'
echo 'When using "patch" mode, carefully review the patch before submitting it.'
echo ''
function coccinelle {
COCCI="$1"
DIR="$2"
OPT=`grep "Option" $COCCI | cut -d':' -f2`
FILE=`echo $COCCI | sed "s|$DIR/||"`
echo "Processing `basename $COCCI` with option(s) \"$OPT\""
echo 'Message example to submit a patch:'
sed -e '/\/\/\//!d' -e 's|^///||' $COCCI
echo ' The semantic patch that makes this change is available'
echo " in $FILE."
echo ''
echo ' More information about semantic patching is available at'
echo ' http://coccinelle.lip6.fr/'
echo ''
# The option '-parse_cocci' can be used to syntaxically check the SmPL files.
#
# $SPATCH -D $MODE -very_quiet -parse_cocci $COCCI $OPT > /dev/null
$SPATCH -D $MODE -very_quiet -sp_file $COCCI $OPT -dir $DIR
}
if [ "$COCCI" = "" ] ; then
for f in `find $srctree/scripts/coccinelle/ -name '*.cocci' -type f | sort`; do
coccinelle $f $srctree;
done
else
coccinelle $COCCI $srctree
fi

View File

@@ -0,0 +1,67 @@
///
/// Casting (void *) value returned by kmalloc is useless
/// as mentioned in Documentation/CodingStyle, Chap 14.
///
// Confidence: High
// Copyright: 2009,2010 Nicolas Palix, DIKU. GPLv2.
// URL: http://coccinelle.lip6.fr/
// Options: -no_includes -include_headers
//
// Keywords: kmalloc, kzalloc, kcalloc
// Version min: < 2.6.12 kmalloc
// Version min: < 2.6.12 kcalloc
// Version min: 2.6.14 kzalloc
//
virtual context
virtual patch
virtual org
virtual report
//----------------------------------------------------------
// For context mode
//----------------------------------------------------------
@depends on context@
type T;
@@
* (T *)
\(kmalloc\|kzalloc\|kcalloc\)(...)
//----------------------------------------------------------
// For patch mode
//----------------------------------------------------------
@depends on patch@
type T;
@@
- (T *)
\(kmalloc\|kzalloc\|kcalloc\)(...)
//----------------------------------------------------------
// For org and report mode
//----------------------------------------------------------
@r depends on org || report@
type T;
position p;
@@
(T@p *)\(kmalloc\|kzalloc\|kcalloc\)(...)
@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 k[cmz]alloc to (%s *) is useless." % (t)
coccilib.report.print_report(p[0], msg)

View File

@@ -0,0 +1,82 @@
///
/// kzalloc should be used rather than kmalloc followed by memset 0
///
// 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)

View File

@@ -0,0 +1,293 @@
///
/// 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 patch
virtual org
virtual report
@initialize:python depends on !context && patch && !org && !report@
import sys
print >> sys.stderr, "This semantic patch does not support the 'patch' mode."
@depends on patch@
@@
this_rule_should_never_matches();
@ifm depends on !patch@
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 depends on !patch expression@
expression *ifm.E;
identifier f;
position p1;
@@
(E != NULL && ...) ? <+...E->f@p1...+> : ...
@pr2 depends on !patch 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 && !patch && (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 && !patch && !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 && !patch && 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 && !patch && (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 && !patch && !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 && !patch && 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 && !patch && !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 depends on !patch@
expression *E;
statement S1,S2;
position p1;
@@
if@p1 ((E == NULL && ...) || ...) S1 else S2
@pr11 depends on !patch expression@
expression *ifm1.E;
identifier f;
position p1;
@@
(E != NULL && ...) ? <+...E->f@p1...+> : ...
@pr12 depends on !patch 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 && !patch && !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

View 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)

View 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)