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: 13// Options: -no_includes -include_headers -D report 14// 15// Applies to kernel code. 16 17virtual org 18virtual report 19 20@free@ 21expression E; 22position p1; 23@@ 24 25\(contigfree@p1(E,...)\|kfree@p1(E,...)\|objcache_put@p1(...,E)\|mpipe_free@p1(...,E)\|zfree@p1(...,E)\) 26 27@print expression@ 28constant char *c; 29expression free.E,E2; 30type T; 31position p; 32identifier 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@ 48expression free.E; 49position p; 50@@ 51 52 sizeof(<+...E@p...+>) 53 54@loop exists@ 55expression E; 56identifier l; 57position ok; 58@@ 59 60while (1) { ... 61 \(contigfree@ok(E,...)\|kfree@ok(E,...)\|objcache_put@ok(...,E)\|mpipe_free@ok(...,E)\|zfree@ok(...,E)\) 62 ... when != break; 63 when != goto l; 64 when forall 65} 66 67@r exists@ 68expression free.E, subE<=free.E, E2; 69expression E1; 70iterator iter; 71statement S; 72position free.p1!=loop.ok,p2!={print.p,sz.p}; 73@@ 74 75\(contigfree@p1(E,...)\|kfree@p1(E,...)\|objcache_put@p1(...,E)\|mpipe_free@p1(...,E)\|zfree@p1(...,E)\) 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 93| 94 return_VALUE(...) 95| 96 return_ACPI_STATUS(...) 97| 98 E@p2 // bad use 99) 100 101@script:python depends on org@ 102p1 << free.p1; 103p2 << r.p2; 104@@ 105 106cocci.print_main("kfree",p1) 107cocci.print_secs("ref",p2) 108 109@script:python depends on report@ 110p1 << free.p1; 111p2 << r.p2; 112@@ 113 114msg = "reference preceded by free on line %s" % (p1[0].line) 115coccilib.report.print_report(p2[0],msg) 116