* 'misc' of git://git.kernel.org/pub/scm/linux/kernel/git/mmarek/kbuild-2.6: (39 commits) Revert "namespace: add source file location exceptions" Coccinelle: Add contextual message Coccinelle: Fix documentation Coccinelle: Find doubled arguments to boolean or bit operators. Coccinelle: Find nested lock+irqsave functions that use the same flags variables. namespace: add source file location exceptions scripts/extract-ikconfig: add support for bzip2, lzma and lzo kbuild: check return value of asprintf() scripts/namespace.pl: improve to get more correct results scripts/namespace.pl: some bug fixes scripts/namespace.pl: update file exclusion list scripts/namespace.pl: fix wrong source path Coccinelle: Use the -no_show_diff option for org and report mode Coccinelle: Add a new mode named 'chain' Coccinelle: Use new comment format to explain kfree.cocci Coccinelle: Improve user information with a new kind of comment Coccinelle: Update documentation MAINTAINERS: Coccinelle: Update email address Documentation/kbuild: modules.txt cleanup Documentation/kbuild: major edit of modules.txt sections 5-8 ...
Showing the changes to scripts (26 of 29 files). Show all
Unified · Split
| @@ -333,7 +333,10 @@ static void docsect(char *filename, char *line) · 332 unmodified lines | ||
| 333 | 333 | if (*s == '\n') |
| 334 | 334 | *s = '\0'; |
| 335 | 335 | |
| 336 | − asprintf(&s, "DOC: %s", line); | |
| 336 | + if (asprintf(&s, "DOC: %s", line) < 0) { | |
| 337 | + perror("asprintf"); | |
| 338 | + exit(1); | |
| 339 | + } | |
| 337 | 340 | consume_symbol(s); |
| 338 | 341 | free(s); |
| 339 | 342 | |
| @@ -16,6 +16,7 @@ if [ "$C" = "1" -o "$C" = "2" ]; then · 15 unmodified lines | ||
| 16 | 16 | else |
| 17 | 17 | ONLINE=0 |
| 18 | 18 | FLAGS="-very_quiet" |
| 19 | + OPTIONS="-dir $srctree" | |
| 19 | 20 | fi |
| 20 | 21 | |
| 21 | 22 | if [ ! -x "$SPATCH" ]; then |
| @@ -25,11 +26,13 @@ fi · 3 unmodified lines | ||
| 25 | 26 | |
| 26 | 27 | if [ "$MODE" = "" ] ; then |
| 27 | 28 | if [ "$ONLINE" = "0" ] ; then |
| 28 | − echo 'You have not explicitly specify the mode to use. Fallback to "report".' | |
| 29 | + echo 'You have not explicitly specified the mode to use. Using default "chain" mode.' | |
| 30 | + echo 'All available modes will be tried (in that order): patch, report, context, org' | |
| 29 | 31 | echo 'You can specify the mode with "make coccicheck MODE=<mode>"' |
| 30 | − echo 'Available modes are: report, patch, context, org' | |
| 31 | 32 | fi |
| 32 | − MODE="report" | |
| 33 | + MODE="chain" | |
| 34 | +elif [ "$MODE" = "report" -o "$MODE" = "org" ] ; then | |
| 35 | + FLAGS="$FLAGS -no_show_diff" | |
| 33 | 36 | fi |
| 34 | 37 | |
| 35 | 38 | if [ "$ONLINE" = "0" ] ; then |
| @@ -44,7 +47,7 @@ coccinelle () { · 8 unmodified lines | ||
| 44 | 47 | |
| 45 | 48 | OPT=`grep "Option" $COCCI | cut -d':' -f2` |
| 46 | 49 | |
| 47 | −# The option '-parse_cocci' can be used to syntaxically check the SmPL files. | |
| 50 | +# The option '-parse_cocci' can be used to syntactically check the SmPL files. | |
| 48 | 51 | # |
| 49 | 52 | # $SPATCH -D $MODE $FLAGS -parse_cocci $COCCI $OPT > /dev/null |
| 50 | 53 | |
| @@ -52,21 +55,44 @@ coccinelle () { · 1 unmodified line | ||
| 52 | 55 | |
| 53 | 56 | FILE=`echo $COCCI | sed "s|$srctree/||"` |
| 54 | 57 | |
| 55 | − echo "Processing `basename $COCCI` with option(s) \"$OPT\"" | |
| 58 | + echo "Processing `basename $COCCI`" | |
| 59 | + echo "with option(s) \"$OPT\"" | |
| 60 | + echo '' | |
| 56 | 61 | echo 'Message example to submit a patch:' |
| 57 | 62 | |
| 58 | − sed -e '/\/\/\//!d' -e 's|^///||' $COCCI | |
| 59 | − | |
| 60 | − echo ' The semantic patch that makes this change is available' | |
| 63 | + sed -ne 's|^///||p' $COCCI | |
| 64 | + | |
| 65 | + if [ "$MODE" = "patch" ] ; then | |
| 66 | + echo ' The semantic patch that makes this change is available' | |
| 67 | + elif [ "$MODE" = "report" ] ; then | |
| 68 | + echo ' The semantic patch that makes this report is available' | |
| 69 | + elif [ "$MODE" = "context" ] ; then | |
| 70 | + echo ' The semantic patch that spots this code is available' | |
| 71 | + elif [ "$MODE" = "org" ] ; then | |
| 72 | + echo ' The semantic patch that makes this Org report is available' | |
| 73 | + else | |
| 74 | + echo ' The semantic patch that makes this output is available' | |
| 75 | + fi | |
| 61 | 76 | echo " in $FILE." |
| 62 | 77 | echo '' |
| 63 | 78 | echo ' More information about semantic patching is available at' |
| 64 | 79 | echo ' http://coccinelle.lip6.fr/' |
| 65 | 80 | echo '' |
| 66 | 81 | |
| 67 | − $SPATCH -D $MODE $FLAGS -sp_file $COCCI $OPT -dir $srctree || exit 1 | |
| 82 | + if [ "`sed -ne 's|^//#||p' $COCCI`" ] ; then | |
| 83 | + echo 'Semantic patch information:' | |
| 84 | + sed -ne 's|^//#||p' $COCCI | |
| 85 | + echo '' | |
| 86 | + fi | |
| 87 | + fi | |
| 88 | + | |
| 89 | + if [ "$MODE" = "chain" ] ; then | |
| 90 | + $SPATCH -D patch $FLAGS -sp_file $COCCI $OPT $OPTIONS || \ | |
| 91 | + $SPATCH -D report $FLAGS -sp_file $COCCI $OPT $OPTIONS -no_show_diff || \ | |
| 92 | + $SPATCH -D context $FLAGS -sp_file $COCCI $OPT $OPTIONS || \ | |
| 93 | + $SPATCH -D org $FLAGS -sp_file $COCCI $OPT $OPTIONS -no_show_diff || exit 1 | |
| 68 | 94 | else |
| 69 | − $SPATCH -D $MODE $FLAGS -sp_file $COCCI $OPT $OPTIONS || exit 1 | |
| 95 | + $SPATCH -D $MODE $FLAGS -sp_file $COCCI $OPT $OPTIONS || exit 1 | |
| 70 | 96 | fi |
| 71 | 97 | |
| 72 | 98 | } |
File renamed without changes.
| @@ -1,5 +1,9 @@ | ||
| 1 | 1 | /// |
| 2 | −/// kzalloc should be used rather than kmalloc followed by memset 0 | |
| 2 | +/// Use kzalloc rather than kmalloc followed by memset with 0 | |
| 3 | +/// | |
| 4 | +/// This considers some simple cases that are common and easy to validate | |
| 5 | +/// Note in particular that there are no ...s in the rule, so all of the | |
| 6 | +/// matched code has to be contiguous | |
| 3 | 7 | /// |
| 4 | 8 | // Confidence: High |
| 5 | 9 | // Copyright: (C) 2009-2010 Julia Lawall, Nicolas Palix, DIKU. GPLv2. |
File renamed without changes.
| @@ -0,0 +1,39 @@ | ||
| 1 | +/// Use kstrdup rather than duplicating its implementation | |
| 2 | +/// | |
| 3 | +// Confidence: High | |
| 4 | +// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. | |
| 5 | +// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. | |
| 6 | +// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. | |
| 7 | +// URL: http://coccinelle.lip6.fr/ | |
| 8 | +// Comments: | |
| 9 | +// Options: -no_includes -include_headers | |
| 10 | + | |
| 11 | +virtual patch | |
| 12 | + | |
| 13 | +@@ | |
| 14 | +expression from,to; | |
| 15 | +expression flag,E1,E2; | |
| 16 | +statement S; | |
| 17 | +@@ | |
| 18 | + | |
| 19 | +- to = kmalloc(strlen(from) + 1,flag); | |
| 20 | ++ to = kstrdup(from, flag); | |
| 21 | + ... when != \(from = E1 \| to = E1 \) | |
| 22 | + if (to==NULL || ...) S | |
| 23 | + ... when != \(from = E2 \| to = E2 \) | |
| 24 | +- strcpy(to, from); | |
| 25 | + | |
| 26 | +@@ | |
| 27 | +expression x,from,to; | |
| 28 | +expression flag,E1,E2,E3; | |
| 29 | +statement S; | |
| 30 | +@@ | |
| 31 | + | |
| 32 | +- x = strlen(from) + 1; | |
| 33 | + ... when != \( x = E1 \| from = E1 \) | |
| 34 | +- to = \(kmalloc\|kzalloc\)(x,flag); | |
| 35 | ++ to = kstrdup(from, flag); | |
| 36 | + ... when != \(x = E2 \| from = E2 \| to = E2 \) | |
| 37 | + if (to==NULL || ...) S | |
| 38 | + ... when != \(x = E3 \| from = E3 \| to = E3 \) | |
| 39 | +- memcpy(to, from, x); | |
| @@ -0,0 +1,40 @@ | ||
| 1 | +/// Use kmemdup rather than duplicating its implementation | |
| 2 | +/// | |
| 3 | +// Confidence: High | |
| 4 | +// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. | |
| 5 | +// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. | |
| 6 | +// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. | |
| 7 | +// URL: http://coccinelle.lip6.fr/ | |
| 8 | +// Comments: | |
| 9 | +// Options: -no_includes -include_headers | |
| 10 | + | |
| 11 | +virtual patch | |
| 12 | + | |
| 13 | +@r1@ | |
| 14 | +expression from,to; | |
| 15 | +expression flag; | |
| 16 | +position p; | |
| 17 | +@@ | |
| 18 | + | |
| 19 | + to = \(kmalloc@p\|kzalloc@p\)(strlen(from) + 1,flag); | |
| 20 | + | |
| 21 | +@r2@ | |
| 22 | +expression x,from,to; | |
| 23 | +expression flag,E1; | |
| 24 | +position p; | |
| 25 | +@@ | |
| 26 | + | |
| 27 | + x = strlen(from) + 1; | |
| 28 | + ... when != \( x = E1 \| from = E1 \) | |
| 29 | + to = \(kmalloc@p\|kzalloc@p\)(x,flag); | |
| 30 | + | |
| 31 | +@@ | |
| 32 | +expression from,to,size,flag; | |
| 33 | +position p != {r1.p,r2.p}; | |
| 34 | +statement S; | |
| 35 | +@@ | |
| 36 | + | |
| 37 | +- to = \(kmalloc@p\|kzalloc@p\)(size,flag); | |
| 38 | ++ to = kmemdup(from,size,flag); | |
| 39 | + if (to==NULL || ...) S | |
| 40 | +- memcpy(to, from, size); | |
| @@ -0,0 +1,35 @@ | ||
| 1 | +/// Use kmemdup_user rather than duplicating its implementation | |
| 2 | +/// This is a little bit restricted to reduce false positives | |
| 3 | +/// | |
| 4 | +// Confidence: High | |
| 5 | +// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. | |
| 6 | +// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. | |
| 7 | +// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. | |
| 8 | +// URL: http://coccinelle.lip6.fr/ | |
| 9 | +// Comments: | |
| 10 | +// Options: -no_includes -include_headers | |
| 11 | + | |
| 12 | +virtual patch | |
| 13 | + | |
| 14 | +@@ | |
| 15 | +expression from,to,size,flag; | |
| 16 | +position p; | |
| 17 | +identifier l1,l2; | |
| 18 | +@@ | |
| 19 | + | |
| 20 | +- to = \(kmalloc@p\|kzalloc@p\)(size,flag); | |
| 21 | ++ to = memdup_user(from,size); | |
| 22 | + if ( | |
| 23 | +- to==NULL | |
| 24 | ++ IS_ERR(to) | |
| 25 | + || ...) { | |
| 26 | + <+... when != goto l1; | |
| 27 | +- -ENOMEM | |
| 28 | ++ PTR_ERR(to) | |
| 29 | + ...+> | |
| 30 | + } | |
| 31 | +- if (copy_from_user(to, from, size) != 0) { | |
| 32 | +- <+... when != goto l2; | |
| 33 | +- -EFAULT | |
| 34 | +- ...+> | |
| 35 | +- } | |
File renamed without changes.
| @@ -0,0 +1,117 @@ | ||
| 1 | +/// Find a use after free. | |
| 2 | +//# Values of variables may imply that some | |
| 3 | +//# execution paths are not possible, resulting in false positives. | |
| 4 | +//# Another source of false positives are macros such as | |
| 5 | +//# SCTP_DBG_OBJCNT_DEC that do not actually evaluate their argument | |
| 6 | +/// | |
| 7 | +// Confidence: Moderate | |
| 8 | +// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. | |
| 9 | +// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. | |
| 10 | +// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. | |
| 11 | +// URL: http://coccinelle.lip6.fr/ | |
| 12 | +// Comments: | |
| 13 | +// Options: -no_includes -include_headers | |
| 14 | + | |
| 15 | +virtual org | |
| 16 | +virtual report | |
| 17 | + | |
| 18 | +@free@ | |
| 19 | +expression E; | |
| 20 | +position p1; | |
| 21 | +@@ | |
| 22 | + | |
| 23 | +kfree@p1(E) | |
| 24 | + | |
| 25 | +@print expression@ | |
| 26 | +constant char *c; | |
| 27 | +expression free.E,E2; | |
| 28 | +type T; | |
| 29 | +position p; | |
| 30 | +identifier f; | |
| 31 | +@@ | |
| 32 | + | |
| 33 | +( | |
| 34 | + f(...,c,...,(T)E@p,...) | |
| 35 | +| | |
| 36 | + E@p == E2 | |
| 37 | +| | |
| 38 | + E@p != E2 | |
| 39 | +| | |
| 40 | + !E@p | |
| 41 | +| | |
| 42 | + E@p || ... | |
| 43 | +) | |
| 44 | + | |
| 45 | +@sz@ | |
| 46 | +expression free.E; | |
| 47 | +position p; | |
| 48 | +@@ | |
| 49 | + | |
| 50 | + sizeof(<+...E@p...+>) | |
| 51 | + | |
| 52 | +@loop exists@ | |
| 53 | +expression E; | |
| 54 | +identifier l; | |
| 55 | +position ok; | |
| 56 | +@@ | |
| 57 | + | |
| 58 | +while (1) { ... | |
| 59 | + kfree@ok(E) | |
| 60 | + ... when != break; | |
| 61 | + when != goto l; | |
| 62 | + when forall | |
| 63 | +} | |
| 64 | + | |
| 65 | +@r exists@ | |
| 66 | +expression free.E, subE<=free.E, E2; | |
| 67 | +expression E1; | |
| 68 | +iterator iter; | |
| 69 | +statement S; | |
| 70 | +position free.p1!=loop.ok,p2!={print.p,sz.p}; | |
| 71 | +@@ | |
| 72 | + | |
| 73 | +kfree@p1(E,...) | |
| 74 | +... | |
| 75 | +( | |
| 76 | + iter(...,subE,...) S // no use | |
| 77 | +| | |
| 78 | + list_remove_head(E1,subE,...) | |
| 79 | +| | |
| 80 | + subE = E2 | |
| 81 | +| | |
| 82 | + subE++ | |
| 83 | +| | |
| 84 | + ++subE | |
| 85 | +| | |
| 86 | + --subE | |
| 87 | +| | |
| 88 | + subE-- | |
| 89 | +| | |
| 90 | + &subE | |
| 91 | +| | |
| 92 | + BUG(...) | |
| 93 | +| | |
| 94 | + BUG_ON(...) | |
| 95 | +| | |
| 96 | + return_VALUE(...) | |
| 97 | +| | |
| 98 | + return_ACPI_STATUS(...) | |
| 99 | +| | |
| 100 | + E@p2 // bad use | |
| 101 | +) | |
| 102 | + | |
| 103 | +@script:python depends on org@ | |
| 104 | +p1 << free.p1; | |
| 105 | +p2 << r.p2; | |
| 106 | +@@ | |
| 107 | + | |
| 108 | +cocci.print_main("kfree",p1) | |
| 109 | +cocci.print_secs("ref",p2) | |
| 110 | + | |
| 111 | +@script:python depends on report@ | |
| 112 | +p1 << free.p1; | |
| 113 | +p2 << r.p2; | |
| 114 | +@@ | |
| 115 | + | |
| 116 | +msg = "reference preceded by free on line %s" % (p1[0].line) | |
| 117 | +coccilib.report.print_report(p2[0],msg) | |
| @@ -0,0 +1,64 @@ | ||
| 1 | +/// These iterators only exit normally when the loop cursor is NULL, so there | |
| 2 | +/// is no point to call of_node_put on the final value. | |
| 3 | +/// | |
| 4 | +// Confidence: High | |
| 5 | +// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. | |
| 6 | +// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. | |
| 7 | +// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. | |
| 8 | +// URL: http://coccinelle.lip6.fr/ | |
| 9 | +// Comments: | |
| 10 | +// Options: -no_includes -include_headers | |
| 11 | + | |
| 12 | +virtual patch | |
| 13 | + | |
| 14 | +@@ | |
| 15 | +iterator name for_each_node_by_name; | |
| 16 | +expression np,E; | |
| 17 | +identifier l; | |
| 18 | +@@ | |
| 19 | + | |
| 20 | +for_each_node_by_name(np,...) { | |
| 21 | + ... when != break; | |
| 22 | + when != goto l; | |
| 23 | +} | |
| 24 | +... when != np = E | |
| 25 | +- of_node_put(np); | |
| 26 | + | |
| 27 | +@@ | |
| 28 | +iterator name for_each_node_by_type; | |
| 29 | +expression np,E; | |
| 30 | +identifier l; | |
| 31 | +@@ | |
| 32 | + | |
| 33 | +for_each_node_by_type(np,...) { | |
| 34 | + ... when != break; | |
| 35 | + when != goto l; | |
| 36 | +} | |
| 37 | +... when != np = E | |
| 38 | +- of_node_put(np); | |
| 39 | + | |
| 40 | +@@ | |
| 41 | +iterator name for_each_compatible_node; | |
| 42 | +expression np,E; | |
| 43 | +identifier l; | |
| 44 | +@@ | |
| 45 | + | |
| 46 | +for_each_compatible_node(np,...) { | |
| 47 | + ... when != break; | |
| 48 | + when != goto l; | |
| 49 | +} | |
| 50 | +... when != np = E | |
| 51 | +- of_node_put(np); | |
| 52 | + | |
| 53 | +@@ | |
| 54 | +iterator name for_each_matching_node; | |
| 55 | +expression np,E; | |
| 56 | +identifier l; | |
| 57 | +@@ | |
| 58 | + | |
| 59 | +for_each_matching_node(np,...) { | |
| 60 | + ... when != break; | |
| 61 | + when != goto l; | |
| 62 | +} | |
| 63 | +... when != np = E | |
| 64 | +- of_node_put(np); | |
| @@ -0,0 +1,58 @@ | ||
| 1 | +/// Many iterators have the property that the first argument is always bound | |
| 2 | +/// to a real list element, never NULL. False positives arise for some | |
| 3 | +/// iterators that do not have this property, or in cases when the loop | |
| 4 | +/// cursor is reassigned. The latter should only happen when the matched | |
| 5 | +/// code is on the way to a loop exit (break, goto, or return). | |
| 6 | +/// | |
| 7 | +// Confidence: Moderate | |
| 8 | +// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. | |
| 9 | +// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. | |
| 10 | +// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. | |
| 11 | +// URL: http://coccinelle.lip6.fr/ | |
| 12 | +// Comments: | |
| 13 | +// Options: -no_includes -include_headers | |
| 14 | + | |
| 15 | +virtual patch | |
| 16 | + | |
| 17 | +@@ | |
| 18 | +iterator I; | |
| 19 | +expression x,E,E1,E2; | |
| 20 | +statement S,S1,S2; | |
| 21 | +@@ | |
| 22 | + | |
| 23 | +I(x,...) { <... | |
| 24 | +( | |
| 25 | +- if (x == NULL && ...) S | |
| 26 | +| | |
| 27 | +- if (x != NULL || ...) | |
| 28 | + S | |
| 29 | +| | |
| 30 | +- (x == NULL) || | |
| 31 | + E | |
| 32 | +| | |
| 33 | +- (x != NULL) && | |
| 34 | + E | |
| 35 | +| | |
| 36 | +- (x == NULL && ...) ? E1 : | |
| 37 | + E2 | |
| 38 | +| | |
| 39 | +- (x != NULL || ...) ? | |
| 40 | + E1 | |
| 41 | +- : E2 | |
| 42 | +| | |
| 43 | +- if (x == NULL && ...) S1 else | |
| 44 | + S2 | |
| 45 | +| | |
| 46 | +- if (x != NULL || ...) | |
| 47 | + S1 | |
| 48 | +- else S2 | |
| 49 | +| | |
| 50 | ++ BAD( | |
| 51 | + x == NULL | |
| 52 | ++ ) | |
| 53 | +| | |
| 54 | ++ BAD( | |
| 55 | + x != NULL | |
| 56 | ++ ) | |
| 57 | +) | |
| 58 | + ...> } | |
| @@ -0,0 +1,62 @@ | ||
| 1 | +/// list_for_each_entry uses its first argument to get from one element of | |
| 2 | +/// the list to the next, so it is usually not a good idea to reassign it. | |
| 3 | +/// The first rule finds such a reassignment and the second rule checks | |
| 4 | +/// that there is a path from the reassignment back to the top of the loop. | |
| 5 | +/// | |
| 6 | +// Confidence: High | |
| 7 | +// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. | |
| 8 | +// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. | |
| 9 | +// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. | |
| 10 | +// URL: http://coccinelle.lip6.fr/ | |
| 11 | +// Comments: | |
| 12 | +// Options: -no_includes -include_headers | |
| 13 | + | |
| 14 | +virtual context | |
| 15 | +virtual org | |
| 16 | +virtual report | |
| 17 | + | |
| 18 | +@r@ | |
| 19 | +iterator name list_for_each_entry; | |
| 20 | +expression x,E; | |
| 21 | +position p1,p2; | |
| 22 | +@@ | |
| 23 | + | |
| 24 | +list_for_each_entry@p1(x,...) { <... x =@p2 E ...> } | |
| 25 | + | |
| 26 | +@depends on context && !org && !report@ | |
| 27 | +expression x,E; | |
| 28 | +position r.p1,r.p2; | |
| 29 | +statement S; | |
| 30 | +@@ | |
| 31 | + | |
| 32 | +*x =@p2 E | |
| 33 | +... | |
| 34 | +list_for_each_entry@p1(x,...) S | |
| 35 | + | |
| 36 | +// ------------------------------------------------------------------------ | |
| 37 | + | |
| 38 | +@back depends on (org || report) && !context exists@ | |
| 39 | +expression x,E; | |
| 40 | +position r.p1,r.p2; | |
| 41 | +statement S; | |
| 42 | +@@ | |
| 43 | + | |
| 44 | +x =@p2 E | |
| 45 | +... | |
| 46 | +list_for_each_entry@p1(x,...) S | |
| 47 | + | |
| 48 | +@script:python depends on back && org@ | |
| 49 | +p1 << r.p1; | |
| 50 | +p2 << r.p2; | |
| 51 | +@@ | |
| 52 | + | |
| 53 | +cocci.print_main("iterator",p1) | |
| 54 | +cocci.print_secs("update",p2) | |
| 55 | + | |
| 56 | +@script:python depends on back && report@ | |
| 57 | +p1 << r.p1; | |
| 58 | +p2 << r.p2; | |
| 59 | +@@ | |
| 60 | + | |
| 61 | +msg = "iterator with update on line %s" % (p2[0].line) | |
| 62 | +coccilib.report.print_report(p1[0],msg) | |
| @@ -0,0 +1,74 @@ | ||
| 1 | +/// Find functions that refer to GFP_KERNEL but are called with locks held. | |
| 2 | +/// The proposed change of converting the GFP_KERNEL is not necessarily the | |
| 3 | +/// correct one. It may be desired to unlock the lock, or to not call the | |
| 4 | +/// function under the lock in the first place. | |
| 5 | +/// | |
| 6 | +// Confidence: Moderate | |
| 7 | +// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. | |
| 8 | +// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. | |
| 9 | +// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. | |
| 10 | +// URL: http://coccinelle.lip6.fr/ | |
| 11 | +// Comments: | |
| 12 | +// Options: -no_includes -include_headers | |
| 13 | + | |
| 14 | +virtual patch | |
| 15 | + | |
| 16 | +@gfp exists@ | |
| 17 | +identifier fn; | |
| 18 | +position p; | |
| 19 | +@@ | |
| 20 | + | |
| 21 | +fn(...) { | |
| 22 | + ... when != read_unlock_irq(...) | |
| 23 | + when != write_unlock_irq(...) | |
| 24 | + when != read_unlock_irqrestore(...) | |
| 25 | + when != write_unlock_irqrestore(...) | |
| 26 | + when != spin_unlock(...) | |
| 27 | + when != spin_unlock_irq(...) | |
| 28 | + when != spin_unlock_irqrestore(...) | |
| 29 | + when != local_irq_enable(...) | |
| 30 | + when any | |
| 31 | + GFP_KERNEL@p | |
| 32 | + ... when any | |
| 33 | +} | |
| 34 | + | |
| 35 | +@locked@ | |
| 36 | +identifier gfp.fn; | |
| 37 | +@@ | |
| 38 | + | |
| 39 | +( | |
| 40 | +read_lock_irq | |
| 41 | +| | |
| 42 | +write_lock_irq | |
| 43 | +| | |
| 44 | +read_lock_irqsave | |
| 45 | +| | |
| 46 | +write_lock_irqsave | |
| 47 | +| | |
| 48 | +spin_lock | |
| 49 | +| | |
| 50 | +spin_trylock | |
| 51 | +| | |
| 52 | +spin_lock_irq | |
| 53 | +| | |
| 54 | +spin_lock_irqsave | |
| 55 | +| | |
| 56 | +local_irq_disable | |
| 57 | +) | |
| 58 | + (...) | |
| 59 | +... when != read_unlock_irq(...) | |
| 60 | + when != write_unlock_irq(...) | |
| 61 | + when != read_unlock_irqrestore(...) | |
| 62 | + when != write_unlock_irqrestore(...) | |
| 63 | + when != spin_unlock(...) | |
| 64 | + when != spin_unlock_irq(...) | |
| 65 | + when != spin_unlock_irqrestore(...) | |
| 66 | + when != local_irq_enable(...) | |
| 67 | +fn(...) | |
| 68 | + | |
| 69 | +@depends on locked@ | |
| 70 | +position gfp.p; | |
| 71 | +@@ | |
| 72 | + | |
| 73 | +- GFP_KERNEL@p | |
| 74 | ++ GFP_ATOMIC | |
| @@ -0,0 +1,92 @@ | ||
| 1 | +/// Find double locks. False positives may occur when some paths cannot | |
| 2 | +/// occur at execution, due to the values of variables, and when there is | |
| 3 | +/// an intervening function call that releases the lock. | |
| 4 | +/// | |
| 5 | +// Confidence: Moderate | |
| 6 | +// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. | |
| 7 | +// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. | |
| 8 | +// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. | |
| 9 | +// URL: http://coccinelle.lip6.fr/ | |
| 10 | +// Comments: | |
| 11 | +// Options: -no_includes -include_headers | |
| 12 | + | |
| 13 | +virtual org | |
| 14 | +virtual report | |
| 15 | + | |
| 16 | +@locked@ | |
| 17 | +position p1; | |
| 18 | +expression E1; | |
| 19 | +position p; | |
| 20 | +@@ | |
| 21 | + | |
| 22 | +( | |
| 23 | +mutex_lock@p1 | |
| 24 | +| | |
| 25 | +mutex_trylock@p1 | |
| 26 | +| | |
| 27 | +spin_lock@p1 | |
| 28 | +| | |
| 29 | +spin_trylock@p1 | |
| 30 | +| | |
| 31 | +read_lock@p1 | |
| 32 | +| | |
| 33 | +read_trylock@p1 | |
| 34 | +| | |
| 35 | +write_lock@p1 | |
| 36 | +| | |
| 37 | +write_trylock@p1 | |
| 38 | +) (E1@p,...); | |
| 39 | + | |
| 40 | +@balanced@ | |
| 41 | +position p1 != locked.p1; | |
| 42 | +position locked.p; | |
| 43 | +identifier lock,unlock; | |
| 44 | +expression x <= locked.E1; | |
| 45 | +expression E,locked.E1; | |
| 46 | +expression E2; | |
| 47 | +@@ | |
| 48 | + | |
| 49 | +if (E) { | |
| 50 | + <+... when != E1 | |
| 51 | + lock(E1@p,...) | |
| 52 | + ...+> | |
| 53 | +} | |
| 54 | +... when != E1 | |
| 55 | + when != \(x = E2\|&x\) | |
| 56 | + when forall | |
| 57 | +if (E) { | |
| 58 | + <+... when != E1 | |
| 59 | + unlock@p1(E1,...) | |
| 60 | + ...+> | |
| 61 | +} | |
| 62 | + | |
| 63 | +@r depends on !balanced exists@ | |
| 64 | +expression x <= locked.E1; | |
| 65 | +expression locked.E1; | |
| 66 | +expression E2; | |
| 67 | +identifier lock; | |
| 68 | +position locked.p,p1,p2; | |
| 69 | +@@ | |
| 70 | + | |
| 71 | +lock@p1 (E1@p,...); | |
| 72 | +... when != E1 | |
| 73 | + when != \(x = E2\|&x\) | |
| 74 | +lock@p2 (E1,...); | |
| 75 | + | |
| 76 | +@script:python depends on org@ | |
| 77 | +p1 << r.p1; | |
| 78 | +p2 << r.p2; | |
| 79 | +lock << r.lock; | |
| 80 | +@@ | |
| 81 | + | |
| 82 | +cocci.print_main(lock,p1) | |
| 83 | +cocci.print_secs("second lock",p2) | |
| 84 | + | |
| 85 | +@script:python depends on report@ | |
| 86 | +p1 << r.p1; | |
| 87 | +p2 << r.p2; | |
| 88 | +lock << r.lock; | |
| 89 | +@@ | |
| 90 | + | |
| 91 | +msg = "second lock on line %s" % (p2[0].line) | |
| 92 | +coccilib.report.print_report(p1[0],msg) | |
| @@ -0,0 +1,80 @@ | ||
| 1 | +/// Find nested lock+irqsave functions that use the same flags variables | |
| 2 | +/// | |
| 3 | +// Confidence: High | |
| 4 | +// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. | |
| 5 | +// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. | |
| 6 | +// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. | |
| 7 | +// URL: http://coccinelle.lip6.fr/ | |
| 8 | +// Comments: | |
| 9 | +// Options: -no_includes -include_headers | |
| 10 | + | |
| 11 | +virtual context | |
| 12 | +virtual org | |
| 13 | +virtual report | |
| 14 | + | |
| 15 | +@r@ | |
| 16 | +expression lock1,lock2,flags; | |
| 17 | +position p1,p2; | |
| 18 | +@@ | |
| 19 | + | |
| 20 | +( | |
| 21 | +spin_lock_irqsave@p1(lock1,flags) | |
| 22 | +| | |
| 23 | +read_lock_irqsave@p1(lock1,flags) | |
| 24 | +| | |
| 25 | +write_lock_irqsave@p1(lock1,flags) | |
| 26 | +) | |
| 27 | +... when != flags | |
| 28 | +( | |
| 29 | +spin_lock_irqsave(lock1,flags) | |
| 30 | +| | |
| 31 | +read_lock_irqsave(lock1,flags) | |
| 32 | +| | |
| 33 | +write_lock_irqsave(lock1,flags) | |
| 34 | +| | |
| 35 | +spin_lock_irqsave@p2(lock2,flags) | |
| 36 | +| | |
| 37 | +read_lock_irqsave@p2(lock2,flags) | |
| 38 | +| | |
| 39 | +write_lock_irqsave@p2(lock2,flags) | |
| 40 | +) | |
| 41 | + | |
| 42 | +@d@ | |
| 43 | +expression f <= r.flags; | |
| 44 | +expression lock1,lock2,flags; | |
| 45 | +position r.p1, r.p2; | |
| 46 | +@@ | |
| 47 | + | |
| 48 | +( | |
| 49 | +*spin_lock_irqsave@p1(lock1,flags) | |
| 50 | +| | |
| 51 | +*read_lock_irqsave@p1(lock1,flags) | |
| 52 | +| | |
| 53 | +*write_lock_irqsave@p1(lock1,flags) | |
| 54 | +) | |
| 55 | +... when != f | |
| 56 | +( | |
| 57 | +*spin_lock_irqsave@p2(lock2,flags) | |
| 58 | +| | |
| 59 | +*read_lock_irqsave@p2(lock2,flags) | |
| 60 | +| | |
| 61 | +*write_lock_irqsave@p2(lock2,flags) | |
| 62 | +) | |
| 63 | + | |
| 64 | +// ---------------------------------------------------------------------- | |
| 65 | + | |
| 66 | +@script:python depends on d && org@ | |
| 67 | +p1 << r.p1; | |
| 68 | +p2 << r.p2; | |
| 69 | +@@ | |
| 70 | + | |
| 71 | +cocci.print_main("original lock",p1) | |
| 72 | +cocci.print_secs("nested lock+irqsave that reuses flags",p2) | |
| 73 | + | |
| 74 | +@script:python depends on d && report@ | |
| 75 | +p1 << r.p1; | |
| 76 | +p2 << r.p2; | |
| 77 | +@@ | |
| 78 | + | |
| 79 | +msg="ERROR: nested lock+irqsave that reuses flags from %s." % (p1[0].line) | |
| 80 | +coccilib.report.print_report(p2[0], msg) | |
| @@ -0,0 +1,95 @@ | ||
| 1 | +/// Find missing unlocks. This semantic match considers the specific case | |
| 2 | +/// where the unlock is missing from an if branch, and there is a lock | |
| 3 | +/// before the if and an unlock after the if. False positives are due to | |
| 4 | +/// cases where the if branch represents a case where the function is | |
| 5 | +/// supposed to exit with the lock held, or where there is some preceding | |
| 6 | +/// function call that releases the lock. | |
| 7 | +/// | |
| 8 | +// Confidence: Moderate | |
| 9 | +// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. | |
| 10 | +// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. | |
| 11 | +// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. | |
| 12 | +// URL: http://coccinelle.lip6.fr/ | |
| 13 | +// Comments: | |
| 14 | +// Options: -no_includes -include_headers | |
| 15 | + | |
| 16 | +virtual org | |
| 17 | +virtual report | |
| 18 | + | |
| 19 | +@prelocked@ | |
| 20 | +position p1,p; | |
| 21 | +expression E1; | |
| 22 | +@@ | |
| 23 | + | |
| 24 | +( | |
| 25 | +mutex_lock@p1 | |
| 26 | +| | |
| 27 | +mutex_trylock@p1 | |
| 28 | +| | |
| 29 | +spin_lock@p1 | |
| 30 | +| | |
| 31 | +spin_trylock@p1 | |
| 32 | +| | |
| 33 | +read_lock@p1 | |
| 34 | +| | |
| 35 | +read_trylock@p1 | |
| 36 | +| | |
| 37 | +write_lock@p1 | |
| 38 | +| | |
| 39 | +write_trylock@p1 | |
| 40 | +| | |
| 41 | +read_lock_irq@p1 | |
| 42 | +| | |
| 43 | +write_lock_irq@p1 | |
| 44 | +| | |
| 45 | +read_lock_irqsave@p1 | |
| 46 | +| | |
| 47 | +write_lock_irqsave@p1 | |
| 48 | +| | |
| 49 | +spin_lock_irq@p1 | |
| 50 | +| | |
| 51 | +spin_lock_irqsave@p1 | |
| 52 | +) (E1@p,...); | |
| 53 | + | |
| 54 | +@looped@ | |
| 55 | +position r; | |
| 56 | +@@ | |
| 57 | + | |
| 58 | +for(...;...;...) { <+... return@r ...; ...+> } | |
| 59 | + | |
| 60 | +@err@ | |
| 61 | +expression E1; | |
| 62 | +position prelocked.p; | |
| 63 | +position up != prelocked.p1; | |
| 64 | +position r!=looped.r; | |
| 65 | +identifier lock,unlock; | |
| 66 | +@@ | |
| 67 | + | |
| 68 | +lock(E1@p,...); | |
| 69 | +<+... when != E1 | |
| 70 | +if (...) { | |
| 71 | + ... when != E1 | |
| 72 | + return@r ...; | |
| 73 | +} | |
| 74 | +...+> | |
| 75 | +unlock@up(E1,...); | |
| 76 | + | |
| 77 | +@script:python depends on org@ | |
| 78 | +p << prelocked.p1; | |
| 79 | +lock << err.lock; | |
| 80 | +unlock << err.unlock; | |
| 81 | +p2 << err.r; | |
| 82 | +@@ | |
| 83 | + | |
| 84 | +cocci.print_main(lock,p) | |
| 85 | +cocci.print_secs(unlock,p2) | |
| 86 | + | |
| 87 | +@script:python depends on report@ | |
| 88 | +p << prelocked.p1; | |
| 89 | +lock << err.lock; | |
| 90 | +unlock << err.unlock; | |
| 91 | +p2 << err.r; | |
| 92 | +@@ | |
| 93 | + | |
| 94 | +msg = "preceding lock on line %s" % (p[0].line) | |
| 95 | +coccilib.report.print_report(p2[0],msg) | |
| @@ -0,0 +1,53 @@ | ||
| 1 | +/// Find duplicate field initializations. This has a high rate of false | |
| 2 | +/// positives due to #ifdefs, which Coccinelle is not aware of in a structure | |
| 3 | +/// initialization. | |
| 4 | +/// | |
| 5 | +// Confidence: Low | |
| 6 | +// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. | |
| 7 | +// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. | |
| 8 | +// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. | |
| 9 | +// URL: http://coccinelle.lip6.fr/ | |
| 10 | +// Comments: | |
| 11 | +// Options: -no_includes -include_headers | |
| 12 | + | |
| 13 | +virtual org | |
| 14 | +virtual report | |
| 15 | + | |
| 16 | +@r@ | |
| 17 | +identifier I, s, fld; | |
| 18 | +position p0,p; | |
| 19 | +expression E; | |
| 20 | +@@ | |
| 21 | + | |
| 22 | +struct I s =@p0 { ... .fld@p = E, ...}; | |
| 23 | + | |
| 24 | +@s@ | |
| 25 | +identifier I, s, r.fld; | |
| 26 | +position r.p0,p; | |
| 27 | +expression E; | |
| 28 | +@@ | |
| 29 | + | |
| 30 | +struct I s =@p0 { ... .fld@p = E, ...}; | |
| 31 | + | |
| 32 | +@script:python depends on org@ | |
| 33 | +p0 << r.p0; | |
| 34 | +fld << r.fld; | |
| 35 | +ps << s.p; | |
| 36 | +pr << r.p; | |
| 37 | +@@ | |
| 38 | + | |
| 39 | +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)): | |
| 40 | + cocci.print_main(fld,p0) | |
| 41 | + cocci.print_secs("s",ps) | |
| 42 | + cocci.print_secs("r",pr) | |
| 43 | + | |
| 44 | +@script:python depends on report@ | |
| 45 | +p0 << r.p0; | |
| 46 | +fld << r.fld; | |
| 47 | +ps << s.p; | |
| 48 | +pr << r.p; | |
| 49 | +@@ | |
| 50 | + | |
| 51 | +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)): | |
| 52 | + msg = "%s: first occurrence %s, second occurrence %s" % (fld,ps[0].line,pr[0].line) | |
| 53 | + coccilib.report.print_report(p0[0],msg) | |
| @@ -0,0 +1,48 @@ | ||
| 1 | +/// Find confusingly indented code in or after an if. An if branch should | |
| 2 | +/// be indented. The code following an if should not be indented. | |
| 3 | +/// Sometimes, code after an if that is indented is actually intended to be | |
| 4 | +/// part of the if branch. | |
| 5 | +/// | |
| 6 | +/// This has a high rate of false positives, because Coccinelle's column | |
| 7 | +/// calculation does not distinguish between spaces and tabs, so code that | |
| 8 | +/// is not visually aligned may be considered to be in the same column. | |
| 9 | +/// | |
| 10 | +// Confidence: Low | |
| 11 | +// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. | |
| 12 | +// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. | |
| 13 | +// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. | |
| 14 | +// URL: http://coccinelle.lip6.fr/ | |
| 15 | +// Comments: | |
| 16 | +// Options: -no_includes -include_headers | |
| 17 | + | |
| 18 | +virtual org | |
| 19 | +virtual report | |
| 20 | + | |
| 21 | +@r disable braces4@ | |
| 22 | +position p1,p2; | |
| 23 | +statement S1,S2; | |
| 24 | +@@ | |
| 25 | + | |
| 26 | +( | |
| 27 | +if (...) { ... } | |
| 28 | +| | |
| 29 | +if (...) S1@p1 S2@p2 | |
| 30 | +) | |
| 31 | + | |
| 32 | +@script:python depends on org@ | |
| 33 | +p1 << r.p1; | |
| 34 | +p2 << r.p2; | |
| 35 | +@@ | |
| 36 | + | |
| 37 | +if (p1[0].column == p2[0].column): | |
| 38 | + cocci.print_main("branch",p1) | |
| 39 | + cocci.print_secs("after",p2) | |
| 40 | + | |
| 41 | +@script:python depends on report@ | |
| 42 | +p1 << r.p1; | |
| 43 | +p2 << r.p2; | |
| 44 | +@@ | |
| 45 | + | |
| 46 | +if (p1[0].column == p2[0].column): | |
| 47 | + msg = "code aligned with following code on line %s" % (p2[0].line) | |
| 48 | + coccilib.report.print_report(p1[0],msg) | |
File renamed without changes.
| @@ -0,0 +1,20 @@ | ||
| 1 | +/// The various basic memory allocation functions don't return ERR_PTR | |
| 2 | +/// | |
| 3 | +// Confidence: High | |
| 4 | +// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. | |
| 5 | +// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. | |
| 6 | +// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. | |
| 7 | +// URL: http://coccinelle.lip6.fr/ | |
| 8 | +// Comments: | |
| 9 | +// Options: -no_includes -include_headers | |
| 10 | + | |
| 11 | +virtual patch | |
| 12 | + | |
| 13 | +@@ | |
| 14 | +expression x,E; | |
| 15 | +@@ | |
| 16 | + | |
| 17 | +x = \(kmalloc\|kzalloc\|kcalloc\|kmem_cache_alloc\|kmem_cache_zalloc\|kmem_cache_alloc_node\|kmalloc_node\|kzalloc_node\)(...) | |
| 18 | +... when != x = E | |
| 19 | +- IS_ERR(x) | |
| 20 | ++ !x | |
| @@ -0,0 +1,72 @@ | ||
| 1 | +/// This semantic patch looks for kmalloc etc that are not followed by a | |
| 2 | +/// NULL check. It only gives a report in the case where there is some | |
| 3 | +/// error handling code later in the function, which may be helpful | |
| 4 | +/// in determining what the error handling code for the call to kmalloc etc | |
| 5 | +/// should be. | |
| 6 | +/// | |
| 7 | +// Confidence: High | |
| 8 | +// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. | |
| 9 | +// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. | |
| 10 | +// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. | |
| 11 | +// URL: http://coccinelle.lip6.fr/ | |
| 12 | +// Comments: | |
| 13 | +// Options: -no_includes -include_headers | |
| 14 | + | |
| 15 | +virtual context | |
| 16 | +virtual org | |
| 17 | +virtual report | |
| 18 | + | |
| 19 | +@withtest@ | |
| 20 | +expression x; | |
| 21 | +position p; | |
| 22 | +identifier f,fld; | |
| 23 | +@@ | |
| 24 | + | |
| 25 | +x@p = f(...); | |
| 26 | +... when != x->fld | |
| 27 | +\(x == NULL \| x != NULL\) | |
| 28 | + | |
| 29 | +@fixed depends on context && !org && !report@ | |
| 30 | +expression x,x1; | |
| 31 | +position p1 != withtest.p; | |
| 32 | +statement S; | |
| 33 | +position any withtest.p; | |
| 34 | +identifier f; | |
| 35 | +@@ | |
| 36 | + | |
| 37 | +*x@p1 = \(kmalloc\|kzalloc\|kcalloc\)(...); | |
| 38 | +... | |
| 39 | +*x1@p = f(...); | |
| 40 | +if (!x1) S | |
| 41 | + | |
| 42 | +// ------------------------------------------------------------------------ | |
| 43 | + | |
| 44 | +@rfixed depends on (org || report) && !context exists@ | |
| 45 | +expression x,x1; | |
| 46 | +position p1 != withtest.p; | |
| 47 | +position p2; | |
| 48 | +statement S; | |
| 49 | +position any withtest.p; | |
| 50 | +identifier f; | |
| 51 | +@@ | |
| 52 | + | |
| 53 | +x@p1 = \(kmalloc\|kzalloc\|kcalloc\)(...); | |
| 54 | +... | |
| 55 | +x1@p = f@p2(...); | |
| 56 | +if (!x1) S | |
| 57 | + | |
| 58 | +@script:python depends on org@ | |
| 59 | +p1 << rfixed.p1; | |
| 60 | +p2 << rfixed.p2; | |
| 61 | +@@ | |
| 62 | + | |
| 63 | +cocci.print_main("alloc call",p1) | |
| 64 | +cocci.print_secs("possible model",p2) | |
| 65 | + | |
| 66 | +@script:python depends on report@ | |
| 67 | +p1 << rfixed.p1; | |
| 68 | +p2 << rfixed.p2; | |
| 69 | +@@ | |
| 70 | + | |
| 71 | +msg = "alloc with no test, possible model on line %s" % (p2[0].line) | |
| 72 | +coccilib.report.print_report(p1[0],msg) | |
| @@ -0,0 +1,54 @@ | ||
| 1 | +/// Find bit operations that include the same argument more than once | |
| 2 | +//# One source of false positives is when the argument performs a side | |
| 3 | +//# effect. Another source of false positives is when a neutral value | |
| 4 | +//# such as 0 for | is used to indicate no information, to maintain the | |
| 5 | +//# same structure as other similar expressions | |
| 6 | +/// | |
| 7 | +// Confidence: Moderate | |
| 8 | +// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. | |
| 9 | +// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. | |
| 10 | +// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. | |
| 11 | +// URL: http://coccinelle.lip6.fr/ | |
| 12 | +// Comments: | |
| 13 | +// Options: -no_includes -include_headers | |
| 14 | + | |
| 15 | +virtual context | |
| 16 | +virtual org | |
| 17 | +virtual report | |
| 18 | + | |
| 19 | +@r expression@ | |
| 20 | +expression E; | |
| 21 | +position p; | |
| 22 | +@@ | |
| 23 | + | |
| 24 | +( | |
| 25 | +* E@p | |
| 26 | + & ... & E | |
| 27 | +| | |
| 28 | +* E@p | |
| 29 | + | ... | E | |
| 30 | +| | |
| 31 | +* E@p | |
| 32 | + & ... & !E | |
| 33 | +| | |
| 34 | +* E@p | |
| 35 | + | ... | !E | |
| 36 | +| | |
| 37 | +* !E@p | |
| 38 | + & ... & E | |
| 39 | +| | |
| 40 | +* !E@p | |
| 41 | + | ... | E | |
| 42 | +) | |
| 43 | + | |
| 44 | +@script:python depends on org@ | |
| 45 | +p << r.p; | |
| 46 | +@@ | |
| 47 | + | |
| 48 | +cocci.print_main("duplicated argument to & or |",p) | |
| 49 | + | |
| 50 | +@script:python depends on report@ | |
| 51 | +p << r.p; | |
| 52 | +@@ | |
| 53 | + | |
| 54 | +coccilib.report.print_report(p[0],"duplicated argument to & or |") | |
| @@ -0,0 +1,40 @@ | ||
| 1 | +/// Find &&/|| operations that include the same argument more than once | |
| 2 | +//# A common source of false positives is when the argument performs a side | |
| 3 | +//# effect. | |
| 4 | +/// | |
| 5 | +// Confidence: Moderate | |
| 6 | +// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. | |
| 7 | +// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. | |
| 8 | +// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. | |
| 9 | +// URL: http://coccinelle.lip6.fr/ | |
| 10 | +// Comments: | |
| 11 | +// Options: -no_includes -include_headers | |
| 12 | + | |
| 13 | +virtual context | |
| 14 | +virtual org | |
| 15 | +virtual report | |
| 16 | + | |
| 17 | +@r expression@ | |
| 18 | +expression E; | |
| 19 | +position p; | |
| 20 | +@@ | |
| 21 | + | |
| 22 | +( | |
| 23 | +* E@p | |
| 24 | + || ... || E | |
| 25 | +| | |
| 26 | +* E@p | |
| 27 | + && ... && E | |
| 28 | +) | |
| 29 | + | |
| 30 | +@script:python depends on org@ | |
| 31 | +p << r.p; | |
| 32 | +@@ | |
| 33 | + | |
| 34 | +cocci.print_main("duplicated argument to && or ||",p) | |
| 35 | + | |
| 36 | +@script:python depends on report@ | |
| 37 | +p << r.p; | |
| 38 | +@@ | |
| 39 | + | |
| 40 | +coccilib.report.print_report(p[0],"duplicated argument to && or ||") | |
| @@ -7,12 +7,10 @@ · 6 unmodified lines | ||
| 7 | 7 | # The obscure use of the "tr" filter is to work around older versions of |
| 8 | 8 | # "grep" that report the byte offset of the line instead of the pattern. |
| 9 | 9 | # |
| 10 | −# (c) 2009, Dick Streefland <dick@streefland.net> | |
| 10 | +# (c) 2009,2010 Dick Streefland <dick@streefland.net> | |
| 11 | 11 | # Licensed under the terms of the GNU General Public License. |
| 12 | 12 | # ---------------------------------------------------------------------- |
| 13 | 13 | |
| 14 | −gz1='\037\213\010' | |
| 15 | −gz2='01' | |
| 16 | 14 | cf1='IKCFG_ST\037\213\010' |
| 17 | 15 | cf2='0123456789' |
| 18 | 16 | |
| @@ -21,11 +19,25 @@ dump_config() · 2 unmodified lines | ||
| 21 | 19 | if pos=`tr "$cf1\n$cf2" "\n$cf2=" < "$1" | grep -abo "^$cf2"` |
| 22 | 20 | then |
| 23 | 21 | pos=${pos%%:*} |
| 24 | − tail -c+$(($pos+8)) "$1" | zcat -q | |
| 25 | − exit 0 | |
| 22 | + tail -c+$(($pos+8)) "$1" | zcat > $tmp1 2> /dev/null | |
| 23 | + if [ $? != 1 ] | |
| 24 | + then # exit status must be 0 or 2 (trailing garbage warning) | |
| 25 | + cat $tmp1 | |
| 26 | + exit 0 | |
| 27 | + fi | |
| 26 | 28 | fi |
| 27 | 29 | } |
| 28 | 30 | |
| 31 | +try_decompress() | |
| 32 | +{ | |
| 33 | + for pos in `tr "$1\n$2" "\n$2=" < "$img" | grep -abo "^$2"` | |
| 34 | + do | |
| 35 | + pos=${pos%%:*} | |
| 36 | + tail -c+$pos "$img" | $3 > $tmp2 2> /dev/null | |
| 37 | + dump_config $tmp2 | |
| 38 | + done | |
| 39 | +} | |
| 40 | + | |
| 29 | 41 | # Check invocation: |
| 30 | 42 | me=${0##*/} |
| 31 | 43 | img=$1 |
| @@ -35,18 +47,19 @@ then · 3 unmodified lines | ||
| 35 | 47 | exit 2 |
| 36 | 48 | fi |
| 37 | 49 | |
| 50 | +# Prepare temp files: | |
| 51 | +tmp1=/tmp/ikconfig$$.1 | |
| 52 | +tmp2=/tmp/ikconfig$$.2 | |
| 53 | +trap "rm -f $tmp1 $tmp2" 0 | |
| 54 | + | |
| 38 | 55 | # Initial attempt for uncompressed images or objects: |
| 39 | 56 | dump_config "$img" |
| 40 | 57 | |
| 41 | −# That didn't work, so decompress and try again: | |
| 42 | −tmp=/tmp/ikconfig$$ | |
| 43 | −trap "rm -f $tmp" 0 | |
| 44 | −for pos in `tr "$gz1\n$gz2" "\n$gz2=" < "$img" | grep -abo "^$gz2"` | |
| 45 | −do | |
| 46 | − pos=${pos%%:*} | |
| 47 | − tail -c+$pos "$img" | zcat 2> /dev/null > $tmp | |
| 48 | − dump_config $tmp | |
| 49 | −done | |
| 58 | +# That didn't work, so retry after decompression. | |
| 59 | +try_decompress '\037\213\010' xy gunzip | |
| 60 | +try_decompress 'BZh' xy bunzip2 | |
| 61 | +try_decompress '\135\0\0\0' xxx unlzma | |
| 62 | +try_decompress '\211\114\132' xy 'lzop -d' | |
| 50 | 63 | |
| 51 | 64 | # Bail out: |
| 52 | 65 | echo "$me: Cannot find kernel config." >&2 |
| @@ -84,6 +84,64 @@ my %ksymtab = (); # names that appear in __ksymtab_ · 83 unmodified lines | ||
| 84 | 84 | my %ref = (); # $ref{$name} exists if there is a true external reference to $name |
| 85 | 85 | my %export = (); # $export{$name} exists if there is an EXPORT_... of $name |
| 86 | 86 | |
| 87 | +my %nmexception = ( | |
| 88 | + 'fs/ext3/bitmap' => 1, | |
| 89 | + 'fs/ext4/bitmap' => 1, | |
| 90 | + 'arch/x86/lib/thunk_32' => 1, | |
| 91 | + 'arch/x86/lib/cmpxchg' => 1, | |
| 92 | + 'arch/x86/vdso/vdso32/note' => 1, | |
| 93 | + 'lib/irq_regs' => 1, | |
| 94 | + 'usr/initramfs_data' => 1, | |
| 95 | + 'drivers/scsi/aic94xx/aic94xx_dump' => 1, | |
| 96 | + 'drivers/scsi/libsas/sas_dump' => 1, | |
| 97 | + 'lib/dec_and_lock' => 1, | |
| 98 | + 'drivers/ide/ide-probe-mini' => 1, | |
| 99 | + 'usr/initramfs_data' => 1, | |
| 100 | + 'drivers/acpi/acpia/exdump' => 1, | |
| 101 | + 'drivers/acpi/acpia/rsdump' => 1, | |
| 102 | + 'drivers/acpi/acpia/nsdumpdv' => 1, | |
| 103 | + 'drivers/acpi/acpia/nsdump' => 1, | |
| 104 | + 'arch/ia64/sn/kernel/sn2/io' => 1, | |
| 105 | + 'arch/ia64/kernel/gate-data' => 1, | |
| 106 | + 'security/capability' => 1, | |
| 107 | + 'fs/ntfs/sysctl' => 1, | |
| 108 | + 'fs/jfs/jfs_debug' => 1, | |
| 109 | +); | |
| 110 | + | |
| 111 | +my %nameexception = ( | |
| 112 | + 'mod_use_count_' => 1, | |
| 113 | + '__initramfs_end' => 1, | |
| 114 | + '__initramfs_start' => 1, | |
| 115 | + '_einittext' => 1, | |
| 116 | + '_sinittext' => 1, | |
| 117 | + 'kallsyms_names' => 1, | |
| 118 | + 'kallsyms_num_syms' => 1, | |
| 119 | + 'kallsyms_addresses'=> 1, | |
| 120 | + '__this_module' => 1, | |
| 121 | + '_etext' => 1, | |
| 122 | + '_edata' => 1, | |
| 123 | + '_end' => 1, | |
| 124 | + '__bss_start' => 1, | |
| 125 | + '_text' => 1, | |
| 126 | + '_stext' => 1, | |
| 127 | + '__gp' => 1, | |
| 128 | + 'ia64_unw_start' => 1, | |
| 129 | + 'ia64_unw_end' => 1, | |
| 130 | + '__init_begin' => 1, | |
| 131 | + '__init_end' => 1, | |
| 132 | + '__bss_stop' => 1, | |
| 133 | + '__nosave_begin' => 1, | |
| 134 | + '__nosave_end' => 1, | |
| 135 | + 'pg0' => 1, | |
| 136 | + 'vdso_enabled' => 1, | |
| 137 | + '__stack_chk_fail' => 1, | |
| 138 | + 'VDSO32_PRELINK' => 1, | |
| 139 | + 'VDSO32_vsyscall' => 1, | |
| 140 | + 'VDSO32_rt_sigreturn'=>1, | |
| 141 | + 'VDSO32_sigreturn' => 1, | |
| 142 | +); | |
| 143 | + | |
| 144 | + | |
| 87 | 145 | &find(\&linux_objects, '.'); # find the objects and do_nm on them |
| 88 | 146 | &list_multiply_defined(); |
| 89 | 147 | &resolve_external_references(); |
| @@ -105,7 +163,8 @@ sub linux_objects · 15 unmodified lines | ||
| 105 | 163 | if (/.*\.o$/ && |
| 106 | 164 | ! ( |
| 107 | 165 | m:/built-in.o$: |
| 108 | − || m:arch/x86/kernel/vsyscall-syms.o$: | |
| 166 | + || m:arch/x86/vdso/: | |
| 167 | + || m:arch/x86/boot/: | |
| 109 | 168 | || m:arch/ia64/ia32/ia32.o$: |
| 110 | 169 | || m:arch/ia64/kernel/gate-syms.o$: |
| 111 | 170 | || m:arch/ia64/lib/__divdi3.o$: |
| @@ -148,6 +207,7 @@ sub linux_objects · 36 unmodified lines | ||
| 148 | 207 | || m:^.*/\.tmp_: |
| 149 | 208 | || m:^\.tmp_: |
| 150 | 209 | || m:/vmlinux-obj.o$: |
| 210 | + || m:^tools/: | |
| 151 | 211 | ) |
| 152 | 212 | ) { |
| 153 | 213 | do_nm($basename, $_); |
| @@ -167,11 +227,11 @@ sub do_nm · 13 unmodified lines | ||
| 167 | 227 | printf STDERR "$fullname is not an object file\n"; |
| 168 | 228 | return; |
| 169 | 229 | } |
| 170 | − ($source = $fullname) =~ s/\.o$//; | |
| 171 | − if (-e "$objtree$source.c" || -e "$objtree$source.S") { | |
| 172 | − $source = "$objtree$source"; | |
| 230 | + ($source = $basename) =~ s/\.o$//; | |
| 231 | + if (-e "$source.c" || -e "$source.S") { | |
| 232 | + $source = "$objtree$File::Find::dir/$source"; | |
| 173 | 233 | } else { |
| 174 | − $source = "$srctree$source"; | |
| 234 | + $source = "$srctree$File::Find::dir/$source"; | |
| 175 | 235 | } |
| 176 | 236 | if (! -e "$source.c" && ! -e "$source.S") { |
| 177 | 237 | # No obvious source, exclude the object if it is conglomerate |
| @@ -214,6 +274,7 @@ sub do_nm · 36 unmodified lines | ||
| 214 | 274 | # T global label/procedure |
| 215 | 275 | # U external reference |
| 216 | 276 | # W weak external reference to text that has been resolved |
| 277 | + # V similar to W, but the value of the weak symbol becomes zero with no error. | |
| 217 | 278 | # a assembler equate |
| 218 | 279 | # b static variable, uninitialised |
| 219 | 280 | # d static variable, initialised |
| @@ -222,8 +283,9 @@ sub do_nm · 2 unmodified lines | ||
| 222 | 283 | # s static variable, uninitialised, small bss |
| 223 | 284 | # t static label/procedures |
| 224 | 285 | # w weak external reference to text that has not been resolved |
| 286 | + # v similar to w | |
| 225 | 287 | # ? undefined type, used a lot by modules |
| 226 | − if ($type !~ /^[ABCDGRSTUWabdgrstw?]$/) { | |
| 288 | + if ($type !~ /^[ABCDGRSTUWVabdgrstwv?]$/) { | |
| 227 | 289 | printf STDERR "nm output for $fullname contains unknown type '$_'\n"; |
| 228 | 290 | } |
| 229 | 291 | elsif ($name =~ /\./) { |
| @@ -234,7 +296,7 @@ sub do_nm · 4 unmodified lines | ||
| 234 | 296 | # binutils keeps changing the type for exported symbols, force it to R |
| 235 | 297 | $type = 'R' if ($name =~ /^__ksymtab/ || $name =~ /^__kstrtab/); |
| 236 | 298 | $name =~ s/_R[a-f0-9]{8}$//; # module versions adds this |
| 237 | − if ($type =~ /[ABCDGRSTW]/ && | |
| 299 | + if ($type =~ /[ABCDGRSTWV]/ && | |
| 238 | 300 | $name ne 'init_module' && |
| 239 | 301 | $name ne 'cleanup_module' && |
| 240 | 302 | $name ne 'Using_Versions' && |
| @@ -270,27 +332,9 @@ sub do_nm · 29 unmodified lines | ||
| 270 | 332 | close($nmdata); |
| 271 | 333 | |
| 272 | 334 | if ($#nmdata < 0) { |
| 273 | − if ( | |
| 274 | − $fullname ne "lib/brlock.o" | |
| 275 | − && $fullname ne "lib/dec_and_lock.o" | |
| 276 | − && $fullname ne "fs/xfs/xfs_macros.o" | |
| 277 | − && $fullname ne "drivers/ide/ide-probe-mini.o" | |
| 278 | − && $fullname ne "usr/initramfs_data.o" | |
| 279 | − && $fullname ne "drivers/acpi/executer/exdump.o" | |
| 280 | − && $fullname ne "drivers/acpi/resources/rsdump.o" | |
| 281 | − && $fullname ne "drivers/acpi/namespace/nsdumpdv.o" | |
| 282 | − && $fullname ne "drivers/acpi/namespace/nsdump.o" | |
| 283 | − && $fullname ne "arch/ia64/sn/kernel/sn2/io.o" | |
| 284 | − && $fullname ne "arch/ia64/kernel/gate-data.o" | |
| 285 | − && $fullname ne "drivers/ieee1394/oui.o" | |
| 286 | − && $fullname ne "security/capability.o" | |
| 287 | − && $fullname ne "sound/core/wrappers.o" | |
| 288 | − && $fullname ne "fs/ntfs/sysctl.o" | |
| 289 | − && $fullname ne "fs/jfs/jfs_debug.o" | |
| 290 | − ) { | |
| 291 | − printf "No nm data for $fullname\n"; | |
| 292 | − } | |
| 293 | − return; | |
| 335 | + printf "No nm data for $fullname\n" | |
| 336 | + unless $nmexception{$fullname}; | |
| 337 | + return; | |
| 294 | 338 | } |
| 295 | 339 | $nmdata{$fullname} = \@nmdata; |
| 296 | 340 | } |
| @@ -319,18 +363,14 @@ sub list_multiply_defined · 22 unmodified lines | ||
| 319 | 363 | foreach my $name (keys(%def)) { |
| 320 | 364 | if ($#{$def{$name}} > 0) { |
| 321 | 365 | # Special case for cond_syscall |
| 322 | − if ($#{$def{$name}} == 1 && $name =~ /^sys_/ && | |
| 323 | − ($def{$name}[0] eq "kernel/sys.o" || | |
| 324 | − $def{$name}[1] eq "kernel/sys.o")) { | |
| 325 | − &drop_def("kernel/sys.o", $name); | |
| 326 | − next; | |
| 327 | − } | |
| 328 | − # Special case for i386 entry code | |
| 329 | − if ($#{$def{$name}} == 1 && $name =~ /^__kernel_/ && | |
| 330 | − $def{$name}[0] eq "arch/x86/kernel/vsyscall-int80_32.o" && | |
| 331 | − $def{$name}[1] eq "arch/x86/kernel/vsyscall-sysenter_32.o") { | |
| 332 | − &drop_def("arch/x86/kernel/vsyscall-sysenter_32.o", $name); | |
| 333 | − next; | |
| 366 | + if ($#{$def{$name}} == 1 && | |
| 367 | + ($name =~ /^sys_/ || $name =~ /^compat_sys_/ || | |
| 368 | + $name =~ /^sys32_/)) { | |
| 369 | + if($def{$name}[0] eq "kernel/sys_ni.o" || | |
| 370 | + $def{$name}[1] eq "kernel/sys_ni.o") { | |
| 371 | + &drop_def("kernel/sys_ni.o", $name); | |
| 372 | + next; | |
| 373 | + } | |
| 334 | 374 | } |
| 335 | 375 | |
| 336 | 376 | printf "$name is multiply defined in :-\n"; |
| @@ -372,31 +412,7 @@ sub resolve_external_references · 35 unmodified lines | ||
| 372 | 412 | $ref{$name} = "" |
| 373 | 413 | } |
| 374 | 414 | } |
| 375 | − elsif ( $name ne "mod_use_count_" | |
| 376 | − && $name ne "__initramfs_end" | |
| 377 | − && $name ne "__initramfs_start" | |
| 378 | − && $name ne "_einittext" | |
| 379 | − && $name ne "_sinittext" | |
| 380 | − && $name ne "kallsyms_names" | |
| 381 | − && $name ne "kallsyms_num_syms" | |
| 382 | − && $name ne "kallsyms_addresses" | |
| 383 | − && $name ne "__this_module" | |
| 384 | − && $name ne "_etext" | |
| 385 | − && $name ne "_edata" | |
| 386 | − && $name ne "_end" | |
| 387 | − && $name ne "__bss_start" | |
| 388 | − && $name ne "_text" | |
| 389 | − && $name ne "_stext" | |
| 390 | − && $name ne "__gp" | |
| 391 | − && $name ne "ia64_unw_start" | |
| 392 | − && $name ne "ia64_unw_end" | |
| 393 | − && $name ne "__init_begin" | |
| 394 | − && $name ne "__init_end" | |
| 395 | − && $name ne "__bss_stop" | |
| 396 | − && $name ne "__nosave_begin" | |
| 397 | − && $name ne "__nosave_end" | |
| 398 | − && $name ne "pg0" | |
| 399 | − && $name ne "__module_text_address" | |
| 415 | + elsif ( ! $nameexception{$name} | |
| 400 | 416 | && $name !~ /^__sched_text_/ |
| 401 | 417 | && $name !~ /^__start_/ |
| 402 | 418 | && $name !~ /^__end_/ |
| @@ -407,7 +423,6 @@ sub resolve_external_references · 4 unmodified lines | ||
| 407 | 423 | && $name !~ /^__.*per_cpu_end/ |
| 408 | 424 | && $name !~ /^__alt_instructions/ |
| 409 | 425 | && $name !~ /^__setup_/ |
| 410 | − && $name !~ /^jiffies/ | |
| 411 | 426 | && $name !~ /^__mod_timer/ |
| 412 | 427 | && $name !~ /^__mod_page_state/ |
| 413 | 428 | && $name !~ /^init_module/ |