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