Commit | Line | Data |
---|---|---|
e90f6590 NP |
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 | |
43ba21b5 NP |
6 | /// |
7 | // Confidence: Moderate | |
29a36d4d JL |
8 | // Copyright: (C) 2010-2012 Nicolas Palix. GPLv2. |
9 | // Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6. GPLv2. | |
10 | // Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6. GPLv2. | |
43ba21b5 NP |
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@ | |
29a36d4d | 26 | constant char [] c; |
43ba21b5 NP |
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 | |
29a36d4d JL |
39 | | |
40 | E2 == E@p | |
41 | | | |
42 | E2 != E@p | |
43ba21b5 NP |
43 | | |
44 | !E@p | |
45 | | | |
46 | E@p || ... | |
47 | ) | |
48 | ||
49 | @sz@ | |
50 | expression free.E; | |
51 | position p; | |
52 | @@ | |
53 | ||
54 | sizeof(<+...E@p...+>) | |
55 | ||
56 | @loop exists@ | |
57 | expression E; | |
58 | identifier l; | |
59 | position ok; | |
60 | @@ | |
61 | ||
62 | while (1) { ... | |
63 | kfree@ok(E) | |
64 | ... when != break; | |
65 | when != goto l; | |
66 | when forall | |
67 | } | |
68 | ||
69 | @r exists@ | |
70 | expression free.E, subE<=free.E, E2; | |
71 | expression E1; | |
72 | iterator iter; | |
73 | statement S; | |
74 | position free.p1!=loop.ok,p2!={print.p,sz.p}; | |
75 | @@ | |
76 | ||
77 | kfree@p1(E,...) | |
78 | ... | |
79 | ( | |
80 | iter(...,subE,...) S // no use | |
81 | | | |
82 | list_remove_head(E1,subE,...) | |
83 | | | |
84 | subE = E2 | |
85 | | | |
86 | subE++ | |
87 | | | |
88 | ++subE | |
89 | | | |
90 | --subE | |
91 | | | |
92 | subE-- | |
93 | | | |
94 | &subE | |
95 | | | |
96 | BUG(...) | |
97 | | | |
98 | BUG_ON(...) | |
99 | | | |
100 | return_VALUE(...) | |
101 | | | |
102 | return_ACPI_STATUS(...) | |
103 | | | |
104 | E@p2 // bad use | |
105 | ) | |
106 | ||
107 | @script:python depends on org@ | |
108 | p1 << free.p1; | |
109 | p2 << r.p2; | |
110 | @@ | |
111 | ||
112 | cocci.print_main("kfree",p1) | |
113 | cocci.print_secs("ref",p2) | |
114 | ||
115 | @script:python depends on report@ | |
116 | p1 << free.p1; | |
117 | p2 << r.p2; | |
118 | @@ | |
119 | ||
29a36d4d | 120 | msg = "ERROR: reference preceded by free on line %s" % (p1[0].line) |
43ba21b5 | 121 | coccilib.report.print_report(p2[0],msg) |