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