xref: /openbmc/linux/scripts/coccinelle/free/kfree.cocci (revision 4f2c0a4acffbec01079c28f839422e64ddeff004)
17f904d7eSThomas Gleixner// SPDX-License-Identifier: GPL-2.0-only
2e90f6590SNicolas Palix/// Find a use after free.
3e90f6590SNicolas Palix//# Values of variables may imply that some
4e90f6590SNicolas Palix//# execution paths are not possible, resulting in false positives.
5e90f6590SNicolas Palix//# Another source of false positives are macros such as
6e90f6590SNicolas Palix//# SCTP_DBG_OBJCNT_DEC that do not actually evaluate their argument
743ba21b5SNicolas Palix///
843ba21b5SNicolas Palix// Confidence: Moderate
97f904d7eSThomas Gleixner// Copyright: (C) 2010-2012 Nicolas Palix.
107f904d7eSThomas Gleixner// Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6.
117f904d7eSThomas Gleixner// Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6.
12*f01701ceSJulia Lawall// URL: https://coccinelle.gitlabpages.inria.fr/website
1343ba21b5SNicolas Palix// Comments:
1493f14468SNicolas Palix// Options: --no-includes --include-headers
1543ba21b5SNicolas Palix
1643ba21b5SNicolas Palixvirtual org
1743ba21b5SNicolas Palixvirtual report
1843ba21b5SNicolas Palix
1943ba21b5SNicolas Palix@free@
2043ba21b5SNicolas Palixexpression E;
2143ba21b5SNicolas Palixposition p1;
2243ba21b5SNicolas Palix@@
2343ba21b5SNicolas Palix
246dd9379eSYann Droneaud(
2532c46561SJulia Lawall kfree@p1(E)
266dd9379eSYann Droneaud|
2732c46561SJulia Lawall kfree_sensitive@p1(E)
286dd9379eSYann Droneaud)
2943ba21b5SNicolas Palix
3043ba21b5SNicolas Palix@print expression@
3129a36d4dSJulia Lawallconstant char [] c;
3243ba21b5SNicolas Palixexpression free.E,E2;
3343ba21b5SNicolas Palixtype T;
3443ba21b5SNicolas Palixposition p;
3543ba21b5SNicolas Palixidentifier f;
3643ba21b5SNicolas Palix@@
3743ba21b5SNicolas Palix
3843ba21b5SNicolas Palix(
3943ba21b5SNicolas Palix f(...,c,...,(T)E@p,...)
4043ba21b5SNicolas Palix|
4143ba21b5SNicolas Palix E@p == E2
4243ba21b5SNicolas Palix|
4343ba21b5SNicolas Palix E@p != E2
4443ba21b5SNicolas Palix|
4529a36d4dSJulia Lawall E2 == E@p
4629a36d4dSJulia Lawall|
4729a36d4dSJulia Lawall E2 != E@p
4829a36d4dSJulia Lawall|
4943ba21b5SNicolas Palix !E@p
5043ba21b5SNicolas Palix|
5143ba21b5SNicolas Palix E@p || ...
5243ba21b5SNicolas Palix)
5343ba21b5SNicolas Palix
5443ba21b5SNicolas Palix@sz@
5543ba21b5SNicolas Palixexpression free.E;
5643ba21b5SNicolas Palixposition p;
5743ba21b5SNicolas Palix@@
5843ba21b5SNicolas Palix
5943ba21b5SNicolas Palix sizeof(<+...E@p...+>)
6043ba21b5SNicolas Palix
6143ba21b5SNicolas Palix@loop exists@
6243ba21b5SNicolas Palixexpression E;
6343ba21b5SNicolas Palixidentifier l;
6443ba21b5SNicolas Palixposition ok;
6543ba21b5SNicolas Palix@@
6643ba21b5SNicolas Palix
6743ba21b5SNicolas Palixwhile (1) { ...
686dd9379eSYann Droneaud(
6932c46561SJulia Lawall kfree@ok(E)
706dd9379eSYann Droneaud|
7132c46561SJulia Lawall kfree_sensitive@ok(E)
726dd9379eSYann Droneaud)
7343ba21b5SNicolas Palix  ... when != break;
7443ba21b5SNicolas Palix      when != goto l;
7543ba21b5SNicolas Palix      when forall
7643ba21b5SNicolas Palix}
7743ba21b5SNicolas Palix
7843ba21b5SNicolas Palix@r exists@
7943ba21b5SNicolas Palixexpression free.E, subE<=free.E, E2;
8043ba21b5SNicolas Palixexpression E1;
8143ba21b5SNicolas Palixiterator iter;
8243ba21b5SNicolas Palixstatement S;
8343ba21b5SNicolas Palixposition free.p1!=loop.ok,p2!={print.p,sz.p};
8443ba21b5SNicolas Palix@@
8543ba21b5SNicolas Palix
866dd9379eSYann Droneaud(
8732c46561SJulia Lawall kfree@p1(E,...)
886dd9379eSYann Droneaud|
8932c46561SJulia Lawall kfree_sensitive@p1(E,...)
906dd9379eSYann Droneaud)
9143ba21b5SNicolas Palix...
9243ba21b5SNicolas Palix(
9343ba21b5SNicolas Palix iter(...,subE,...) S // no use
9443ba21b5SNicolas Palix|
9543ba21b5SNicolas Palix list_remove_head(E1,subE,...)
9643ba21b5SNicolas Palix|
9743ba21b5SNicolas Palix subE = E2
9843ba21b5SNicolas Palix|
9943ba21b5SNicolas Palix subE++
10043ba21b5SNicolas Palix|
10143ba21b5SNicolas Palix ++subE
10243ba21b5SNicolas Palix|
10343ba21b5SNicolas Palix --subE
10443ba21b5SNicolas Palix|
10543ba21b5SNicolas Palix subE--
10643ba21b5SNicolas Palix|
10743ba21b5SNicolas Palix &subE
10843ba21b5SNicolas Palix|
10943ba21b5SNicolas Palix BUG(...)
11043ba21b5SNicolas Palix|
11143ba21b5SNicolas Palix BUG_ON(...)
11243ba21b5SNicolas Palix|
11343ba21b5SNicolas Palix return_VALUE(...)
11443ba21b5SNicolas Palix|
11543ba21b5SNicolas Palix return_ACPI_STATUS(...)
11643ba21b5SNicolas Palix|
11743ba21b5SNicolas Palix E@p2 // bad use
11843ba21b5SNicolas Palix)
11943ba21b5SNicolas Palix
12043ba21b5SNicolas Palix@script:python depends on org@
12143ba21b5SNicolas Palixp1 << free.p1;
12243ba21b5SNicolas Palixp2 << r.p2;
12343ba21b5SNicolas Palix@@
12443ba21b5SNicolas Palix
12543ba21b5SNicolas Palixcocci.print_main("kfree",p1)
12643ba21b5SNicolas Palixcocci.print_secs("ref",p2)
12743ba21b5SNicolas Palix
12843ba21b5SNicolas Palix@script:python depends on report@
12943ba21b5SNicolas Palixp1 << free.p1;
13043ba21b5SNicolas Palixp2 << r.p2;
13143ba21b5SNicolas Palix@@
13243ba21b5SNicolas Palix
13329a36d4dSJulia Lawallmsg = "ERROR: reference preceded by free on line %s" % (p1[0].line)
13443ba21b5SNicolas Palixcoccilib.report.print_report(p2[0],msg)
135