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