Commit | Line | Data |
---|---|---|
7a92c046 SW |
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 | |
5 | //# 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: | |
1f80e4b0 | 13 | // Options: -no_includes -include_headers -D report |
cfa4e38f SW |
14 | // |
15 | // Applies to kernel code. | |
7a92c046 SW |
16 | |
17 | virtual org | |
18 | virtual report | |
19 | ||
20 | @free@ | |
21 | expression E; | |
22 | position p1; | |
23 | @@ | |
24 | ||
1f80e4b0 | 25 | \(contigfree@p1(E,...)\|kfree@p1(E,...)\|objcache_put@p1(...,E)\|mpipe_free@p1(...,E)\|zfree@p1(...,E)\) |
7a92c046 SW |
26 | |
27 | @print expression@ | |
28 | constant char *c; | |
29 | expression free.E,E2; | |
30 | type T; | |
31 | position p; | |
32 | identifier f; | |
33 | @@ | |
34 | ||
35 | ( | |
36 | f(...,c,...,(T)E@p,...) | |
37 | | | |
38 | E@p == E2 | |
39 | | | |
40 | E@p != E2 | |
41 | | | |
42 | !E@p | |
43 | | | |
44 | E@p || ... | |
45 | ) | |
46 | ||
47 | @sz@ | |
48 | expression free.E; | |
49 | position p; | |
50 | @@ | |
51 | ||
52 | sizeof(<+...E@p...+>) | |
53 | ||
54 | @loop exists@ | |
55 | expression E; | |
56 | identifier l; | |
57 | position ok; | |
58 | @@ | |
59 | ||
60 | while (1) { ... | |
1f80e4b0 | 61 | \(contigfree@ok(E,...)\|kfree@ok(E,...)\|objcache_put@ok(...,E)\|mpipe_free@ok(...,E)\|zfree@ok(...,E)\) |
7a92c046 SW |
62 | ... when != break; |
63 | when != goto l; | |
64 | when forall | |
65 | } | |
66 | ||
67 | @r exists@ | |
68 | expression free.E, subE<=free.E, E2; | |
69 | expression E1; | |
70 | iterator iter; | |
71 | statement S; | |
72 | position free.p1!=loop.ok,p2!={print.p,sz.p}; | |
73 | @@ | |
74 | ||
1f80e4b0 | 75 | \(contigfree@p1(E,...)\|kfree@p1(E,...)\|objcache_put@p1(...,E)\|mpipe_free@p1(...,E)\|zfree@p1(...,E)\) |
7a92c046 SW |
76 | ... |
77 | ( | |
78 | iter(...,subE,...) S // no use | |
79 | | | |
80 | list_remove_head(E1,subE,...) | |
81 | | | |
82 | subE = E2 | |
83 | | | |
84 | subE++ | |
85 | | | |
86 | ++subE | |
87 | | | |
88 | --subE | |
89 | | | |
90 | subE-- | |
91 | | | |
92 | &subE | |
7a92c046 SW |
93 | | |
94 | return_VALUE(...) | |
95 | | | |
96 | return_ACPI_STATUS(...) | |
97 | | | |
98 | E@p2 // bad use | |
99 | ) | |
100 | ||
101 | @script:python depends on org@ | |
102 | p1 << free.p1; | |
103 | p2 << r.p2; | |
104 | @@ | |
105 | ||
106 | cocci.print_main("kfree",p1) | |
107 | cocci.print_secs("ref",p2) | |
108 | ||
109 | @script:python depends on report@ | |
110 | p1 << free.p1; | |
111 | p2 << r.p2; | |
112 | @@ | |
113 | ||
114 | msg = "reference preceded by free on line %s" % (p1[0].line) | |
115 | coccilib.report.print_report(p2[0],msg) |