162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 262306a36Sopenharmony_ci/// Find a use after free. 362306a36Sopenharmony_ci//# Values of variables may imply that some 462306a36Sopenharmony_ci//# execution paths are not possible, resulting in false positives. 562306a36Sopenharmony_ci//# Another source of false positives are macros such as 662306a36Sopenharmony_ci//# SCTP_DBG_OBJCNT_DEC that do not actually evaluate their argument 762306a36Sopenharmony_ci/// 862306a36Sopenharmony_ci// Confidence: Moderate 962306a36Sopenharmony_ci// Copyright: (C) 2010-2012 Nicolas Palix. 1062306a36Sopenharmony_ci// Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6. 1162306a36Sopenharmony_ci// Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6. 1262306a36Sopenharmony_ci// URL: https://coccinelle.gitlabpages.inria.fr/website 1362306a36Sopenharmony_ci// Comments: 1462306a36Sopenharmony_ci// Options: --no-includes --include-headers 1562306a36Sopenharmony_ci 1662306a36Sopenharmony_civirtual org 1762306a36Sopenharmony_civirtual report 1862306a36Sopenharmony_ci 1962306a36Sopenharmony_ci@free@ 2062306a36Sopenharmony_ciexpression E; 2162306a36Sopenharmony_ciposition p1; 2262306a36Sopenharmony_ci@@ 2362306a36Sopenharmony_ci 2462306a36Sopenharmony_ci( 2562306a36Sopenharmony_ci kfree@p1(E) 2662306a36Sopenharmony_ci| 2762306a36Sopenharmony_ci kfree_sensitive@p1(E) 2862306a36Sopenharmony_ci) 2962306a36Sopenharmony_ci 3062306a36Sopenharmony_ci@print expression@ 3162306a36Sopenharmony_ciconstant char [] c; 3262306a36Sopenharmony_ciexpression free.E,E2; 3362306a36Sopenharmony_citype T; 3462306a36Sopenharmony_ciposition p; 3562306a36Sopenharmony_ciidentifier f; 3662306a36Sopenharmony_ci@@ 3762306a36Sopenharmony_ci 3862306a36Sopenharmony_ci( 3962306a36Sopenharmony_ci f(...,c,...,(T)E@p,...) 4062306a36Sopenharmony_ci| 4162306a36Sopenharmony_ci E@p == E2 4262306a36Sopenharmony_ci| 4362306a36Sopenharmony_ci E@p != E2 4462306a36Sopenharmony_ci| 4562306a36Sopenharmony_ci E2 == E@p 4662306a36Sopenharmony_ci| 4762306a36Sopenharmony_ci E2 != E@p 4862306a36Sopenharmony_ci| 4962306a36Sopenharmony_ci !E@p 5062306a36Sopenharmony_ci| 5162306a36Sopenharmony_ci E@p || ... 5262306a36Sopenharmony_ci) 5362306a36Sopenharmony_ci 5462306a36Sopenharmony_ci@sz@ 5562306a36Sopenharmony_ciexpression free.E; 5662306a36Sopenharmony_ciposition p; 5762306a36Sopenharmony_ci@@ 5862306a36Sopenharmony_ci 5962306a36Sopenharmony_ci sizeof(<+...E@p...+>) 6062306a36Sopenharmony_ci 6162306a36Sopenharmony_ci@loop exists@ 6262306a36Sopenharmony_ciexpression E; 6362306a36Sopenharmony_ciidentifier l; 6462306a36Sopenharmony_ciposition ok; 6562306a36Sopenharmony_ci@@ 6662306a36Sopenharmony_ci 6762306a36Sopenharmony_ciwhile (1) { ... 6862306a36Sopenharmony_ci( 6962306a36Sopenharmony_ci kfree@ok(E) 7062306a36Sopenharmony_ci| 7162306a36Sopenharmony_ci kfree_sensitive@ok(E) 7262306a36Sopenharmony_ci) 7362306a36Sopenharmony_ci ... when != break; 7462306a36Sopenharmony_ci when != goto l; 7562306a36Sopenharmony_ci when forall 7662306a36Sopenharmony_ci} 7762306a36Sopenharmony_ci 7862306a36Sopenharmony_ci@r exists@ 7962306a36Sopenharmony_ciexpression free.E, subE<=free.E, E2; 8062306a36Sopenharmony_ciexpression E1; 8162306a36Sopenharmony_ciiterator iter; 8262306a36Sopenharmony_cistatement S; 8362306a36Sopenharmony_ciposition free.p1!=loop.ok,p2!={print.p,sz.p}; 8462306a36Sopenharmony_ci@@ 8562306a36Sopenharmony_ci 8662306a36Sopenharmony_ci( 8762306a36Sopenharmony_ci kfree@p1(E,...) 8862306a36Sopenharmony_ci| 8962306a36Sopenharmony_ci kfree_sensitive@p1(E,...) 9062306a36Sopenharmony_ci) 9162306a36Sopenharmony_ci... 9262306a36Sopenharmony_ci( 9362306a36Sopenharmony_ci iter(...,subE,...) S // no use 9462306a36Sopenharmony_ci| 9562306a36Sopenharmony_ci list_remove_head(E1,subE,...) 9662306a36Sopenharmony_ci| 9762306a36Sopenharmony_ci subE = E2 9862306a36Sopenharmony_ci| 9962306a36Sopenharmony_ci subE++ 10062306a36Sopenharmony_ci| 10162306a36Sopenharmony_ci ++subE 10262306a36Sopenharmony_ci| 10362306a36Sopenharmony_ci --subE 10462306a36Sopenharmony_ci| 10562306a36Sopenharmony_ci subE-- 10662306a36Sopenharmony_ci| 10762306a36Sopenharmony_ci &subE 10862306a36Sopenharmony_ci| 10962306a36Sopenharmony_ci BUG(...) 11062306a36Sopenharmony_ci| 11162306a36Sopenharmony_ci BUG_ON(...) 11262306a36Sopenharmony_ci| 11362306a36Sopenharmony_ci return_VALUE(...) 11462306a36Sopenharmony_ci| 11562306a36Sopenharmony_ci return_ACPI_STATUS(...) 11662306a36Sopenharmony_ci| 11762306a36Sopenharmony_ci E@p2 // bad use 11862306a36Sopenharmony_ci) 11962306a36Sopenharmony_ci 12062306a36Sopenharmony_ci@script:python depends on org@ 12162306a36Sopenharmony_cip1 << free.p1; 12262306a36Sopenharmony_cip2 << r.p2; 12362306a36Sopenharmony_ci@@ 12462306a36Sopenharmony_ci 12562306a36Sopenharmony_cicocci.print_main("kfree",p1) 12662306a36Sopenharmony_cicocci.print_secs("ref",p2) 12762306a36Sopenharmony_ci 12862306a36Sopenharmony_ci@script:python depends on report@ 12962306a36Sopenharmony_cip1 << free.p1; 13062306a36Sopenharmony_cip2 << r.p2; 13162306a36Sopenharmony_ci@@ 13262306a36Sopenharmony_ci 13362306a36Sopenharmony_cimsg = "ERROR: reference preceded by free on line %s" % (p1[0].line) 13462306a36Sopenharmony_cicoccilib.report.print_report(p2[0],msg) 135