1/// If list_for_each_entry, etc complete a traversal of the list, the iterator 2/// variable ends up pointing to an address at an offset from the list head, 3/// and not a meaningful structure. Thus this value should not be used after 4/// the end of the iterator. 5//#False positives arise when there is a goto in the iterator and the 6//#reported reference is at the label of this goto. Some flag tests 7//#may also cause a report to be a false positive. 8/// 9// Confidence: Moderate 10// Copyright: (C) 2012 Julia Lawall, INRIA/LIP6. GPLv2. 11// Copyright: (C) 2012 Gilles Muller, INRIA/LIP6. GPLv2. 12// URL: http://coccinelle.lip6.fr/ 13// Comments: 14// Options: --no-includes --include-headers 15 16virtual context 17virtual org 18virtual report 19 20@r exists@ 21identifier c,member; 22expression E,x; 23iterator name list_for_each_entry; 24iterator name list_for_each_entry_reverse; 25iterator name list_for_each_entry_continue; 26iterator name list_for_each_entry_continue_reverse; 27iterator name list_for_each_entry_from; 28iterator name list_for_each_entry_safe; 29iterator name list_for_each_entry_safe_continue; 30iterator name list_for_each_entry_safe_from; 31iterator name list_for_each_entry_safe_reverse; 32iterator name hlist_for_each_entry; 33iterator name hlist_for_each_entry_continue; 34iterator name hlist_for_each_entry_from; 35iterator name hlist_for_each_entry_safe; 36statement S; 37position p1,p2; 38type T; 39@@ 40 41( 42list_for_each_entry@p1(c,...,member) { ... when != break; 43 when forall 44 when strict 45} 46| 47list_for_each_entry_reverse@p1(c,...,member) { ... when != break; 48 when forall 49 when strict 50} 51| 52list_for_each_entry_continue@p1(c,...,member) { ... when != break; 53 when forall 54 when strict 55} 56| 57list_for_each_entry_continue_reverse@p1(c,...,member) { ... when != break; 58 when forall 59 when strict 60} 61| 62list_for_each_entry_from@p1(c,...,member) { ... when != break; 63 when forall 64 when strict 65} 66| 67list_for_each_entry_safe@p1(c,...,member) { ... when != break; 68 when forall 69 when strict 70} 71| 72list_for_each_entry_safe_continue@p1(c,...,member) { ... when != break; 73 when forall 74 when strict 75} 76| 77list_for_each_entry_safe_from@p1(c,...,member) { ... when != break; 78 when forall 79 when strict 80} 81| 82list_for_each_entry_safe_reverse@p1(c,...,member) { ... when != break; 83 when forall 84 when strict 85} 86) 87... 88( 89list_for_each_entry(c,...) S 90| 91list_for_each_entry_reverse(c,...) S 92| 93list_for_each_entry_continue(c,...) S 94| 95list_for_each_entry_continue_reverse(c,...) S 96| 97list_for_each_entry_from(c,...) S 98| 99list_for_each_entry_safe(c,...) S 100| 101list_for_each_entry_safe(x,c,...) S 102| 103list_for_each_entry_safe_continue(c,...) S 104| 105list_for_each_entry_safe_continue(x,c,...) S 106| 107list_for_each_entry_safe_from(c,...) S 108| 109list_for_each_entry_safe_from(x,c,...) S 110| 111list_for_each_entry_safe_reverse(c,...) S 112| 113list_for_each_entry_safe_reverse(x,c,...) S 114| 115hlist_for_each_entry(c,...) S 116| 117hlist_for_each_entry_continue(c,...) S 118| 119hlist_for_each_entry_from(c,...) S 120| 121hlist_for_each_entry_safe(c,...) S 122| 123list_remove_head(x,c,...) 124| 125sizeof(<+...c...+>) 126| 127 &c->member 128| 129T c; 130| 131c = E 132| 133*c@p2 134) 135 136@script:python depends on org@ 137p1 << r.p1; 138p2 << r.p2; 139@@ 140 141cocci.print_main("invalid iterator index reference",p2) 142cocci.print_secs("iterator",p1) 143 144@script:python depends on report@ 145p1 << r.p1; 146p2 << r.p2; 147@@ 148 149msg = "ERROR: invalid reference to the index variable of the iterator on line %s" % (p1[0].line) 150coccilib.report.print_report(p2[0], msg) 151