kmerr: verify that malloc and calloc are followed by a check to verify that we are not out of memory. badzero: Compare pointer-typed values to NULL rather than 0 Both checks are copied from the Linux kernel archive. Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>master
parent
428e60e079
commit
4320e2fda4
@ -0,0 +1,241 @@ |
||||
/// Compare pointer-typed values to NULL rather than 0 |
||||
/// |
||||
//# This makes an effort to choose between !x and x == NULL. !x is used |
||||
//# if it has previously been used with the function used to initialize x. |
||||
//# This relies on type information. More type information can be obtained |
||||
//# using the option -all_includes and the option -I to specify an |
||||
//# include path. |
||||
// |
||||
// Confidence: High |
||||
// Copyright: (C) 2012 Julia Lawall, INRIA/LIP6. GPLv2. |
||||
// Copyright: (C) 2012 Gilles Muller, INRIA/LiP6. GPLv2. |
||||
// URL: http://coccinelle.lip6.fr/ |
||||
// Requires: 1.0.0 |
||||
// Options: |
||||
// |
||||
// SPDX-License-Identifier: GPL-2.0 |
||||
// |
||||
|
||||
virtual patch |
||||
virtual context |
||||
virtual org |
||||
virtual report |
||||
|
||||
@initialize:ocaml@ |
||||
@@ |
||||
let negtable = Hashtbl.create 101 |
||||
|
||||
@depends on patch@ |
||||
expression *E; |
||||
identifier f; |
||||
@@ |
||||
|
||||
( |
||||
(E = f(...)) == |
||||
- 0 |
||||
+ NULL |
||||
| |
||||
(E = f(...)) != |
||||
- 0 |
||||
+ NULL |
||||
| |
||||
- 0 |
||||
+ NULL |
||||
== (E = f(...)) |
||||
| |
||||
- 0 |
||||
+ NULL |
||||
!= (E = f(...)) |
||||
) |
||||
|
||||
|
||||
@t1 depends on !patch@ |
||||
expression *E; |
||||
identifier f; |
||||
position p; |
||||
@@ |
||||
|
||||
( |
||||
(E = f(...)) == |
||||
* 0@p |
||||
| |
||||
(E = f(...)) != |
||||
* 0@p |
||||
| |
||||
* 0@p |
||||
== (E = f(...)) |
||||
| |
||||
* 0@p |
||||
!= (E = f(...)) |
||||
) |
||||
|
||||
@script:python depends on org@ |
||||
p << t1.p; |
||||
@@ |
||||
|
||||
coccilib.org.print_todo(p[0], "WARNING comparing pointer to 0") |
||||
|
||||
@script:python depends on report@ |
||||
p << t1.p; |
||||
@@ |
||||
|
||||
coccilib.report.print_report(p[0], "WARNING comparing pointer to 0") |
||||
|
||||
// Tests of returned values |
||||
|
||||
@s@ |
||||
identifier f; |
||||
expression E,E1; |
||||
@@ |
||||
|
||||
E = f(...) |
||||
... when != E = E1 |
||||
!E |
||||
|
||||
@script:ocaml depends on s@ |
||||
f << s.f; |
||||
@@ |
||||
|
||||
try let _ = Hashtbl.find negtable f in () |
||||
with Not_found -> Hashtbl.add negtable f () |
||||
|
||||
@ r disable is_zero,isnt_zero exists @ |
||||
expression *E; |
||||
identifier f; |
||||
@@ |
||||
|
||||
E = f(...) |
||||
... |
||||
(E == 0 |
||||
|E != 0 |
||||
|0 == E |
||||
|0 != E |
||||
) |
||||
|
||||
@script:ocaml@ |
||||
f << r.f; |
||||
@@ |
||||
|
||||
try let _ = Hashtbl.find negtable f in () |
||||
with Not_found -> include_match false |
||||
|
||||
// This rule may lead to inconsistent path problems, if E is defined in two |
||||
// places |
||||
@ depends on patch disable is_zero,isnt_zero @ |
||||
expression *E; |
||||
expression E1; |
||||
identifier r.f; |
||||
@@ |
||||
|
||||
E = f(...) |
||||
<... |
||||
( |
||||
- E == 0 |
||||
+ !E |
||||
| |
||||
- E != 0 |
||||
+ E |
||||
| |
||||
- 0 == E |
||||
+ !E |
||||
| |
||||
- 0 != E |
||||
+ E |
||||
) |
||||
...> |
||||
?E = E1 |
||||
|
||||
@t2 depends on !patch disable is_zero,isnt_zero @ |
||||
expression *E; |
||||
expression E1; |
||||
identifier r.f; |
||||
position p1; |
||||
position p2; |
||||
@@ |
||||
|
||||
E = f(...) |
||||
<... |
||||
( |
||||
* E == 0@p1 |
||||
| |
||||
* E != 0@p2 |
||||
| |
||||
* 0@p1 == E |
||||
| |
||||
* 0@p1 != E |
||||
) |
||||
...> |
||||
?E = E1 |
||||
|
||||
@script:python depends on org@ |
||||
p << t2.p1; |
||||
@@ |
||||
|
||||
coccilib.org.print_todo(p[0], "WARNING comparing pointer to 0, suggest !E") |
||||
|
||||
@script:python depends on org@ |
||||
p << t2.p2; |
||||
@@ |
||||
|
||||
coccilib.org.print_todo(p[0], "WARNING comparing pointer to 0") |
||||
|
||||
@script:python depends on report@ |
||||
p << t2.p1; |
||||
@@ |
||||
|
||||
coccilib.report.print_report(p[0], "WARNING comparing pointer to 0, suggest !E") |
||||
|
||||
@script:python depends on report@ |
||||
p << t2.p2; |
||||
@@ |
||||
|
||||
coccilib.report.print_report(p[0], "WARNING comparing pointer to 0") |
||||
|
||||
@ depends on patch disable is_zero,isnt_zero @ |
||||
expression *E; |
||||
@@ |
||||
|
||||
( |
||||
E == |
||||
- 0 |
||||
+ NULL |
||||
| |
||||
E != |
||||
- 0 |
||||
+ NULL |
||||
| |
||||
- 0 |
||||
+ NULL |
||||
== E |
||||
| |
||||
- 0 |
||||
+ NULL |
||||
!= E |
||||
) |
||||
|
||||
@ t3 depends on !patch disable is_zero,isnt_zero @ |
||||
expression *E; |
||||
position p; |
||||
@@ |
||||
|
||||
( |
||||
* E == 0@p |
||||
| |
||||
* E != 0@p |
||||
| |
||||
* 0@p == E |
||||
| |
||||
* 0@p != E |
||||
) |
||||
|
||||
@script:python depends on org@ |
||||
p << t3.p; |
||||
@@ |
||||
|
||||
coccilib.org.print_todo(p[0], "WARNING comparing pointer to 0") |
||||
|
||||
@script:python depends on report@ |
||||
p << t3.p; |
||||
@@ |
||||
|
||||
coccilib.report.print_report(p[0], "WARNING comparing pointer to 0") |
@ -0,0 +1,75 @@ |
||||
/// This semantic patch looks for malloc 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 malloc 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 |
||||
// |
||||
// SPDX-License-Identifier: GPL-2.0 |
||||
// |
||||
|
||||
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 = \(malloc\|calloc\)(...); |
||||
... |
||||
*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 = \(malloc\|calloc\)(...); |
||||
... |
||||
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) |
Loading…
Reference in new issue