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