diff options
author | Nicolas Palix <npalix@diku.dk> | 2010-08-24 11:39:04 -0400 |
---|---|---|
committer | Michal Marek <mmarek@suse.cz> | 2010-08-31 05:37:53 -0400 |
commit | 43ba21b57a3e757000bfa8ccf46c81f232b4d881 (patch) | |
tree | a4d8b0ab92c6739f430bb7f43cab8988d13dda9b /scripts | |
parent | 5c34050188f5e3db7f8137d819ecbb7d9327dd93 (diff) |
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 <npalix@diku.dk>
Signed-off-by: Julia Lawall <julia@diku.dk>
Signed-off-by: Michal Marek <mmarek@suse.cz>
Diffstat (limited to 'scripts')
-rw-r--r-- | scripts/coccinelle/free/kfree.cocci | 116 |
1 files changed, 116 insertions, 0 deletions
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 @@ | |||
1 | /// Find a use after free. Values of variables may imply that some | ||
2 | /// execution paths are not possible, resulting in false positives. | ||
3 | /// Another source of false positives are macros such as | ||
4 | /// SCTP_DBG_OBJCNT_DEC that do not actually evaluate their argument | ||
5 | /// | ||
6 | // Confidence: Moderate | ||
7 | // Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. | ||
8 | // Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. | ||
9 | // Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. | ||
10 | // URL: http://coccinelle.lip6.fr/ | ||
11 | // Comments: | ||
12 | // Options: -no_includes -include_headers | ||
13 | |||
14 | virtual org | ||
15 | virtual report | ||
16 | |||
17 | @free@ | ||
18 | expression E; | ||
19 | position p1; | ||
20 | @@ | ||
21 | |||
22 | kfree@p1(E) | ||
23 | |||
24 | @print expression@ | ||
25 | constant char *c; | ||
26 | expression free.E,E2; | ||
27 | type T; | ||
28 | position p; | ||
29 | identifier f; | ||
30 | @@ | ||
31 | |||
32 | ( | ||
33 | f(...,c,...,(T)E@p,...) | ||
34 | | | ||
35 | E@p == E2 | ||
36 | | | ||
37 | E@p != E2 | ||
38 | | | ||
39 | !E@p | ||
40 | | | ||
41 | E@p || ... | ||
42 | ) | ||
43 | |||
44 | @sz@ | ||
45 | expression free.E; | ||
46 | position p; | ||
47 | @@ | ||
48 | |||
49 | sizeof(<+...E@p...+>) | ||
50 | |||
51 | @loop exists@ | ||
52 | expression E; | ||
53 | identifier l; | ||
54 | position ok; | ||
55 | @@ | ||
56 | |||
57 | while (1) { ... | ||
58 | kfree@ok(E) | ||
59 | ... when != break; | ||
60 | when != goto l; | ||
61 | when forall | ||
62 | } | ||
63 | |||
64 | @r exists@ | ||
65 | expression free.E, subE<=free.E, E2; | ||
66 | expression E1; | ||
67 | iterator iter; | ||
68 | statement S; | ||
69 | position free.p1!=loop.ok,p2!={print.p,sz.p}; | ||
70 | @@ | ||
71 | |||
72 | kfree@p1(E,...) | ||
73 | ... | ||
74 | ( | ||
75 | iter(...,subE,...) S // no use | ||
76 | | | ||
77 | list_remove_head(E1,subE,...) | ||
78 | | | ||
79 | subE = E2 | ||
80 | | | ||
81 | subE++ | ||
82 | | | ||
83 | ++subE | ||
84 | | | ||
85 | --subE | ||
86 | | | ||
87 | subE-- | ||
88 | | | ||
89 | &subE | ||
90 | | | ||
91 | BUG(...) | ||
92 | | | ||
93 | BUG_ON(...) | ||
94 | | | ||
95 | return_VALUE(...) | ||
96 | | | ||
97 | return_ACPI_STATUS(...) | ||
98 | | | ||
99 | E@p2 // bad use | ||
100 | ) | ||
101 | |||
102 | @script:python depends on org@ | ||
103 | p1 << free.p1; | ||
104 | p2 << r.p2; | ||
105 | @@ | ||
106 | |||
107 | cocci.print_main("kfree",p1) | ||
108 | cocci.print_secs("ref",p2) | ||
109 | |||
110 | @script:python depends on report@ | ||
111 | p1 << free.p1; | ||
112 | p2 << r.p2; | ||
113 | @@ | ||
114 | |||
115 | msg = "reference preceded by free on line %s" % (p1[0].line) | ||
116 | coccilib.report.print_report(p2[0],msg) | ||