From c75b81bffa0a9493a24ae61d0c52f85e4043c183 Mon Sep 17 00:00:00 2001 From: Nicolas Palix Date: Tue, 24 Aug 2010 17:38:55 +0200 Subject: Coccinelle: Add null/eno.cocci The various basic memory allocation functions don't return ERR_PTR Signed-off-by: Nicolas Palix Signed-off-by: Julia Lawall Signed-off-by: Michal Marek --- scripts/coccinelle/null/eno.cocci | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 scripts/coccinelle/null/eno.cocci (limited to 'scripts') diff --git a/scripts/coccinelle/null/eno.cocci b/scripts/coccinelle/null/eno.cocci new file mode 100644 index 000000000000..4c9c52b9c413 --- /dev/null +++ b/scripts/coccinelle/null/eno.cocci @@ -0,0 +1,20 @@ +/// The various basic memory allocation functions don't return ERR_PTR +/// +// Confidence: High +// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. +// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. +// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. +// URL: http://coccinelle.lip6.fr/ +// Comments: +// Options: -no_includes -include_headers + +virtual patch + +@@ +expression x,E; +@@ + +x = \(kmalloc\|kzalloc\|kcalloc\|kmem_cache_alloc\|kmem_cache_zalloc\|kmem_cache_alloc_node\|kmalloc_node\|kzalloc_node\)(...) +... when != x = E +- IS_ERR(x) ++ !x -- cgit v1.2.3 From 2e1e1605fc60b3fcf1e9382729a92fc305727952 Mon Sep 17 00:00:00 2001 From: Nicolas Palix Date: Tue, 24 Aug 2010 17:38:56 +0200 Subject: Coccinelle: Add null/kmerr.cocci This semantic patch looks for kmalloc etc that are not followed by a NULL check. It only gives a report in the case where there is some error handling code later in the function, which may be helpful in determining what the error handling code for the call to kmalloc etc should be. Signed-off-by: Nicolas Palix Signed-off-by: Julia Lawall Signed-off-by: Michal Marek --- scripts/coccinelle/null/kmerr.cocci | 72 +++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 scripts/coccinelle/null/kmerr.cocci (limited to 'scripts') diff --git a/scripts/coccinelle/null/kmerr.cocci b/scripts/coccinelle/null/kmerr.cocci new file mode 100644 index 000000000000..949bf656c64c --- /dev/null +++ b/scripts/coccinelle/null/kmerr.cocci @@ -0,0 +1,72 @@ +/// This semantic patch looks for kmalloc etc that are not followed by a +/// NULL check. It only gives a report in the case where there is some +/// error handling code later in the function, which may be helpful +/// in determining what the error handling code for the call to kmalloc etc +/// should be. +/// +// Confidence: High +// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. +// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. +// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. +// URL: http://coccinelle.lip6.fr/ +// Comments: +// Options: -no_includes -include_headers + +virtual context +virtual org +virtual report + +@withtest@ +expression x; +position p; +identifier f,fld; +@@ + +x@p = f(...); +... when != x->fld +\(x == NULL \| x != NULL\) + +@fixed depends on context && !org && !report@ +expression x,x1; +position p1 != withtest.p; +statement S; +position any withtest.p; +identifier f; +@@ + +*x@p1 = \(kmalloc\|kzalloc\|kcalloc\)(...); +... +*x1@p = f(...); +if (!x1) S + +// ------------------------------------------------------------------------ + +@rfixed depends on (org || report) && !context exists@ +expression x,x1; +position p1 != withtest.p; +position p2; +statement S; +position any withtest.p; +identifier f; +@@ + +x@p1 = \(kmalloc\|kzalloc\|kcalloc\)(...); +... +x1@p = f@p2(...); +if (!x1) S + +@script:python depends on org@ +p1 << rfixed.p1; +p2 << rfixed.p2; +@@ + +cocci.print_main("alloc call",p1) +cocci.print_secs("possible model",p2) + +@script:python depends on report@ +p1 << rfixed.p1; +p2 << rfixed.p2; +@@ + +msg = "alloc with no test, possible model on line %s" % (p2[0].line) +coccilib.report.print_report(p1[0],msg) -- cgit v1.2.3 From 7703692ef8d6356c32fbe9665d8cbe5b040eec09 Mon Sep 17 00:00:00 2001 From: Nicolas Palix Date: Tue, 24 Aug 2010 17:38:57 +0200 Subject: Coccinelle: Move deref_null.cocci to a more appropriate directory deref_null.cocci is moved to the 'null' directory which contains other null related rules. Signed-off-by: Nicolas Palix Signed-off-by: Julia Lawall Signed-off-by: Michal Marek --- scripts/coccinelle/deref_null.cocci | 293 ------------------------------- scripts/coccinelle/null/deref_null.cocci | 293 +++++++++++++++++++++++++++++++ 2 files changed, 293 insertions(+), 293 deletions(-) delete mode 100644 scripts/coccinelle/deref_null.cocci create mode 100644 scripts/coccinelle/null/deref_null.cocci (limited to 'scripts') diff --git a/scripts/coccinelle/deref_null.cocci b/scripts/coccinelle/deref_null.cocci deleted file mode 100644 index 9969d76d0f4b..000000000000 --- a/scripts/coccinelle/deref_null.cocci +++ /dev/null @@ -1,293 +0,0 @@ -/// -/// 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 diff --git a/scripts/coccinelle/null/deref_null.cocci b/scripts/coccinelle/null/deref_null.cocci new file mode 100644 index 000000000000..9969d76d0f4b --- /dev/null +++ b/scripts/coccinelle/null/deref_null.cocci @@ -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 -- cgit v1.2.3 From e105007c1271243568d58c8a4285b19c8eea48d1 Mon Sep 17 00:00:00 2001 From: Nicolas Palix Date: Tue, 24 Aug 2010 17:38:58 +0200 Subject: Coccinelle: Add locks/call_kern.cocci Find functions that refer to GFP_KERNEL but are called with locks held. The proposed change of converting the GFP_KERNEL is not necessarily the correct one. It may be desired to unlock the lock, or to not call the function under the lock in the first place. Signed-off-by: Nicolas Palix Signed-off-by: Julia Lawall Signed-off-by: Michal Marek --- scripts/coccinelle/locks/call_kern.cocci | 74 ++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 scripts/coccinelle/locks/call_kern.cocci (limited to 'scripts') diff --git a/scripts/coccinelle/locks/call_kern.cocci b/scripts/coccinelle/locks/call_kern.cocci new file mode 100644 index 000000000000..00af5344a68f --- /dev/null +++ b/scripts/coccinelle/locks/call_kern.cocci @@ -0,0 +1,74 @@ +/// Find functions that refer to GFP_KERNEL but are called with locks held. +/// The proposed change of converting the GFP_KERNEL is not necessarily the +/// correct one. It may be desired to unlock the lock, or to not call the +/// function under the lock in the first place. +/// +// Confidence: Moderate +// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. +// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. +// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. +// URL: http://coccinelle.lip6.fr/ +// Comments: +// Options: -no_includes -include_headers + +virtual patch + +@gfp exists@ +identifier fn; +position p; +@@ + +fn(...) { + ... when != read_unlock_irq(...) + when != write_unlock_irq(...) + when != read_unlock_irqrestore(...) + when != write_unlock_irqrestore(...) + when != spin_unlock(...) + when != spin_unlock_irq(...) + when != spin_unlock_irqrestore(...) + when != local_irq_enable(...) + when any + GFP_KERNEL@p + ... when any +} + +@locked@ +identifier gfp.fn; +@@ + +( +read_lock_irq +| +write_lock_irq +| +read_lock_irqsave +| +write_lock_irqsave +| +spin_lock +| +spin_trylock +| +spin_lock_irq +| +spin_lock_irqsave +| +local_irq_disable +) + (...) +... when != read_unlock_irq(...) + when != write_unlock_irq(...) + when != read_unlock_irqrestore(...) + when != write_unlock_irqrestore(...) + when != spin_unlock(...) + when != spin_unlock_irq(...) + when != spin_unlock_irqrestore(...) + when != local_irq_enable(...) +fn(...) + +@depends on locked@ +position gfp.p; +@@ + +- GFP_KERNEL@p ++ GFP_ATOMIC -- cgit v1.2.3 From 8aa6273106756c30e5349b58eed28d93d8d88164 Mon Sep 17 00:00:00 2001 From: Nicolas Palix Date: Tue, 24 Aug 2010 17:38:59 +0200 Subject: Coccinelle: Add locks/double_lock.cocci Find double locks. False positives may occur when some paths cannot occur at execution, due to the values of variables, and when there is an intervening function call that releases the lock. Signed-off-by: Nicolas Palix Signed-off-by: Julia Lawall Signed-off-by: Michal Marek --- scripts/coccinelle/locks/double_lock.cocci | 92 ++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 scripts/coccinelle/locks/double_lock.cocci (limited to 'scripts') diff --git a/scripts/coccinelle/locks/double_lock.cocci b/scripts/coccinelle/locks/double_lock.cocci new file mode 100644 index 000000000000..63b24e682fad --- /dev/null +++ b/scripts/coccinelle/locks/double_lock.cocci @@ -0,0 +1,92 @@ +/// Find double locks. False positives may occur when some paths cannot +/// occur at execution, due to the values of variables, and when there is +/// an intervening function call that releases the lock. +/// +// Confidence: Moderate +// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. +// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. +// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. +// URL: http://coccinelle.lip6.fr/ +// Comments: +// Options: -no_includes -include_headers + +virtual org +virtual report + +@locked@ +position p1; +expression E1; +position p; +@@ + +( +mutex_lock@p1 +| +mutex_trylock@p1 +| +spin_lock@p1 +| +spin_trylock@p1 +| +read_lock@p1 +| +read_trylock@p1 +| +write_lock@p1 +| +write_trylock@p1 +) (E1@p,...); + +@balanced@ +position p1 != locked.p1; +position locked.p; +identifier lock,unlock; +expression x <= locked.E1; +expression E,locked.E1; +expression E2; +@@ + +if (E) { + <+... when != E1 + lock(E1@p,...) + ...+> +} +... when != E1 + when != \(x = E2\|&x\) + when forall +if (E) { + <+... when != E1 + unlock@p1(E1,...) + ...+> +} + +@r depends on !balanced exists@ +expression x <= locked.E1; +expression locked.E1; +expression E2; +identifier lock; +position locked.p,p1,p2; +@@ + +lock@p1 (E1@p,...); +... when != E1 + when != \(x = E2\|&x\) +lock@p2 (E1,...); + +@script:python depends on org@ +p1 << r.p1; +p2 << r.p2; +lock << r.lock; +@@ + +cocci.print_main(lock,p1) +cocci.print_secs("second lock",p2) + +@script:python depends on report@ +p1 << r.p1; +p2 << r.p2; +lock << r.lock; +@@ + +msg = "second lock on line %s" % (p2[0].line) +coccilib.report.print_report(p1[0],msg) -- cgit v1.2.3 From 54c056280e0dfcd39b33c4ed75116ce98697511c Mon Sep 17 00:00:00 2001 From: Nicolas Palix Date: Tue, 24 Aug 2010 17:39:00 +0200 Subject: Coccinelle: Add locks/mini_lock.cocci Find missing unlocks. This semantic match considers the specific case where the unlock is missing from an if branch, and there is a lock before the if and an unlock after the if. False positives are due to cases where the if branch represents a case where the function is supposed to exit with the lock held, or where there is some preceding function call that releases the lock. Signed-off-by: Nicolas Palix Signed-off-by: Julia Lawall Signed-off-by: Michal Marek --- scripts/coccinelle/locks/mini_lock.cocci | 95 ++++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 scripts/coccinelle/locks/mini_lock.cocci (limited to 'scripts') diff --git a/scripts/coccinelle/locks/mini_lock.cocci b/scripts/coccinelle/locks/mini_lock.cocci new file mode 100644 index 000000000000..7641a2925434 --- /dev/null +++ b/scripts/coccinelle/locks/mini_lock.cocci @@ -0,0 +1,95 @@ +/// Find missing unlocks. This semantic match considers the specific case +/// where the unlock is missing from an if branch, and there is a lock +/// before the if and an unlock after the if. False positives are due to +/// cases where the if branch represents a case where the function is +/// supposed to exit with the lock held, or where there is some preceding +/// function call that releases the lock. +/// +// Confidence: Moderate +// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. +// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. +// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. +// URL: http://coccinelle.lip6.fr/ +// Comments: +// Options: -no_includes -include_headers + +virtual org +virtual report + +@prelocked@ +position p1,p; +expression E1; +@@ + +( +mutex_lock@p1 +| +mutex_trylock@p1 +| +spin_lock@p1 +| +spin_trylock@p1 +| +read_lock@p1 +| +read_trylock@p1 +| +write_lock@p1 +| +write_trylock@p1 +| +read_lock_irq@p1 +| +write_lock_irq@p1 +| +read_lock_irqsave@p1 +| +write_lock_irqsave@p1 +| +spin_lock_irq@p1 +| +spin_lock_irqsave@p1 +) (E1@p,...); + +@looped@ +position r; +@@ + +for(...;...;...) { <+... return@r ...; ...+> } + +@err@ +expression E1; +position prelocked.p; +position up != prelocked.p1; +position r!=looped.r; +identifier lock,unlock; +@@ + +lock(E1@p,...); +<+... when != E1 +if (...) { + ... when != E1 + return@r ...; +} +...+> +unlock@up(E1,...); + +@script:python depends on org@ +p << prelocked.p1; +lock << err.lock; +unlock << err.unlock; +p2 << err.r; +@@ + +cocci.print_main(lock,p) +cocci.print_secs(unlock,p2) + +@script:python depends on report@ +p << prelocked.p1; +lock << err.lock; +unlock << err.unlock; +p2 << err.r; +@@ + +msg = "preceding lock on line %s" % (p[0].line) +coccilib.report.print_report(p2[0],msg) -- cgit v1.2.3 From 4045159253a49a56d117148d67bc86a72762a0d3 Mon Sep 17 00:00:00 2001 From: Nicolas Palix Date: Tue, 24 Aug 2010 17:39:01 +0200 Subject: Coccinelle: Add iterators/fen.cocci for_each_node iterators only exit normally when the loop cursor is NULL, so there is no point to call of_node_put on the final value. Signed-off-by: Nicolas Palix Signed-off-by: Julia Lawall Signed-off-by: Michal Marek --- scripts/coccinelle/iterators/fen.cocci | 64 ++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 scripts/coccinelle/iterators/fen.cocci (limited to 'scripts') diff --git a/scripts/coccinelle/iterators/fen.cocci b/scripts/coccinelle/iterators/fen.cocci new file mode 100644 index 000000000000..77bc108c3f59 --- /dev/null +++ b/scripts/coccinelle/iterators/fen.cocci @@ -0,0 +1,64 @@ +/// These iterators only exit normally when the loop cursor is NULL, so there +/// is no point to call of_node_put on the final value. +/// +// Confidence: High +// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. +// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. +// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. +// URL: http://coccinelle.lip6.fr/ +// Comments: +// Options: -no_includes -include_headers + +virtual patch + +@@ +iterator name for_each_node_by_name; +expression np,E; +identifier l; +@@ + +for_each_node_by_name(np,...) { + ... when != break; + when != goto l; +} +... when != np = E +- of_node_put(np); + +@@ +iterator name for_each_node_by_type; +expression np,E; +identifier l; +@@ + +for_each_node_by_type(np,...) { + ... when != break; + when != goto l; +} +... when != np = E +- of_node_put(np); + +@@ +iterator name for_each_compatible_node; +expression np,E; +identifier l; +@@ + +for_each_compatible_node(np,...) { + ... when != break; + when != goto l; +} +... when != np = E +- of_node_put(np); + +@@ +iterator name for_each_matching_node; +expression np,E; +identifier l; +@@ + +for_each_matching_node(np,...) { + ... when != break; + when != goto l; +} +... when != np = E +- of_node_put(np); -- cgit v1.2.3 From afc48a82fafe55dbeeaf7c0d83d29cf279cb1c70 Mon Sep 17 00:00:00 2001 From: Nicolas Palix Date: Tue, 24 Aug 2010 17:39:02 +0200 Subject: Coccinelle: Add iterators/itnull.cocci Many iterators have the property that the first argument is always bound to a real list element, never NULL. False positives arise for some iterators that do not have this property, or in cases when the loop cursor is reassigned. The latter should only happen when the matched code is on the way to a loop exit (break, goto, or return). Signed-off-by: Nicolas Palix Signed-off-by: Julia Lawall Signed-off-by: Michal Marek --- scripts/coccinelle/iterators/itnull.cocci | 58 +++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 scripts/coccinelle/iterators/itnull.cocci (limited to 'scripts') diff --git a/scripts/coccinelle/iterators/itnull.cocci b/scripts/coccinelle/iterators/itnull.cocci new file mode 100644 index 000000000000..baa4297a4ed1 --- /dev/null +++ b/scripts/coccinelle/iterators/itnull.cocci @@ -0,0 +1,58 @@ +/// Many iterators have the property that the first argument is always bound +/// to a real list element, never NULL. False positives arise for some +/// iterators that do not have this property, or in cases when the loop +/// cursor is reassigned. The latter should only happen when the matched +/// code is on the way to a loop exit (break, goto, or return). +/// +// Confidence: Moderate +// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. +// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. +// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. +// URL: http://coccinelle.lip6.fr/ +// Comments: +// Options: -no_includes -include_headers + +virtual patch + +@@ +iterator I; +expression x,E,E1,E2; +statement S,S1,S2; +@@ + +I(x,...) { <... +( +- if (x == NULL && ...) S +| +- if (x != NULL || ...) + S +| +- (x == NULL) || + E +| +- (x != NULL) && + E +| +- (x == NULL && ...) ? E1 : + E2 +| +- (x != NULL || ...) ? + E1 +- : E2 +| +- if (x == NULL && ...) S1 else + S2 +| +- if (x != NULL || ...) + S1 +- else S2 +| ++ BAD( + x == NULL ++ ) +| ++ BAD( + x != NULL ++ ) +) + ...> } \ No newline at end of file -- cgit v1.2.3 From 5c34050188f5e3db7f8137d819ecbb7d9327dd93 Mon Sep 17 00:00:00 2001 From: Nicolas Palix Date: Tue, 24 Aug 2010 17:39:03 +0200 Subject: Coccinelle: Add iterators/list_entry_update.cocci list_for_each_entry uses its first argument to get from one element of the list to the next, so it is usually not a good idea to reassign it. The first rule finds such a reassignment and the second rule checks that there is a path from the reassignment back to the top of the loop. Signed-off-by: Nicolas Palix Signed-off-by: Julia Lawall Signed-off-by: Michal Marek --- .../coccinelle/iterators/list_entry_update.cocci | 62 ++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 scripts/coccinelle/iterators/list_entry_update.cocci (limited to 'scripts') diff --git a/scripts/coccinelle/iterators/list_entry_update.cocci b/scripts/coccinelle/iterators/list_entry_update.cocci new file mode 100644 index 000000000000..b2967475679b --- /dev/null +++ b/scripts/coccinelle/iterators/list_entry_update.cocci @@ -0,0 +1,62 @@ +/// list_for_each_entry uses its first argument to get from one element of +/// the list to the next, so it is usually not a good idea to reassign it. +/// The first rule finds such a reassignment and the second rule checks +/// that there is a path from the reassignment back to the top of the loop. +/// +// Confidence: High +// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. +// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. +// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. +// URL: http://coccinelle.lip6.fr/ +// Comments: +// Options: -no_includes -include_headers + +virtual context +virtual org +virtual report + +@r@ +iterator name list_for_each_entry; +expression x,E; +position p1,p2; +@@ + +list_for_each_entry@p1(x,...) { <... x =@p2 E ...> } + +@depends on context && !org && !report@ +expression x,E; +position r.p1,r.p2; +statement S; +@@ + +*x =@p2 E +... +list_for_each_entry@p1(x,...) S + +// ------------------------------------------------------------------------ + +@back depends on (org || report) && !context exists@ +expression x,E; +position r.p1,r.p2; +statement S; +@@ + +x =@p2 E +... +list_for_each_entry@p1(x,...) S + +@script:python depends on back && org@ +p1 << r.p1; +p2 << r.p2; +@@ + +cocci.print_main("iterator",p1) +cocci.print_secs("update",p2) + +@script:python depends on back && report@ +p1 << r.p1; +p2 << r.p2; +@@ + +msg = "iterator with update on line %s" % (p2[0].line) +coccilib.report.print_report(p1[0],msg) -- cgit v1.2.3 From 43ba21b57a3e757000bfa8ccf46c81f232b4d881 Mon Sep 17 00:00:00 2001 From: Nicolas Palix Date: Tue, 24 Aug 2010 17:39:04 +0200 Subject: Coccinelle: Add free/kfree.cocci Find a use after free. Values of variables may imply that some execution paths are not possible, resulting in false positives. Another source of false positives are macros such as SCTP_DBG_OBJCNT_DEC that do not actually evaluate their argument Signed-off-by: Nicolas Palix Signed-off-by: Julia Lawall Signed-off-by: Michal Marek --- scripts/coccinelle/free/kfree.cocci | 116 ++++++++++++++++++++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 scripts/coccinelle/free/kfree.cocci (limited to 'scripts') diff --git a/scripts/coccinelle/free/kfree.cocci b/scripts/coccinelle/free/kfree.cocci new file mode 100644 index 000000000000..c13a5395707b --- /dev/null +++ b/scripts/coccinelle/free/kfree.cocci @@ -0,0 +1,116 @@ +/// Find a use after free. Values of variables may imply that some +/// execution paths are not possible, resulting in false positives. +/// Another source of false positives are macros such as +/// SCTP_DBG_OBJCNT_DEC that do not actually evaluate their argument +/// +// Confidence: Moderate +// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. +// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. +// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. +// URL: http://coccinelle.lip6.fr/ +// Comments: +// Options: -no_includes -include_headers + +virtual org +virtual report + +@free@ +expression E; +position p1; +@@ + +kfree@p1(E) + +@print expression@ +constant char *c; +expression free.E,E2; +type T; +position p; +identifier f; +@@ + +( + f(...,c,...,(T)E@p,...) +| + E@p == E2 +| + E@p != E2 +| + !E@p +| + E@p || ... +) + +@sz@ +expression free.E; +position p; +@@ + + sizeof(<+...E@p...+>) + +@loop exists@ +expression E; +identifier l; +position ok; +@@ + +while (1) { ... + kfree@ok(E) + ... when != break; + when != goto l; + when forall +} + +@r exists@ +expression free.E, subE<=free.E, E2; +expression E1; +iterator iter; +statement S; +position free.p1!=loop.ok,p2!={print.p,sz.p}; +@@ + +kfree@p1(E,...) +... +( + iter(...,subE,...) S // no use +| + list_remove_head(E1,subE,...) +| + subE = E2 +| + subE++ +| + ++subE +| + --subE +| + subE-- +| + &subE +| + BUG(...) +| + BUG_ON(...) +| + return_VALUE(...) +| + return_ACPI_STATUS(...) +| + E@p2 // bad use +) + +@script:python depends on org@ +p1 << free.p1; +p2 << r.p2; +@@ + +cocci.print_main("kfree",p1) +cocci.print_secs("ref",p2) + +@script:python depends on report@ +p1 << free.p1; +p2 << r.p2; +@@ + +msg = "reference preceded by free on line %s" % (p1[0].line) +coccilib.report.print_report(p2[0],msg) -- cgit v1.2.3 From 998f5523230a8a837809f942d556360f69121677 Mon Sep 17 00:00:00 2001 From: Nicolas Palix Date: Tue, 24 Aug 2010 17:39:05 +0200 Subject: Coccinelle: Add api/kstrdup.cocci Use kstrdup rather than duplicating its implementation Signed-off-by: Nicolas Palix Signed-off-by: Julia Lawall Signed-off-by: Michal Marek --- scripts/coccinelle/api/kstrdup.cocci | 39 ++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 scripts/coccinelle/api/kstrdup.cocci (limited to 'scripts') diff --git a/scripts/coccinelle/api/kstrdup.cocci b/scripts/coccinelle/api/kstrdup.cocci new file mode 100644 index 000000000000..e0805ad08d39 --- /dev/null +++ b/scripts/coccinelle/api/kstrdup.cocci @@ -0,0 +1,39 @@ +/// Use kstrdup rather than duplicating its implementation +/// +// Confidence: High +// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. +// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. +// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. +// URL: http://coccinelle.lip6.fr/ +// Comments: +// Options: -no_includes -include_headers + +virtual patch + +@@ +expression from,to; +expression flag,E1,E2; +statement S; +@@ + +- to = kmalloc(strlen(from) + 1,flag); ++ to = kstrdup(from, flag); + ... when != \(from = E1 \| to = E1 \) + if (to==NULL || ...) S + ... when != \(from = E2 \| to = E2 \) +- strcpy(to, from); + +@@ +expression x,from,to; +expression flag,E1,E2,E3; +statement S; +@@ + +- x = strlen(from) + 1; + ... when != \( x = E1 \| from = E1 \) +- to = \(kmalloc\|kzalloc\)(x,flag); ++ to = kstrdup(from, flag); + ... when != \(x = E2 \| from = E2 \| to = E2 \) + if (to==NULL || ...) S + ... when != \(x = E3 \| from = E3 \| to = E3 \) +- memcpy(to, from, x); -- cgit v1.2.3 From 0426a97c4b672166cbcfdc7b18466d4f207f7a36 Mon Sep 17 00:00:00 2001 From: Nicolas Palix Date: Tue, 24 Aug 2010 17:39:06 +0200 Subject: Coccinelle: Add api/memdup.cocci Use kmemdup rather than duplicating its implementation Signed-off-by: Nicolas Palix Signed-off-by: Julia Lawall Signed-off-by: Michal Marek --- scripts/coccinelle/api/memdup.cocci | 40 +++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 scripts/coccinelle/api/memdup.cocci (limited to 'scripts') diff --git a/scripts/coccinelle/api/memdup.cocci b/scripts/coccinelle/api/memdup.cocci new file mode 100644 index 000000000000..b5d722077dc1 --- /dev/null +++ b/scripts/coccinelle/api/memdup.cocci @@ -0,0 +1,40 @@ +/// Use kmemdup rather than duplicating its implementation +/// +// Confidence: High +// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. +// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. +// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. +// URL: http://coccinelle.lip6.fr/ +// Comments: +// Options: -no_includes -include_headers + +virtual patch + +@r1@ +expression from,to; +expression flag; +position p; +@@ + + to = \(kmalloc@p\|kzalloc@p\)(strlen(from) + 1,flag); + +@r2@ +expression x,from,to; +expression flag,E1; +position p; +@@ + + x = strlen(from) + 1; + ... when != \( x = E1 \| from = E1 \) + to = \(kmalloc@p\|kzalloc@p\)(x,flag); + +@@ +expression from,to,size,flag; +position p != {r1.p,r2.p}; +statement S; +@@ + +- to = \(kmalloc@p\|kzalloc@p\)(size,flag); ++ to = kmemdup(from,size,flag); + if (to==NULL || ...) S +- memcpy(to, from, size); -- cgit v1.2.3 From 034174598bc8ffd9586432852502e368a43ef0f1 Mon Sep 17 00:00:00 2001 From: Nicolas Palix Date: Tue, 24 Aug 2010 17:39:07 +0200 Subject: Coccinelle: Add api/memdup_user Use kmemdup_user rather than duplicating its implementation This is a little bit restricted to reduce false positives Signed-off-by: Nicolas Palix Signed-off-by: Julia Lawall Signed-off-by: Michal Marek --- scripts/coccinelle/api/memdup_user.cocci | 35 ++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 scripts/coccinelle/api/memdup_user.cocci (limited to 'scripts') diff --git a/scripts/coccinelle/api/memdup_user.cocci b/scripts/coccinelle/api/memdup_user.cocci new file mode 100644 index 000000000000..72ce012e878a --- /dev/null +++ b/scripts/coccinelle/api/memdup_user.cocci @@ -0,0 +1,35 @@ +/// Use kmemdup_user rather than duplicating its implementation +/// This is a little bit restricted to reduce false positives +/// +// Confidence: High +// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. +// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. +// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. +// URL: http://coccinelle.lip6.fr/ +// Comments: +// Options: -no_includes -include_headers + +virtual patch + +@@ +expression from,to,size,flag; +position p; +identifier l1,l2; +@@ + +- to = \(kmalloc@p\|kzalloc@p\)(size,flag); ++ to = memdup_user(from,size); + if ( +- to==NULL ++ IS_ERR(to) + || ...) { + <+... when != goto l1; +- -ENOMEM ++ PTR_ERR(to) + ...+> + } +- if (copy_from_user(to, from, size) != 0) { +- <+... when != goto l2; +- -EFAULT +- ...+> +- } -- cgit v1.2.3 From 99d653d4bc269aebf255f3864334110dbcc70f37 Mon Sep 17 00:00:00 2001 From: Nicolas Palix Date: Tue, 24 Aug 2010 17:39:08 +0200 Subject: Coccinelle: Move err_cast.cocci to the api directory Signed-off-by: Nicolas Palix Signed-off-by: Julia Lawall Signed-off-by: Michal Marek --- scripts/coccinelle/api/err_cast.cocci | 56 +++++++++++++++++++++++++++++++++++ scripts/coccinelle/err_cast.cocci | 56 ----------------------------------- 2 files changed, 56 insertions(+), 56 deletions(-) create mode 100644 scripts/coccinelle/api/err_cast.cocci delete mode 100644 scripts/coccinelle/err_cast.cocci (limited to 'scripts') diff --git a/scripts/coccinelle/api/err_cast.cocci b/scripts/coccinelle/api/err_cast.cocci new file mode 100644 index 000000000000..2ce115000af6 --- /dev/null +++ b/scripts/coccinelle/api/err_cast.cocci @@ -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) diff --git a/scripts/coccinelle/err_cast.cocci b/scripts/coccinelle/err_cast.cocci deleted file mode 100644 index 2ce115000af6..000000000000 --- a/scripts/coccinelle/err_cast.cocci +++ /dev/null @@ -1,56 +0,0 @@ -/// -/// 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) -- cgit v1.2.3 From 77c272fb24507c43fa301e3da83eb7d67d36a544 Mon Sep 17 00:00:00 2001 From: Nicolas Palix Date: Tue, 24 Aug 2010 17:39:09 +0200 Subject: Coccinelle: Move resource_size.cocci to the api directory Signed-off-by: Nicolas Palix Signed-off-by: Julia Lawall Signed-off-by: Michal Marek --- scripts/coccinelle/api/resource_size.cocci | 93 ++++++++++++++++++++++++++++++ scripts/coccinelle/resource_size.cocci | 93 ------------------------------ 2 files changed, 93 insertions(+), 93 deletions(-) create mode 100644 scripts/coccinelle/api/resource_size.cocci delete mode 100644 scripts/coccinelle/resource_size.cocci (limited to 'scripts') diff --git a/scripts/coccinelle/api/resource_size.cocci b/scripts/coccinelle/api/resource_size.cocci new file mode 100644 index 000000000000..1935a58b39d9 --- /dev/null +++ b/scripts/coccinelle/api/resource_size.cocci @@ -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) diff --git a/scripts/coccinelle/resource_size.cocci b/scripts/coccinelle/resource_size.cocci deleted file mode 100644 index 1935a58b39d9..000000000000 --- a/scripts/coccinelle/resource_size.cocci +++ /dev/null @@ -1,93 +0,0 @@ -/// -/// 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) -- cgit v1.2.3 From be8fe9d451936a7a412b02cb88a13ffe46879bcf Mon Sep 17 00:00:00 2001 From: Nicolas Palix Date: Tue, 24 Aug 2010 17:39:10 +0200 Subject: Coccinelle: Move alloc directory into api directory alloc contains various semantic patches related to the allocation APIs Signed-off-by: Nicolas Palix Signed-off-by: Julia Lawall Signed-off-by: Michal Marek --- scripts/coccinelle/alloc/drop_kmalloc_cast.cocci | 67 ----------------- scripts/coccinelle/alloc/kzalloc-simple.cocci | 82 --------------------- .../coccinelle/api/alloc/drop_kmalloc_cast.cocci | 67 +++++++++++++++++ scripts/coccinelle/api/alloc/kzalloc-simple.cocci | 86 ++++++++++++++++++++++ 4 files changed, 153 insertions(+), 149 deletions(-) delete mode 100644 scripts/coccinelle/alloc/drop_kmalloc_cast.cocci delete mode 100644 scripts/coccinelle/alloc/kzalloc-simple.cocci create mode 100644 scripts/coccinelle/api/alloc/drop_kmalloc_cast.cocci create mode 100644 scripts/coccinelle/api/alloc/kzalloc-simple.cocci (limited to 'scripts') diff --git a/scripts/coccinelle/alloc/drop_kmalloc_cast.cocci b/scripts/coccinelle/alloc/drop_kmalloc_cast.cocci deleted file mode 100644 index 7d4771d449c3..000000000000 --- a/scripts/coccinelle/alloc/drop_kmalloc_cast.cocci +++ /dev/null @@ -1,67 +0,0 @@ -/// -/// 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) diff --git a/scripts/coccinelle/alloc/kzalloc-simple.cocci b/scripts/coccinelle/alloc/kzalloc-simple.cocci deleted file mode 100644 index 2eae828fc657..000000000000 --- a/scripts/coccinelle/alloc/kzalloc-simple.cocci +++ /dev/null @@ -1,82 +0,0 @@ -/// -/// 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) diff --git a/scripts/coccinelle/api/alloc/drop_kmalloc_cast.cocci b/scripts/coccinelle/api/alloc/drop_kmalloc_cast.cocci new file mode 100644 index 000000000000..7d4771d449c3 --- /dev/null +++ b/scripts/coccinelle/api/alloc/drop_kmalloc_cast.cocci @@ -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) diff --git a/scripts/coccinelle/api/alloc/kzalloc-simple.cocci b/scripts/coccinelle/api/alloc/kzalloc-simple.cocci new file mode 100644 index 000000000000..046b9b16f8f9 --- /dev/null +++ b/scripts/coccinelle/api/alloc/kzalloc-simple.cocci @@ -0,0 +1,86 @@ +/// +/// Use kzalloc rather than kmalloc followed by memset with 0 +/// +/// This considers some simple cases that are common and easy to validate +/// Note in particular that there are no ...s in the rule, so all of the +/// matched code has to be contiguous +/// +// Confidence: High +// Copyright: (C) 2009-2010 Julia Lawall, Nicolas Palix, DIKU. GPLv2. +// Copyright: (C) 2009-2010 Gilles Muller, INRIA/LiP6. GPLv2. +// URL: http://coccinelle.lip6.fr/rules/kzalloc.html +// Options: -no_includes -include_headers +// +// Keywords: kmalloc, kzalloc +// Version min: < 2.6.12 kmalloc +// Version min: 2.6.14 kzalloc +// + +virtual context +virtual patch +virtual org +virtual report + +//---------------------------------------------------------- +// For context mode +//---------------------------------------------------------- + +@depends on context@ +type T, T2; +expression x; +expression E1,E2; +statement S; +@@ + +* x = (T)kmalloc(E1,E2); + if ((x==NULL) || ...) S +* memset((T2)x,0,E1); + +//---------------------------------------------------------- +// For patch mode +//---------------------------------------------------------- + +@depends on patch@ +type T, T2; +expression x; +expression E1,E2; +statement S; +@@ + +- x = (T)kmalloc(E1,E2); ++ x = kzalloc(E1,E2); + if ((x==NULL) || ...) S +- memset((T2)x,0,E1); + +//---------------------------------------------------------- +// For org mode +//---------------------------------------------------------- + +@r depends on org || report@ +type T, T2; +expression x; +expression E1,E2; +statement S; +position p; +@@ + + x = (T)kmalloc@p(E1,E2); + if ((x==NULL) || ...) S + memset((T2)x,0,E1); + +@script:python depends on org@ +p << r.p; +x << r.x; +@@ + +msg="%s" % (x) +msg_safe=msg.replace("[","@(").replace("]",")") +coccilib.org.print_todo(p[0], msg_safe) + +@script:python depends on report@ +p << r.p; +x << r.x; +@@ + +msg="WARNING: kzalloc should be used for %s, instead of kmalloc/memset" % (x) +coccilib.report.print_report(p[0], msg) -- cgit v1.2.3 From 033456e2c507a9b804de56dd258af55f03764334 Mon Sep 17 00:00:00 2001 From: Nicolas Palix Date: Tue, 24 Aug 2010 17:39:11 +0200 Subject: Coccinelle: Add misc/doubleinit.cocci Find duplicate field initializations. This has a high rate of false positives due to #ifdefs, which Coccinelle is not aware of in a structure initialization. Signed-off-by: Nicolas Palix Signed-off-by: Julia Lawall Signed-off-by: Michal Marek --- scripts/coccinelle/misc/doubleinit.cocci | 53 ++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 scripts/coccinelle/misc/doubleinit.cocci (limited to 'scripts') diff --git a/scripts/coccinelle/misc/doubleinit.cocci b/scripts/coccinelle/misc/doubleinit.cocci new file mode 100644 index 000000000000..55d7dc19dfe0 --- /dev/null +++ b/scripts/coccinelle/misc/doubleinit.cocci @@ -0,0 +1,53 @@ +/// Find duplicate field initializations. This has a high rate of false +/// positives due to #ifdefs, which Coccinelle is not aware of in a structure +/// initialization. +/// +// Confidence: Low +// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. +// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. +// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. +// URL: http://coccinelle.lip6.fr/ +// Comments: +// Options: -no_includes -include_headers + +virtual org +virtual report + +@r@ +identifier I, s, fld; +position p0,p; +expression E; +@@ + +struct I s =@p0 { ... .fld@p = E, ...}; + +@s@ +identifier I, s, r.fld; +position r.p0,p; +expression E; +@@ + +struct I s =@p0 { ... .fld@p = E, ...}; + +@script:python depends on org@ +p0 << r.p0; +fld << r.fld; +ps << s.p; +pr << r.p; +@@ + +if int(ps[0].line) < int(pr[0].line) or (int(ps[0].line) == int(pr[0].line) and int(ps[0].column) < int(pr[0].column)): + cocci.print_main(fld,p0) + cocci.print_secs("s",ps) + cocci.print_secs("r",pr) + +@script:python depends on report@ +p0 << r.p0; +fld << r.fld; +ps << s.p; +pr << r.p; +@@ + +if int(ps[0].line) < int(pr[0].line) or (int(ps[0].line) == int(pr[0].line) and int(ps[0].column) < int(pr[0].column)): + msg = "%s: first occurrence %s, second occurrence %s" % (fld,ps[0].line,pr[0].line) + coccilib.report.print_report(p0[0],msg) -- cgit v1.2.3 From 49ab7a39136566eb8312e770031af4182c9f2967 Mon Sep 17 00:00:00 2001 From: Nicolas Palix Date: Tue, 24 Aug 2010 17:39:12 +0200 Subject: Coccinelle: Add misc/ifcol.cocci Find confusingly indented code in or after an if. An if branch should be indented. The code following an if should not be indented. Sometimes, code after an if that is indented is actually intended to be part of the if branch. This has a high rate of false positives, because Coccinelle's column calculation does not distinguish between spaces and tabs, so code that is not visually aligned may be considered to be in the same column. Signed-off-by: Nicolas Palix Signed-off-by: Julia Lawall Signed-off-by: Michal Marek --- scripts/coccinelle/misc/ifcol.cocci | 48 +++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 scripts/coccinelle/misc/ifcol.cocci (limited to 'scripts') diff --git a/scripts/coccinelle/misc/ifcol.cocci b/scripts/coccinelle/misc/ifcol.cocci new file mode 100644 index 000000000000..b7ed91dbeb95 --- /dev/null +++ b/scripts/coccinelle/misc/ifcol.cocci @@ -0,0 +1,48 @@ +/// Find confusingly indented code in or after an if. An if branch should +/// be indented. The code following an if should not be indented. +/// Sometimes, code after an if that is indented is actually intended to be +/// part of the if branch. +/// +/// This has a high rate of false positives, because Coccinelle's column +/// calculation does not distinguish between spaces and tabs, so code that +/// is not visually aligned may be considered to be in the same column. +/// +// Confidence: Low +// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. +// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. +// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. +// URL: http://coccinelle.lip6.fr/ +// Comments: +// Options: -no_includes -include_headers + +virtual org +virtual report + +@r disable braces4@ +position p1,p2; +statement S1,S2; +@@ + +( +if (...) { ... } +| +if (...) S1@p1 S2@p2 +) + +@script:python depends on org@ +p1 << r.p1; +p2 << r.p2; +@@ + +if (p1[0].column == p2[0].column): + cocci.print_main("branch",p1) + cocci.print_secs("after",p2) + +@script:python depends on report@ +p1 << r.p1; +p2 << r.p2; +@@ + +if (p1[0].column == p2[0].column): + msg = "code aligned with following code on line %s" % (p2[0].line) + coccilib.report.print_report(p1[0],msg) -- cgit v1.2.3 From 3c908417677f890265ff9d5efd372207cf75fd45 Mon Sep 17 00:00:00 2001 From: Nicolas Palix Date: Fri, 8 Oct 2010 21:27:38 +0200 Subject: Coccinelle: Improve user information with a new kind of comment Improve user information with a new kind of comment about semantic patch output. Fix spelling. Signed-off-by: Nicolas Palix Signed-off-by: Julia Lawall Signed-off-by: Michal Marek --- scripts/coccicheck | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'scripts') diff --git a/scripts/coccicheck b/scripts/coccicheck index b8bcf1f7bed7..ef78c875a0e3 100755 --- a/scripts/coccicheck +++ b/scripts/coccicheck @@ -25,7 +25,7 @@ fi if [ "$MODE" = "" ] ; then if [ "$ONLINE" = "0" ] ; then - echo 'You have not explicitly specify the mode to use. Fallback to "report".' + echo 'You have not explicitly specified the mode to use. Fallback to "report".' echo 'You can specify the mode with "make coccicheck MODE="' echo 'Available modes are: report, patch, context, org' fi @@ -52,10 +52,12 @@ coccinelle () { FILE=`echo $COCCI | sed "s|$srctree/||"` - echo "Processing `basename $COCCI` with option(s) \"$OPT\"" + echo "Processing `basename $COCCI`" + echo "with option(s) \"$OPT\"" + echo '' echo 'Message example to submit a patch:' - sed -e '/\/\/\//!d' -e 's|^///||' $COCCI + sed -ne 's|^///||p' $COCCI echo ' The semantic patch that makes this change is available' echo " in $FILE." @@ -64,6 +66,12 @@ coccinelle () { echo ' http://coccinelle.lip6.fr/' echo '' + if [ "`sed -ne 's|^//#||p' $COCCI`" ] ; then + echo 'Semantic patch information:' + sed -ne 's|^//#||p' $COCCI + echo '' + fi + $SPATCH -D $MODE $FLAGS -sp_file $COCCI $OPT -dir $srctree || exit 1 else $SPATCH -D $MODE $FLAGS -sp_file $COCCI $OPT $OPTIONS || exit 1 -- cgit v1.2.3 From e90f6590219a0082618b9b6828458b1c74f37cc0 Mon Sep 17 00:00:00 2001 From: Nicolas Palix Date: Fri, 8 Oct 2010 21:27:39 +0200 Subject: Coccinelle: Use new comment format to explain kfree.cocci Use new comment format to separate proposed commit message and information about generated false positives Signed-off-by: Nicolas Palix Signed-off-by: Julia Lawall Signed-off-by: Michal Marek --- scripts/coccinelle/free/kfree.cocci | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'scripts') diff --git a/scripts/coccinelle/free/kfree.cocci b/scripts/coccinelle/free/kfree.cocci index c13a5395707b..f9f79d9245ee 100644 --- a/scripts/coccinelle/free/kfree.cocci +++ b/scripts/coccinelle/free/kfree.cocci @@ -1,7 +1,8 @@ -/// Find a use after free. Values of variables may imply that some -/// execution paths are not possible, resulting in false positives. -/// Another source of false positives are macros such as -/// SCTP_DBG_OBJCNT_DEC that do not actually evaluate their argument +/// Find a use after free. +//# Values of variables may imply that some +//# execution paths are not possible, resulting in false positives. +//# Another source of false positives are macros such as +//# SCTP_DBG_OBJCNT_DEC that do not actually evaluate their argument /// // Confidence: Moderate // Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. -- cgit v1.2.3 From 2c1160c87465ee2d61eee14596e5376d2ff74f31 Mon Sep 17 00:00:00 2001 From: Nicolas Palix