This patch ensures that all semantic patches in the scripts/coccinelle directory provide the report option. Report messages that include line numbers now have the line number preceded by "line" for easier subsequent processing.
Showing the changes to scripts (11 of 11 files). Show all
Unified · Split
| @@ -1,16 +1,19 @@ | |||
| 1 | /// Use kstrdup rather than duplicating its implementation | 1 | /// Use kstrdup rather than duplicating its implementation |
| 2 | /// | 2 | /// |
| 3 | // Confidence: High | 3 | // Confidence: High |
| 4 | // Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. | 4 | // Copyright: (C) 2010-2012 Nicolas Palix. GPLv2. |
| 5 | // Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. | 5 | // Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6. GPLv2. |
| 6 | // Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. | 6 | // Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6. GPLv2. |
| 7 | // URL: http://coccinelle.lip6.fr/ | 7 | // URL: http://coccinelle.lip6.fr/ |
| 8 | // Comments: | 8 | // Comments: |
| 9 | // Options: -no_includes -include_headers | 9 | // Options: -no_includes -include_headers |
| 10 | 10 | ||
| 11 | virtual patch | 11 | virtual patch |
| 12 | virtual context | ||
| 13 | virtual org | ||
| 14 | virtual report | ||
| 12 | 15 | ||
| 13 | @@ | 16 | @depends on patch@ |
| 14 | expression from,to; | 17 | expression from,to; |
| 15 | expression flag,E1,E2; | 18 | expression flag,E1,E2; |
| 16 | statement S; | 19 | statement S; |
| @@ -23,7 +26,7 @@ statement S; · 6 unmodified lines | |||
| 23 | ... when != \(from = E2 \| to = E2 \) | 26 | ... when != \(from = E2 \| to = E2 \) |
| 24 | - strcpy(to, from); | 27 | - strcpy(to, from); |
| 25 | 28 | ||
| 26 | @@ | 29 | @depends on patch@ |
| 27 | expression x,from,to; | 30 | expression x,from,to; |
| 28 | expression flag,E1,E2,E3; | 31 | expression flag,E1,E2,E3; |
| 29 | statement S; | 32 | statement S; |
| @@ -37,3 +40,65 @@ statement S; · 7 unmodified lines | |||
| 37 | if (to==NULL || ...) S | 40 | if (to==NULL || ...) S |
| 38 | ... when != \(x = E3 \| from = E3 \| to = E3 \) | 41 | ... when != \(x = E3 \| from = E3 \| to = E3 \) |
| 39 | - memcpy(to, from, x); | 42 | - memcpy(to, from, x); |
| 43 | |||
| 44 | // --------------------------------------------------------------------- | ||
| 45 | |||
| 46 | @r1 depends on !patch exists@ | ||
| 47 | expression from,to; | ||
| 48 | expression flag,E1,E2; | ||
| 49 | statement S; | ||
| 50 | position p1,p2; | ||
| 51 | @@ | ||
| 52 | |||
| 53 | * to = kmalloc@p1(strlen(from) + 1,flag); | ||
| 54 | ... when != \(from = E1 \| to = E1 \) | ||
| 55 | if (to==NULL || ...) S | ||
| 56 | ... when != \(from = E2 \| to = E2 \) | ||
| 57 | * strcpy@p2(to, from); | ||
| 58 | |||
| 59 | @r2 depends on !patch exists@ | ||
| 60 | expression x,from,to; | ||
| 61 | expression flag,E1,E2,E3; | ||
| 62 | statement S; | ||
| 63 | position p1,p2; | ||
| 64 | @@ | ||
| 65 | |||
| 66 | * x = strlen(from) + 1; | ||
| 67 | ... when != \( x = E1 \| from = E1 \) | ||
| 68 | * to = \(kmalloc@p1\|kzalloc@p2\)(x,flag); | ||
| 69 | ... when != \(x = E2 \| from = E2 \| to = E2 \) | ||
| 70 | if (to==NULL || ...) S | ||
| 71 | ... when != \(x = E3 \| from = E3 \| to = E3 \) | ||
| 72 | * memcpy@p2(to, from, x); | ||
| 73 | |||
| 74 | @script:python depends on org@ | ||
| 75 | p1 << r1.p1; | ||
| 76 | p2 << r1.p2; | ||
| 77 | @@ | ||
| 78 | |||
| 79 | cocci.print_main("WARNING opportunity for kstrdep",p1) | ||
| 80 | cocci.print_secs("strcpy",p2) | ||
| 81 | |||
| 82 | @script:python depends on org@ | ||
| 83 | p1 << r2.p1; | ||
| 84 | p2 << r2.p2; | ||
| 85 | @@ | ||
| 86 | |||
| 87 | cocci.print_main("WARNING opportunity for kstrdep",p1) | ||
| 88 | cocci.print_secs("memcpy",p2) | ||
| 89 | |||
| 90 | @script:python depends on report@ | ||
| 91 | p1 << r1.p1; | ||
| 92 | p2 << r1.p2; | ||
| 93 | @@ | ||
| 94 | |||
| 95 | msg = "WARNING opportunity for kstrdep (strcpy on line %s)" % (p2[0].line) | ||
| 96 | coccilib.report.print_report(p1[0], msg) | ||
| 97 | |||
| 98 | @script:python depends on report@ | ||
| 99 | p1 << r2.p1; | ||
| 100 | p2 << r2.p2; | ||
| 101 | @@ | ||
| 102 | |||
| 103 | msg = "WARNING opportunity for kstrdep (memcpy on line %s)" % (p2[0].line) | ||
| 104 | coccilib.report.print_report(p1[0], msg) | ||
| @@ -1,14 +1,17 @@ | |||
| 1 | /// Use kmemdup rather than duplicating its implementation | 1 | /// Use kmemdup rather than duplicating its implementation |
| 2 | /// | 2 | /// |
| 3 | // Confidence: High | 3 | // Confidence: High |
| 4 | // Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. | 4 | // Copyright: (C) 2010-2012 Nicolas Palix. GPLv2. |
| 5 | // Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. | 5 | // Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6. GPLv2. |
| 6 | // Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. | 6 | // Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6. GPLv2. |
| 7 | // URL: http://coccinelle.lip6.fr/ | 7 | // URL: http://coccinelle.lip6.fr/ |
| 8 | // Comments: | 8 | // Comments: |
| 9 | // Options: -no_includes -include_headers | 9 | // Options: -no_includes -include_headers |
| 10 | 10 | ||
| 11 | virtual patch | 11 | virtual patch |
| 12 | virtual context | ||
| 13 | virtual org | ||
| 14 | virtual report | ||
| 12 | 15 | ||
| 13 | @r1@ | 16 | @r1@ |
| 14 | expression from,to; | 17 | expression from,to; |
| @@ -28,7 +31,7 @@ position p; · 13 unmodified lines | |||
| 28 | ... when != \( x = E1 \| from = E1 \) | 31 | ... when != \( x = E1 \| from = E1 \) |
| 29 | to = \(kmalloc@p\|kzalloc@p\)(x,flag); | 32 | to = \(kmalloc@p\|kzalloc@p\)(x,flag); |
| 30 | 33 | ||
| 31 | @@ | 34 | @depends on patch@ |
| 32 | expression from,to,size,flag; | 35 | expression from,to,size,flag; |
| 33 | position p != {r1.p,r2.p}; | 36 | position p != {r1.p,r2.p}; |
| 34 | statement S; | 37 | statement S; |
| @@ -38,3 +41,26 @@ statement S; · 3 unmodified lines | |||
| 38 | + to = kmemdup(from,size,flag); | 41 | + to = kmemdup(from,size,flag); |
| 39 | if (to==NULL || ...) S | 42 | if (to==NULL || ...) S |
| 40 | - memcpy(to, from, size); | 43 | - memcpy(to, from, size); |
| 44 | |||
| 45 | @r depends on !patch@ | ||
| 46 | expression from,to,size,flag; | ||
| 47 | position p != {r1.p,r2.p}; | ||
| 48 | statement S; | ||
| 49 | @@ | ||
| 50 | |||
| 51 | * to = \(kmalloc@p\|kzalloc@p\)(size,flag); | ||
| 52 | to = kmemdup(from,size,flag); | ||
| 53 | if (to==NULL || ...) S | ||
| 54 | * memcpy(to, from, size); | ||
| 55 | |||
| 56 | @script:python depends on org@ | ||
| 57 | p << r.p; | ||
| 58 | @@ | ||
| 59 | |||
| 60 | coccilib.org.print_todo(p[0], "WARNING opportunity for kmemdep") | ||
| 61 | |||
| 62 | @script:python depends on report@ | ||
| 63 | p << r.p; | ||
| 64 | @@ | ||
| 65 | |||
| 66 | coccilib.report.print_report(p[0], "WARNING opportunity for kmemdep") | ||
| @@ -1,23 +1,25 @@ | |||
| 1 | /// Use kmemdup_user rather than duplicating its implementation | 1 | /// Use memdup_user rather than duplicating its implementation |
| 2 | /// This is a little bit restricted to reduce false positives | 2 | /// This is a little bit restricted to reduce false positives |
| 3 | /// | 3 | /// |
| 4 | // Confidence: High | 4 | // Confidence: High |
| 5 | // Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. | 5 | // Copyright: (C) 2010-2012 Nicolas Palix. GPLv2. |
| 6 | // Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. | 6 | // Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6. GPLv2. |
| 7 | // Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. | 7 | // Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6. GPLv2. |
| 8 | // URL: http://coccinelle.lip6.fr/ | 8 | // URL: http://coccinelle.lip6.fr/ |
| 9 | // Comments: | 9 | // Comments: |
| 10 | // Options: -no_includes -include_headers | 10 | // Options: -no_includes -include_headers |
| 11 | 11 | ||
| 12 | virtual patch | 12 | virtual patch |
| 13 | virtual context | ||
| 14 | virtual org | ||
| 15 | virtual report | ||
| 13 | 16 | ||
| 14 | @@ | 17 | @depends on patch@ |
| 15 | expression from,to,size,flag; | 18 | expression from,to,size,flag; |
| 16 | position p; | ||
| 17 | identifier l1,l2; | 19 | identifier l1,l2; |
| 18 | @@ | 20 | @@ |
| 19 | 21 | ||
| 20 | - to = \(kmalloc@p\|kzalloc@p\)(size,flag); | 22 | - to = \(kmalloc\|kzalloc\)(size,flag); |
| 21 | + to = memdup_user(from,size); | 23 | + to = memdup_user(from,size); |
| 22 | if ( | 24 | if ( |
| 23 | - to==NULL | 25 | - to==NULL |
| @@ -33,3 +35,26 @@ identifier l1,l2; · 9 unmodified lines | |||
| 33 | - -EFAULT | 35 | - -EFAULT |
| 34 | - ...+> | 36 | - ...+> |
| 35 | - } | 37 | - } |
| 38 | |||
| 39 | @r depends on !patch@ | ||
| 40 | expression from,to,size,flag; | ||
| 41 | position p; | ||
| 42 | statement S1,S2; | ||
| 43 | @@ | ||
| 44 | |||
| 45 | * to = \(kmalloc@p\|kzalloc@p\)(size,flag); | ||
| 46 | if (to==NULL || ...) S1 | ||
| 47 | if (copy_from_user(to, from, size) != 0) | ||
| 48 | S2 | ||
| 49 | |||
| 50 | @script:python depends on org@ | ||
| 51 | p << r.p; | ||
| 52 | @@ | ||
| 53 | |||
| 54 | coccilib.org.print_todo(p[0], "WARNING opportunity for memdep_user") | ||
| 55 | |||
| 56 | @script:python depends on report@ | ||
| 57 | p << r.p; | ||
| 58 | @@ | ||
| 59 | |||
| 60 | coccilib.report.print_report(p[0], "WARNING opportunity for memdep_user") | ||
| @@ -5,9 +5,9 @@ · 4 unmodified lines | |||
| 5 | //# SCTP_DBG_OBJCNT_DEC that do not actually evaluate their argument | 5 | //# SCTP_DBG_OBJCNT_DEC that do not actually evaluate their argument |
| 6 | /// | 6 | /// |
| 7 | // Confidence: Moderate | 7 | // Confidence: Moderate |
| 8 | // Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. | 8 | // Copyright: (C) 2010-2012 Nicolas Palix. GPLv2. |
| 9 | // Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. | 9 | // Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6. GPLv2. |
| 10 | // Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. | 10 | // Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6. GPLv2. |
| 11 | // URL: http://coccinelle.lip6.fr/ | 11 | // URL: http://coccinelle.lip6.fr/ |
| 12 | // Comments: | 12 | // Comments: |
| 13 | // Options: -no_includes -include_headers | 13 | // Options: -no_includes -include_headers |
| @@ -23,7 +23,7 @@ position p1; · 9 unmodified lines | |||
| 23 | kfree@p1(E) | 23 | kfree@p1(E) |
| 24 | 24 | ||
| 25 | @print expression@ | 25 | @print expression@ |
| 26 | constant char *c; | 26 | constant char [] c; |
| 27 | expression free.E,E2; | 27 | expression free.E,E2; |
| 28 | type T; | 28 | type T; |
| 29 | position p; | 29 | position p; |
| @@ -36,6 +36,10 @@ identifier f; · 6 unmodified lines | |||
| 36 | E@p == E2 | 36 | E@p == E2 |
| 37 | | | 37 | | |
| 38 | E@p != E2 | 38 | E@p != E2 |
| 39 | | | ||
| 40 | E2 == E@p | ||
| 41 | | | ||
| 42 | E2 != E@p | ||
| 39 | | | 43 | | |
| 40 | !E@p | 44 | !E@p |
| 41 | | | 45 | | |
| @@ -113,5 +117,5 @@ p1 << free.p1; · 71 unmodified lines | |||
| 113 | p2 << r.p2; | 117 | p2 << r.p2; |
| 114 | @@ | 118 | @@ |
| 115 | 119 | ||
| 116 | msg = "reference preceded by free on line %s" % (p1[0].line) | 120 | msg = "ERROR: reference preceded by free on line %s" % (p1[0].line) |
| 117 | coccilib.report.print_report(p2[0],msg) | 121 | coccilib.report.print_report(p2[0],msg) |
| @@ -2,16 +2,19 @@ · 1 unmodified line | |||
| 2 | /// is no point to call of_node_put on the final value. | 2 | /// is no point to call of_node_put on the final value. |
| 3 | /// | 3 | /// |
| 4 | // Confidence: High | 4 | // Confidence: High |
| 5 | // Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. | 5 | // Copyright: (C) 2010-2012 Nicolas Palix. GPLv2. |
| 6 | // Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. | 6 | // Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6. GPLv2. |
| 7 | // Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. | 7 | // Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6. GPLv2. |
| 8 | // URL: http://coccinelle.lip6.fr/ | 8 | // URL: http://coccinelle.lip6.fr/ |
| 9 | // Comments: | 9 | // Comments: |
| 10 | // Options: -no_includes -include_headers | 10 | // Options: -no_includes -include_headers |
| 11 | 11 | ||
| 12 | virtual patch | 12 | virtual patch |
| 13 | virtual context | ||
| 14 | virtual org | ||
| 15 | virtual report | ||
| 13 | 16 | ||
| 14 | @@ | 17 | @depends on patch@ |
| 15 | iterator name for_each_node_by_name; | 18 | iterator name for_each_node_by_name; |
| 16 | expression np,E; | 19 | expression np,E; |
| 17 | identifier l; | 20 | identifier l; |
| @@ -24,7 +27,7 @@ for_each_node_by_name(np,...) { · 6 unmodified lines | |||
| 24 | ... when != np = E | 27 | ... when != np = E |
| 25 | - of_node_put(np); | 28 | - of_node_put(np); |
| 26 | 29 | ||
| 27 | @@ | 30 | @depends on patch@ |
| 28 | iterator name for_each_node_by_type; | 31 | iterator name for_each_node_by_type; |
| 29 | expression np,E; | 32 | expression np,E; |
| 30 | identifier l; | 33 | identifier l; |
| @@ -37,7 +40,7 @@ for_each_node_by_type(np,...) { · 6 unmodified lines | |||
| 37 | ... when != np = E | 40 | ... when != np = E |
| 38 | - of_node_put(np); | 41 | - of_node_put(np); |
| 39 | 42 | ||
| 40 | @@ | 43 | @depends on patch@ |
| 41 | iterator name for_each_compatible_node; | 44 | iterator name for_each_compatible_node; |
| 42 | expression np,E; | 45 | expression np,E; |
| 43 | identifier l; | 46 | identifier l; |
| @@ -50,7 +53,7 @@ for_each_compatible_node(np,...) { · 6 unmodified lines | |||
| 50 | ... when != np = E | 53 | ... when != np = E |
| 51 | - of_node_put(np); | 54 | - of_node_put(np); |
| 52 | 55 | ||
| 53 | @@ | 56 | @depends on patch@ |
| 54 | iterator name for_each_matching_node; | 57 | iterator name for_each_matching_node; |
| 55 | expression np,E; | 58 | expression np,E; |
| 56 | identifier l; | 59 | identifier l; |
| @@ -62,3 +65,59 @@ for_each_matching_node(np,...) { · 5 unmodified lines | |||
| 62 | } | 65 | } |
| 63 | ... when != np = E | 66 | ... when != np = E |
| 64 | - of_node_put(np); | 67 | - of_node_put(np); |
| 68 | |||
| 69 | // ---------------------------------------------------------------------- | ||
| 70 | |||
| 71 | @r depends on !patch forall@ | ||
| 72 | //iterator name for_each_node_by_name; | ||
| 73 | //iterator name for_each_node_by_type; | ||
| 74 | //iterator name for_each_compatible_node; | ||
| 75 | //iterator name for_each_matching_node; | ||
| 76 | expression np,E; | ||
| 77 | identifier l; | ||
| 78 | position p1,p2; | ||
| 79 | @@ | ||
| 80 | |||
| 81 | ( | ||
| 82 | *for_each_node_by_name@p1(np,...) | ||
| 83 | { | ||
| 84 | ... when != break; | ||
| 85 | when != goto l; | ||
| 86 | } | ||
| 87 | | | ||
| 88 | *for_each_node_by_type@p1(np,...) | ||
| 89 | { | ||
| 90 | ... when != break; | ||
| 91 | when != goto l; | ||
| 92 | } | ||
| 93 | | | ||
| 94 | *for_each_compatible_node@p1(np,...) | ||
| 95 | { | ||
| 96 | ... when != break; | ||
| 97 | when != goto l; | ||
| 98 | } | ||
| 99 | | | ||
| 100 | *for_each_matching_node@p1(np,...) | ||
| 101 | { | ||
| 102 | ... when != break; | ||
| 103 | when != goto l; | ||
| 104 | } | ||
| 105 | ) | ||
| 106 | ... when != np = E | ||
| 107 | * of_node_put@p2(np); | ||
| 108 | |||
| 109 | @script:python depends on org@ | ||
| 110 | p1 << r.p1; | ||
| 111 | p2 << r.p2; | ||
| 112 | @@ | ||
| 113 | |||
| 114 | cocci.print_main("unneeded of_node_put",p2) | ||
| 115 | cocci.print_secs("iterator",p1) | ||
| 116 | |||
| 117 | @script:python depends on report@ | ||
| 118 | p1 << r.p1; | ||
| 119 | p2 << r.p2; | ||
| 120 | @@ | ||
| 121 | |||
| 122 | msg = "ERROR: of_node_put not needed after iterator on line %s" % (p1[0].line) | ||
| 123 | coccilib.report.print_report(p2[0], msg) | ||
| @@ -1,20 +1,24 @@ | |||
| 1 | /// Many iterators have the property that the first argument is always bound | 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 | 2 | /// to a real list element, never NULL. |
| 3 | /// iterators that do not have this property, or in cases when the loop | 3 | //# False positives arise for some iterators that do not have this property, |
| 4 | /// cursor is reassigned. The latter should only happen when the matched | 4 | //# or in cases when the loop cursor is reassigned. The latter should only |
| 5 | /// code is on the way to a loop exit (break, goto, or return). | 5 | //# happen when the matched code is on the way to a loop exit (break, goto, |
| 6 | //# or return). | ||
| 6 | /// | 7 | /// |
| 7 | // Confidence: Moderate | 8 | // Confidence: Moderate |
| 8 | // Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. | 9 | // Copyright: (C) 2010-2012 Nicolas Palix. GPLv2. |
| 9 | // Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. | 10 | // Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6. GPLv2. |
| 10 | // Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. | 11 | // Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6. GPLv2. |
| 11 | // URL: http://coccinelle.lip6.fr/ | 12 | // URL: http://coccinelle.lip6.fr/ |
| 12 | // Comments: | 13 | // Comments: |
| 13 | // Options: -no_includes -include_headers | 14 | // Options: -no_includes -include_headers |
| 14 | 15 | ||
| 15 | virtual patch | 16 | virtual patch |
| 17 | virtual context | ||
| 18 | virtual org | ||
| 19 | virtual report | ||
| 16 | 20 | ||
| 17 | @@ | 21 | @depends on patch@ |
| 18 | iterator I; | 22 | iterator I; |
| 19 | expression x,E,E1,E2; | 23 | expression x,E,E1,E2; |
| 20 | statement S,S1,S2; | 24 | statement S,S1,S2; |
| @@ -55,4 +59,36 @@ I(x,...) { <... · 34 unmodified lines | |||
| 55 | x != NULL | 59 | x != NULL |
| 56 | + ) | 60 | + ) |
| 57 | ) | 61 | ) |
| 58 | ...> } | 62 | ...> } |
| 63 | |||
| 64 | @r depends on !patch exists@ | ||
| 65 | iterator I; | ||
| 66 | expression x,E; | ||
| 67 | position p1,p2; | ||
| 68 | @@ | ||
| 69 | |||
| 70 | *I@p1(x,...) | ||
| 71 | { ... when != x = E | ||
| 72 | ( | ||
| 73 | * x@p2 == NULL | ||
| 74 | | | ||
| 75 | * x@p2 != NULL | ||
| 76 | ) | ||
| 77 | ... when any | ||
| 78 | } | ||
| 79 | |||
| 80 | @script:python depends on org@ | ||
| 81 | p1 << r.p1; | ||
| 82 | p2 << r.p2; | ||
| 83 | @@ | ||
| 84 | |||
| 85 | cocci.print_main("iterator-bound variable",p1) | ||
| 86 | cocci.print_secs("useless NULL test",p2) | ||
| 87 | |||
| 88 | @script:python depends on report@ | ||
| 89 | p1 << r.p1; | ||
| 90 | p2 << r.p2; | ||
| 91 | @@ | ||
| 92 | |||
| 93 | msg = "ERROR: iterator variable bound on line %s cannot be NULL" % (p1[0].line) | ||
| 94 | coccilib.report.print_report(p2[0], msg) | ||
| @@ -1,17 +1,20 @@ | |||
| 1 | /// Find functions that refer to GFP_KERNEL but are called with locks held. | 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 | 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 | 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. | 4 | //# function under the lock in the first place. |
| 5 | /// | 5 | /// |
| 6 | // Confidence: Moderate | 6 | // Confidence: Moderate |
| 7 | // Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. | 7 | // Copyright: (C) 2012 Nicolas Palix. GPLv2. |
| 8 | // Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. | 8 | // Copyright: (C) 2012 Julia Lawall, INRIA/LIP6. GPLv2. |
| 9 | // Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. | 9 | // Copyright: (C) 2012 Gilles Muller, INRIA/LiP6. GPLv2. |
| 10 | // URL: http://coccinelle.lip6.fr/ | 10 | // URL: http://coccinelle.lip6.fr/ |
| 11 | // Comments: | 11 | // Comments: |
| 12 | // Options: -no_includes -include_headers | 12 | // Options: -no_includes -include_headers |
| 13 | 13 | ||
| 14 | virtual patch | 14 | virtual patch |
| 15 | virtual context | ||
| 16 | virtual org | ||
| 17 | virtual report | ||
| 15 | 18 | ||
| 16 | @gfp exists@ | 19 | @gfp exists@ |
| 17 | identifier fn; | 20 | identifier fn; |
| @@ -32,28 +35,29 @@ fn(...) { · 14 unmodified lines | |||
| 32 | ... when any | 35 | ... when any |
| 33 | } | 36 | } |
| 34 | 37 | ||
| 35 | @locked@ | 38 | @locked exists@ |
| 36 | identifier gfp.fn; | 39 | identifier gfp.fn; |
| 40 | position p1,p2; | ||
| 37 | @@ | 41 | @@ |
| 38 | 42 | ||
| 39 | ( | 43 | ( |
| 40 | read_lock_irq | 44 | read_lock_irq@p1 |
| 41 | | | 45 | | |
| 42 | write_lock_irq | 46 | write_lock_irq@p1 |
| 43 | | | 47 | | |
| 44 | read_lock_irqsave | 48 | read_lock_irqsave@p1 |
| 45 | | | 49 | | |
| 46 | write_lock_irqsave | 50 | write_lock_irqsave@p1 |
| 47 | | | 51 | | |
| 48 | spin_lock | 52 | spin_lock@p1 |
| 49 | | | 53 | | |
| 50 | spin_trylock | 54 | spin_trylock@p1 |
| 51 | | | 55 | | |
| 52 | spin_lock_irq | 56 | spin_lock_irq@p1 |
| 53 | | | 57 | | |
| 54 | spin_lock_irqsave | 58 | spin_lock_irqsave@p1 |
| 55 | | | 59 | | |
| 56 | local_irq_disable | 60 | local_irq_disable@p1 |
| 57 | ) | 61 | ) |
| 58 | (...) | 62 | (...) |
| 59 | ... when != read_unlock_irq(...) | 63 | ... when != read_unlock_irq(...) |
| @@ -64,11 +68,38 @@ local_irq_disable · 4 unmodified lines | |||
| 64 | when != spin_unlock_irq(...) | 68 | when != spin_unlock_irq(...) |
| 65 | when != spin_unlock_irqrestore(...) | 69 | when != spin_unlock_irqrestore(...) |
| 66 | when != local_irq_enable(...) | 70 | when != local_irq_enable(...) |
| 67 | fn(...) | 71 | fn@p2(...) |
| 68 | 72 | ||
| 69 | @depends on locked@ | 73 | @depends on locked && patch@ |
| 70 | position gfp.p; | 74 | position gfp.p; |
| 71 | @@ | 75 | @@ |
| 72 | 76 | ||
| 73 | - GFP_KERNEL@p | 77 | - GFP_KERNEL@p |
| 74 | + GFP_ATOMIC | 78 | + GFP_ATOMIC |
| 79 | |||
| 80 | @depends on locked && !patch@ | ||
| 81 | position gfp.p; | ||
| 82 | @@ | ||
| 83 | |||
| 84 | * GFP_KERNEL@p | ||
| 85 | |||
| 86 | @script:python depends on !patch && org@ | ||
| 87 | p << gfp.p; | ||
| 88 | fn << gfp.fn; | ||
| 89 | p1 << locked.p1; | ||
| 90 | p2 << locked.p2; | ||
| 91 | @@ | ||
| 92 | |||
| 93 | cocci.print_main("lock",p1) | ||
| 94 | cocci.print_secs("call",p2) | ||
| 95 | cocci.print_secs("GFP_KERNEL",p) | ||
| 96 | |||
| 97 | @script:python depends on !patch && report@ | ||
| 98 | p << gfp.p; | ||
| 99 | fn << gfp.fn; | ||
| 100 | p1 << locked.p1; | ||
| 101 | p2 << locked.p2; | ||
| 102 | @@ | ||
| 103 | |||
| 104 | msg = "ERROR: function %s called on line %s inside lock on line %s but uses GFP_KERNEL" % (fn,p2[0].line,p1[0].line) | ||
| 105 | coccilib.report.print_report(p[0], msg) | ||
| @@ -1,9 +1,9 @@ | |||
| 1 | /// Find nested lock+irqsave functions that use the same flags variables | 1 | /// Find nested lock+irqsave functions that use the same flags variables |
| 2 | /// | 2 | /// |
| 3 | // Confidence: High | 3 | // Confidence: High |
| 4 | // Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. | 4 | // Copyright: (C) 2010-2012 Nicolas Palix. GPLv2. |
| 5 | // Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. | 5 | // Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6. GPLv2. |
| 6 | // Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. | 6 | // Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6. GPLv2. |
| 7 | // URL: http://coccinelle.lip6.fr/ | 7 | // URL: http://coccinelle.lip6.fr/ |
| 8 | // Comments: | 8 | // Comments: |
| 9 | // Options: -no_includes -include_headers | 9 | // Options: -no_includes -include_headers |
| @@ -12,7 +12,7 @@ virtual context · 2 unmodified lines | |||
| 12 | virtual org | 12 | virtual org |
| 13 | virtual report | 13 | virtual report |
| 14 | 14 | ||
| 15 | @r@ | 15 | @r exists@ |
| 16 | expression lock1,lock2,flags; | 16 | expression lock1,lock2,flags; |
| 17 | position p1,p2; | 17 | position p1,p2; |
| 18 | @@ | 18 | @@ |
| @@ -39,7 +39,7 @@ read_lock_irqsave@p2(lock2,flags) · 20 unmodified lines | |||
| 39 | write_lock_irqsave@p2(lock2,flags) | 39 | write_lock_irqsave@p2(lock2,flags) |
| 40 | ) | 40 | ) |
| 41 | 41 | ||
| 42 | @d@ | 42 | @d exists@ |
| 43 | expression f <= r.flags; | 43 | expression f <= r.flags; |
| 44 | expression lock1,lock2,flags; | 44 | expression lock1,lock2,flags; |
| 45 | position r.p1, r.p2; | 45 | position r.p1, r.p2; |
| @@ -76,5 +76,5 @@ p1 << r.p1; · 30 unmodified lines | |||
| 76 | p2 << r.p2; | 76 | p2 << r.p2; |
| 77 | @@ | 77 | @@ |
| 78 | 78 | ||
| 79 | msg="ERROR: nested lock+irqsave that reuses flags from %s." % (p1[0].line) | 79 | msg="ERROR: nested lock+irqsave that reuses flags from line %s." % (p1[0].line) |
| 80 | coccilib.report.print_report(p2[0], msg) | 80 | coccilib.report.print_report(p2[0], msg) |
| @@ -6,13 +6,14 @@ · 5 unmodified lines | |||
| 6 | /// function call that releases the lock. | 6 | /// function call that releases the lock. |
| 7 | /// | 7 | /// |
| 8 | // Confidence: Moderate | 8 | // Confidence: Moderate |
| 9 | // Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. | 9 | // Copyright: (C) 2010-2012 Nicolas Palix. GPLv2. |
| 10 | // Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. | 10 | // Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6. GPLv2. |
| 11 | // Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. | 11 | // Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6. GPLv2. |
| 12 | // URL: http://coccinelle.lip6.fr/ | 12 | // URL: http://coccinelle.lip6.fr/ |
| 13 | // Comments: | 13 | // Comments: |
| 14 | // Options: -no_includes -include_headers | 14 | // Options: -no_includes -include_headers |
| 15 | 15 | ||
| 16 | virtual context | ||
| 16 | virtual org | 17 | virtual org |
| 17 | virtual report | 18 | virtual report |
| 18 | 19 | ||
| @@ -57,7 +58,7 @@ position r; · 38 unmodified lines | |||
| 57 | 58 | ||
| 58 | for(...;...;...) { <+... return@r ...; ...+> } | 59 | for(...;...;...) { <+... return@r ...; ...+> } |
| 59 | 60 | ||
| 60 | @err@ | 61 | @err exists@ |
| 61 | expression E1; | 62 | expression E1; |
| 62 | position prelocked.p; | 63 | position prelocked.p; |
| 63 | position up != prelocked.p1; | 64 | position up != prelocked.p1; |
| @@ -65,14 +66,14 @@ position r!=looped.r; · 1 unmodified line | |||
| 65 | identifier lock,unlock; | 66 | identifier lock,unlock; |
| 66 | @@ | 67 | @@ |
| 67 | 68 | ||
| 68 | lock(E1@p,...); | 69 | *lock(E1@p,...); |
| 69 | <+... when != E1 | 70 | <+... when != E1 |
| 70 | if (...) { | 71 | if (...) { |
| 71 | ... when != E1 | 72 | ... when != E1 |
| 72 | return@r ...; | 73 | * return@r ...; |
| 73 | } | 74 | } |
| 74 | ...+> | 75 | ...+> |
| 75 | unlock@up(E1,...); | 76 | *unlock@up(E1,...); |
| 76 | 77 | ||
| 77 | @script:python depends on org@ | 78 | @script:python depends on org@ |
| 78 | p << prelocked.p1; | 79 | p << prelocked.p1; |
| @@ -3,9 +3,9 @@ · 2 unmodified lines | |||
| 3 | /// initialization. | 3 | /// initialization. |
| 4 | /// | 4 | /// |
| 5 | // Confidence: Low | 5 | // Confidence: Low |
| 6 | // Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. | 6 | // Copyright: (C) 2010-2012 Nicolas Palix. GPLv2. |
| 7 | // Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. | 7 | // Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6. GPLv2. |
| 8 | // Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. | 8 | // Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6. GPLv2. |
| 9 | // URL: http://coccinelle.lip6.fr/ | 9 | // URL: http://coccinelle.lip6.fr/ |
| 10 | // Comments: requires at least Coccinelle 0.2.4, lex or parse error otherwise | 10 | // Comments: requires at least Coccinelle 0.2.4, lex or parse error otherwise |
| 11 | // Options: -no_includes -include_headers | 11 | // Options: -no_includes -include_headers |
| @@ -49,5 +49,5 @@ pr << r.p; · 37 unmodified lines | |||
| 49 | @@ | 49 | @@ |
| 50 | 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)): | 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) | 52 | msg = "%s: first occurrence line %s, second occurrence line %s" % (fld,ps[0].line,pr[0].line) |
| 53 | coccilib.report.print_report(p0[0],msg) | 53 | coccilib.report.print_report(p0[0],msg) |
| @@ -1,16 +1,19 @@ | |||
| 1 | /// The various basic memory allocation functions don't return ERR_PTR | 1 | /// The various basic memory allocation functions don't return ERR_PTR |
| 2 | /// | 2 | /// |
| 3 | // Confidence: High | 3 | // Confidence: High |
| 4 | // Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. | 4 | // Copyright: (C) 2010-2012 Nicolas Palix. GPLv2. |
| 5 | // Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. | 5 | // Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6. GPLv2. |
| 6 | // Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. | 6 | // Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6. GPLv2. |
| 7 | // URL: http://coccinelle.lip6.fr/ | 7 | // URL: http://coccinelle.lip6.fr/ |
| 8 | // Comments: | 8 | // Comments: |
| 9 | // Options: -no_includes -include_headers | 9 | // Options: -no_includes -include_headers |
| 10 | 10 | ||
| 11 | virtual patch | 11 | virtual patch |
| 12 | virtual context | ||
| 13 | virtual org | ||
| 14 | virtual report | ||
| 12 | 15 | ||
| 13 | @@ | 16 | @depends on patch@ |
| 14 | expression x,E; | 17 | expression x,E; |
| 15 | @@ | 18 | @@ |
| 16 | 19 | ||
| @@ -18,3 +21,28 @@ x = \(kmalloc\|kzalloc\|kcalloc\|kmem_cache_alloc\|kmem_cache_zalloc\|kmem_cache · 1 unmodified line | |||
| 18 | ... when != x = E | 21 | ... when != x = E |
| 19 | - IS_ERR(x) | 22 | - IS_ERR(x) |
| 20 | + !x | 23 | + !x |
| 24 | |||
| 25 | @r depends on !patch exists@ | ||
| 26 | expression x,E; | ||
| 27 | position p1,p2; | ||
| 28 | @@ | ||
| 29 | |||
| 30 | *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\)(...) | ||
| 31 | ... when != x = E | ||
| 32 | * IS_ERR@p2(x) | ||
| 33 | |||
| 34 | @script:python depends on org@ | ||
| 35 | p1 << r.p1; | ||
| 36 | p2 << r.p2; | ||
| 37 | @@ | ||
| 38 | |||
| 39 | cocci.print_main("alloc call",p1) | ||
| 40 | cocci.print_secs("IS_ERR that should be NULL tests",p2) | ||
| 41 | |||
| 42 | @script:python depends on report@ | ||
| 43 | p1 << r.p1; | ||
| 44 | p2 << r.p2; | ||
| 45 | @@ | ||
| 46 | |||
| 47 | msg = "ERROR: allocation function on line %s returns NULL not ERR_PTR on failure" % (p1[0].line) | ||
| 48 | coccilib.report.print_report(p2[0], msg) | ||