History

scripts/coccinelle: list iterator variable semantic patch

If list_for_each_entry, etc complete a traversal of the list, the iterator variable ends up pointing to an address at an offset from the list head, and not a meaningful structure. Thus this value should not be used after the end of the iterator.

Julia Lawall committed 14 years ago

Commit 6fcd5f21 parent f1f45501 file · +147 −0Browse files

Unified · Split

scripts/coccinelle/iterators/use_after_iter.cocci+147−0
@@ -0,0 +1,147 @@
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+
16+virtual context
17+virtual org
18+virtual report
19+
20+@r exists@
21+identifier c,member;
22+expression E,x;
23+iterator name list_for_each_entry;
24+iterator name list_for_each_entry_reverse;
25+iterator name list_for_each_entry_continue;
26+iterator name list_for_each_entry_continue_reverse;
27+iterator name list_for_each_entry_from;
28+iterator name list_for_each_entry_safe;
29+iterator name list_for_each_entry_safe_continue;
30+iterator name list_for_each_entry_safe_from;
31+iterator name list_for_each_entry_safe_reverse;
32+iterator name hlist_for_each_entry;
33+iterator name hlist_for_each_entry_continue;
34+iterator name hlist_for_each_entry_from;
35+iterator name hlist_for_each_entry_safe;
36+statement S;
37+position p1,p2;
38+@@
39+
40+(
41+list_for_each_entry@p1(c,...,member) { ... when != break;
42+ when forall
43+ when strict
44+}
45+|
46+list_for_each_entry_reverse@p1(c,...,member) { ... when != break;
47+ when forall
48+ when strict
49+}
50+|
51+list_for_each_entry_continue@p1(c,...,member) { ... when != break;
52+ when forall
53+ when strict
54+}
55+|
56+list_for_each_entry_continue_reverse@p1(c,...,member) { ... when != break;
57+ when forall
58+ when strict
59+}
60+|
61+list_for_each_entry_from@p1(c,...,member) { ... when != break;
62+ when forall
63+ when strict
64+}
65+|
66+list_for_each_entry_safe@p1(c,...,member) { ... when != break;
67+ when forall
68+ when strict
69+}
70+|
71+list_for_each_entry_safe_continue@p1(c,...,member) { ... when != break;
72+ when forall
73+ when strict
74+}
75+|
76+list_for_each_entry_safe_from@p1(c,...,member) { ... when != break;
77+ when forall
78+ when strict
79+}
80+|
81+list_for_each_entry_safe_reverse@p1(c,...,member) { ... when != break;
82+ when forall
83+ when strict
84+}
85+)
86+...
87+(
88+list_for_each_entry(c,...) S
89+|
90+list_for_each_entry_reverse(c,...) S
91+|
92+list_for_each_entry_continue(c,...) S
93+|
94+list_for_each_entry_continue_reverse(c,...) S
95+|
96+list_for_each_entry_from(c,...) S
97+|
98+list_for_each_entry_safe(c,...) S
99+|
100+list_for_each_entry_safe(x,c,...) S
101+|
102+list_for_each_entry_safe_continue(c,...) S
103+|
104+list_for_each_entry_safe_continue(x,c,...) S
105+|
106+list_for_each_entry_safe_from(c,...) S
107+|
108+list_for_each_entry_safe_from(x,c,...) S
109+|
110+list_for_each_entry_safe_reverse(c,...) S
111+|
112+list_for_each_entry_safe_reverse(x,c,...) S
113+|
114+hlist_for_each_entry(c,...) S
115+|
116+hlist_for_each_entry_continue(c,...) S
117+|
118+hlist_for_each_entry_from(c,...) S
119+|
120+hlist_for_each_entry_safe(c,...) S
121+|
122+list_remove_head(x,c,...)
123+|
124+sizeof(<+...c...+>)
125+|
126+&c->member
127+|
128+c = E
129+|
130+*c@p2
131+)
132+
133+@script:python depends on org@
134+p1 << r.p1;
135+p2 << r.p2;
136+@@
137+
138+cocci.print_main("invalid iterator index reference",p2)
139+cocci.print_secs("iterator",p1)
140+
141+@script:python depends on report@
142+p1 << r.p1;
143+p2 << r.p2;
144+@@
145+
146+msg = "ERROR: invalid reference to the index variable of the iterator on line %s" % (p1[0].line)
147+coccilib.report.print_report(p2[0], msg)