Skip to content

Commit de50862

Browse files
evdenisJuliaLawall
authored andcommitted
coccinelle: misc: add array_size_dup script to detect missed overflow checks
Detect an opencoded expression that is used before or after array_size()/array3_size()/struct_size() to compute the same size. Signed-off-by: Denis Efremov <[email protected]> Signed-off-by: Julia Lawall <[email protected]>
1 parent 2fbecb7 commit de50862

File tree

1 file changed

+209
-0
lines changed

1 file changed

+209
-0
lines changed
Lines changed: 209 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,209 @@
1+
// SPDX-License-Identifier: GPL-2.0-only
2+
///
3+
/// Check for array_size(), array3_size(), struct_size() duplicates.
4+
/// These patterns are detected:
5+
/// 1. An opencoded expression is used before array_size() to compute the same size
6+
/// 2. An opencoded expression is used after array_size() to compute the same size
7+
/// From security point of view only first case is relevant. These functions
8+
/// perform arithmetic overflow check. Thus, if we use an opencoded expression
9+
/// before a call to the *_size() function we can miss an overflow.
10+
///
11+
// Confidence: High
12+
// Copyright: (C) 2020 Denis Efremov ISPRAS
13+
// Options: --no-includes --include-headers --no-loops
14+
15+
virtual context
16+
virtual report
17+
virtual org
18+
19+
@as@
20+
expression E1, E2;
21+
@@
22+
23+
array_size(E1, E2)
24+
25+
@as_next@
26+
expression subE1 <= as.E1;
27+
expression subE2 <= as.E2;
28+
expression as.E1, as.E2, E3;
29+
assignment operator aop;
30+
position p1, p2;
31+
@@
32+
33+
* E1 * E2@p1
34+
... when != \(subE1\|subE2\) aop E3
35+
when != &\(subE1\|subE2\)
36+
* array_size(E1, E2)@p2
37+
38+
@script:python depends on report@
39+
p1 << as_next.p1;
40+
p2 << as_next.p2;
41+
@@
42+
43+
msg = "WARNING: array_size is used later (line %s) to compute the same size" % (p2[0].line)
44+
coccilib.report.print_report(p1[0], msg)
45+
46+
@script:python depends on org@
47+
p1 << as_next.p1;
48+
p2 << as_next.p2;
49+
@@
50+
51+
msg = "WARNING: array_size is used later (line %s) to compute the same size" % (p2[0].line)
52+
coccilib.org.print_todo(p1[0], msg)
53+
54+
@as_prev@
55+
expression subE1 <= as.E1;
56+
expression subE2 <= as.E2;
57+
expression as.E1, as.E2, E3;
58+
assignment operator aop;
59+
position p1, p2;
60+
@@
61+
62+
* array_size(E1, E2)@p1
63+
... when != \(subE1\|subE2\) aop E3
64+
when != &\(subE1\|subE2\)
65+
* E1 * E2@p2
66+
67+
@script:python depends on report@
68+
p1 << as_prev.p1;
69+
p2 << as_prev.p2;
70+
@@
71+
72+
msg = "WARNING: array_size is already used (line %s) to compute the same size" % (p1[0].line)
73+
coccilib.report.print_report(p2[0], msg)
74+
75+
@script:python depends on org@
76+
p1 << as_prev.p1;
77+
p2 << as_prev.p2;
78+
@@
79+
80+
msg = "WARNING: array_size is already used (line %s) to compute the same size" % (p1[0].line)
81+
coccilib.org.print_todo(p2[0], msg)
82+
83+
@as3@
84+
expression E1, E2, E3;
85+
@@
86+
87+
array3_size(E1, E2, E3)
88+
89+
@as3_next@
90+
expression subE1 <= as3.E1;
91+
expression subE2 <= as3.E2;
92+
expression subE3 <= as3.E3;
93+
expression as3.E1, as3.E2, as3.E3, E4;
94+
assignment operator aop;
95+
position p1, p2;
96+
@@
97+
98+
* E1 * E2 * E3@p1
99+
... when != \(subE1\|subE2\|subE3\) aop E4
100+
when != &\(subE1\|subE2\|subE3\)
101+
* array3_size(E1, E2, E3)@p2
102+
103+
@script:python depends on report@
104+
p1 << as3_next.p1;
105+
p2 << as3_next.p2;
106+
@@
107+
108+
msg = "WARNING: array3_size is used later (line %s) to compute the same size" % (p2[0].line)
109+
coccilib.report.print_report(p1[0], msg)
110+
111+
@script:python depends on org@
112+
p1 << as3_next.p1;
113+
p2 << as3_next.p2;
114+
@@
115+
116+
msg = "WARNING: array3_size is used later (line %s) to compute the same size" % (p2[0].line)
117+
coccilib.org.print_todo(p1[0], msg)
118+
119+
@as3_prev@
120+
expression subE1 <= as3.E1;
121+
expression subE2 <= as3.E2;
122+
expression subE3 <= as3.E3;
123+
expression as3.E1, as3.E2, as3.E3, E4;
124+
assignment operator aop;
125+
position p1, p2;
126+
@@
127+
128+
* array3_size(E1, E2, E3)@p1
129+
... when != \(subE1\|subE2\|subE3\) aop E4
130+
when != &\(subE1\|subE2\|subE3\)
131+
* E1 * E2 * E3@p2
132+
133+
@script:python depends on report@
134+
p1 << as3_prev.p1;
135+
p2 << as3_prev.p2;
136+
@@
137+
138+
msg = "WARNING: array3_size is already used (line %s) to compute the same size" % (p1[0].line)
139+
coccilib.report.print_report(p2[0], msg)
140+
141+
@script:python depends on org@
142+
p1 << as3_prev.p1;
143+
p2 << as3_prev.p2;
144+
@@
145+
146+
msg = "WARNING: array3_size is already used (line %s) to compute the same size" % (p1[0].line)
147+
coccilib.org.print_todo(p2[0], msg)
148+
149+
@ss@
150+
expression E1, E2, E3;
151+
@@
152+
153+
struct_size(E1, E2, E3)
154+
155+
@ss_next@
156+
expression subE3 <= ss.E3;
157+
expression ss.E1, ss.E2, ss.E3, E4;
158+
assignment operator aop;
159+
position p1, p2;
160+
@@
161+
162+
* E1 * E2 + E3@p1
163+
... when != subE3 aop E4
164+
when != &subE3
165+
* struct_size(E1, E2, E3)@p2
166+
167+
@script:python depends on report@
168+
p1 << ss_next.p1;
169+
p2 << ss_next.p2;
170+
@@
171+
172+
msg = "WARNING: struct_size is used later (line %s) to compute the same size" % (p2[0].line)
173+
coccilib.report.print_report(p1[0], msg)
174+
175+
@script:python depends on org@
176+
p1 << ss_next.p1;
177+
p2 << ss_next.p2;
178+
@@
179+
180+
msg = "WARNING: struct_size is used later (line %s) to compute the same size" % (p2[0].line)
181+
coccilib.org.print_todo(p1[0], msg)
182+
183+
@ss_prev@
184+
expression subE3 <= ss.E3;
185+
expression ss.E1, ss.E2, ss.E3, E4;
186+
assignment operator aop;
187+
position p1, p2;
188+
@@
189+
190+
* struct_size(E1, E2, E3)@p1
191+
... when != subE3 aop E4
192+
when != &subE3
193+
* E1 * E2 + E3@p2
194+
195+
@script:python depends on report@
196+
p1 << ss_prev.p1;
197+
p2 << ss_prev.p2;
198+
@@
199+
200+
msg = "WARNING: struct_size is already used (line %s) to compute the same size" % (p1[0].line)
201+
coccilib.report.print_report(p2[0], msg)
202+
203+
@script:python depends on org@
204+
p1 << ss_prev.p1;
205+
p2 << ss_prev.p2;
206+
@@
207+
208+
msg = "WARNING: struct_size is already used (line %s) to compute the same size" % (p1[0].line)
209+
coccilib.org.print_todo(p2[0], msg)

0 commit comments

Comments
 (0)