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