1*4882a593Smuzhiyun// SPDX-License-Identifier: GPL-2.0-only 2*4882a593Smuzhiyun/// Find a use after free. 3*4882a593Smuzhiyun//# Values of variables may imply that some 4*4882a593Smuzhiyun//# execution paths are not possible, resulting in false positives. 5*4882a593Smuzhiyun//# Another source of false positives are macros such as 6*4882a593Smuzhiyun//# SCTP_DBG_OBJCNT_DEC that do not actually evaluate their argument 7*4882a593Smuzhiyun/// 8*4882a593Smuzhiyun// Confidence: Moderate 9*4882a593Smuzhiyun// Copyright: (C) 2010-2012 Nicolas Palix. 10*4882a593Smuzhiyun// Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6. 11*4882a593Smuzhiyun// Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6. 12*4882a593Smuzhiyun// URL: http://coccinelle.lip6.fr/ 13*4882a593Smuzhiyun// Comments: 14*4882a593Smuzhiyun// Options: --no-includes --include-headers 15*4882a593Smuzhiyun 16*4882a593Smuzhiyunvirtual org 17*4882a593Smuzhiyunvirtual report 18*4882a593Smuzhiyun 19*4882a593Smuzhiyun@free@ 20*4882a593Smuzhiyunexpression E; 21*4882a593Smuzhiyunposition p1; 22*4882a593Smuzhiyun@@ 23*4882a593Smuzhiyun 24*4882a593Smuzhiyun( 25*4882a593Smuzhiyun* kfree@p1(E) 26*4882a593Smuzhiyun| 27*4882a593Smuzhiyun* kfree_sensitive@p1(E) 28*4882a593Smuzhiyun) 29*4882a593Smuzhiyun 30*4882a593Smuzhiyun@print expression@ 31*4882a593Smuzhiyunconstant char [] c; 32*4882a593Smuzhiyunexpression free.E,E2; 33*4882a593Smuzhiyuntype T; 34*4882a593Smuzhiyunposition p; 35*4882a593Smuzhiyunidentifier f; 36*4882a593Smuzhiyun@@ 37*4882a593Smuzhiyun 38*4882a593Smuzhiyun( 39*4882a593Smuzhiyun f(...,c,...,(T)E@p,...) 40*4882a593Smuzhiyun| 41*4882a593Smuzhiyun E@p == E2 42*4882a593Smuzhiyun| 43*4882a593Smuzhiyun E@p != E2 44*4882a593Smuzhiyun| 45*4882a593Smuzhiyun E2 == E@p 46*4882a593Smuzhiyun| 47*4882a593Smuzhiyun E2 != E@p 48*4882a593Smuzhiyun| 49*4882a593Smuzhiyun !E@p 50*4882a593Smuzhiyun| 51*4882a593Smuzhiyun E@p || ... 52*4882a593Smuzhiyun) 53*4882a593Smuzhiyun 54*4882a593Smuzhiyun@sz@ 55*4882a593Smuzhiyunexpression free.E; 56*4882a593Smuzhiyunposition p; 57*4882a593Smuzhiyun@@ 58*4882a593Smuzhiyun 59*4882a593Smuzhiyun sizeof(<+...E@p...+>) 60*4882a593Smuzhiyun 61*4882a593Smuzhiyun@loop exists@ 62*4882a593Smuzhiyunexpression E; 63*4882a593Smuzhiyunidentifier l; 64*4882a593Smuzhiyunposition ok; 65*4882a593Smuzhiyun@@ 66*4882a593Smuzhiyun 67*4882a593Smuzhiyunwhile (1) { ... 68*4882a593Smuzhiyun( 69*4882a593Smuzhiyun* kfree@ok(E) 70*4882a593Smuzhiyun| 71*4882a593Smuzhiyun* kfree_sensitive@ok(E) 72*4882a593Smuzhiyun) 73*4882a593Smuzhiyun ... when != break; 74*4882a593Smuzhiyun when != goto l; 75*4882a593Smuzhiyun when forall 76*4882a593Smuzhiyun} 77*4882a593Smuzhiyun 78*4882a593Smuzhiyun@r exists@ 79*4882a593Smuzhiyunexpression free.E, subE<=free.E, E2; 80*4882a593Smuzhiyunexpression E1; 81*4882a593Smuzhiyuniterator iter; 82*4882a593Smuzhiyunstatement S; 83*4882a593Smuzhiyunposition free.p1!=loop.ok,p2!={print.p,sz.p}; 84*4882a593Smuzhiyun@@ 85*4882a593Smuzhiyun 86*4882a593Smuzhiyun( 87*4882a593Smuzhiyun* kfree@p1(E,...) 88*4882a593Smuzhiyun| 89*4882a593Smuzhiyun* kfree_sensitive@p1(E,...) 90*4882a593Smuzhiyun) 91*4882a593Smuzhiyun... 92*4882a593Smuzhiyun( 93*4882a593Smuzhiyun iter(...,subE,...) S // no use 94*4882a593Smuzhiyun| 95*4882a593Smuzhiyun list_remove_head(E1,subE,...) 96*4882a593Smuzhiyun| 97*4882a593Smuzhiyun subE = E2 98*4882a593Smuzhiyun| 99*4882a593Smuzhiyun subE++ 100*4882a593Smuzhiyun| 101*4882a593Smuzhiyun ++subE 102*4882a593Smuzhiyun| 103*4882a593Smuzhiyun --subE 104*4882a593Smuzhiyun| 105*4882a593Smuzhiyun subE-- 106*4882a593Smuzhiyun| 107*4882a593Smuzhiyun &subE 108*4882a593Smuzhiyun| 109*4882a593Smuzhiyun BUG(...) 110*4882a593Smuzhiyun| 111*4882a593Smuzhiyun BUG_ON(...) 112*4882a593Smuzhiyun| 113*4882a593Smuzhiyun return_VALUE(...) 114*4882a593Smuzhiyun| 115*4882a593Smuzhiyun return_ACPI_STATUS(...) 116*4882a593Smuzhiyun| 117*4882a593Smuzhiyun E@p2 // bad use 118*4882a593Smuzhiyun) 119*4882a593Smuzhiyun 120*4882a593Smuzhiyun@script:python depends on org@ 121*4882a593Smuzhiyunp1 << free.p1; 122*4882a593Smuzhiyunp2 << r.p2; 123*4882a593Smuzhiyun@@ 124*4882a593Smuzhiyun 125*4882a593Smuzhiyuncocci.print_main("kfree",p1) 126*4882a593Smuzhiyuncocci.print_secs("ref",p2) 127*4882a593Smuzhiyun 128*4882a593Smuzhiyun@script:python depends on report@ 129*4882a593Smuzhiyunp1 << free.p1; 130*4882a593Smuzhiyunp2 << r.p2; 131*4882a593Smuzhiyun@@ 132*4882a593Smuzhiyun 133*4882a593Smuzhiyunmsg = "ERROR: reference preceded by free on line %s" % (p1[0].line) 134*4882a593Smuzhiyuncoccilib.report.print_report(p2[0],msg) 135