0001 // SPDX-License-Identifier: GPL-2.0-only
0002 ///
0003 /// Check for array_size(), array3_size(), struct_size() duplicates.
0004 /// These patterns are detected:
0005 /// 1. An opencoded expression is used before array_size() to compute the same size
0006 /// 2. An opencoded expression is used after array_size() to compute the same size
0007 /// From security point of view only first case is relevant. These functions
0008 /// perform arithmetic overflow check. Thus, if we use an opencoded expression
0009 /// before a call to the *_size() function we can miss an overflow.
0010 ///
0011 // Confidence: High
0012 // Copyright: (C) 2020 Denis Efremov ISPRAS
0013 // Options: --no-includes --include-headers --no-loops
0014
0015 virtual context
0016 virtual report
0017 virtual org
0018
0019 @as@
0020 expression E1, E2;
0021 @@
0022
0023 array_size(E1, E2)
0024
0025 @as_next@
0026 expression subE1 <= as.E1;
0027 expression subE2 <= as.E2;
0028 expression as.E1, as.E2, E3;
0029 assignment operator aop;
0030 position p1, p2;
0031 @@
0032
0033 * E1 * E2@p1
0034 ... when != \(subE1\|subE2\) aop E3
0035 when != &\(subE1\|subE2\)
0036 * array_size(E1, E2)@p2
0037
0038 @script:python depends on report@
0039 p1 << as_next.p1;
0040 p2 << as_next.p2;
0041 @@
0042
0043 msg = "WARNING: array_size is used later (line %s) to compute the same size" % (p2[0].line)
0044 coccilib.report.print_report(p1[0], msg)
0045
0046 @script:python depends on org@
0047 p1 << as_next.p1;
0048 p2 << as_next.p2;
0049 @@
0050
0051 msg = "WARNING: array_size is used later (line %s) to compute the same size" % (p2[0].line)
0052 coccilib.org.print_todo(p1[0], msg)
0053
0054 @as_prev@
0055 expression subE1 <= as.E1;
0056 expression subE2 <= as.E2;
0057 expression as.E1, as.E2, E3;
0058 assignment operator aop;
0059 position p1, p2;
0060 @@
0061
0062 * array_size(E1, E2)@p1
0063 ... when != \(subE1\|subE2\) aop E3
0064 when != &\(subE1\|subE2\)
0065 * E1 * E2@p2
0066
0067 @script:python depends on report@
0068 p1 << as_prev.p1;
0069 p2 << as_prev.p2;
0070 @@
0071
0072 msg = "WARNING: array_size is already used (line %s) to compute the same size" % (p1[0].line)
0073 coccilib.report.print_report(p2[0], msg)
0074
0075 @script:python depends on org@
0076 p1 << as_prev.p1;
0077 p2 << as_prev.p2;
0078 @@
0079
0080 msg = "WARNING: array_size is already used (line %s) to compute the same size" % (p1[0].line)
0081 coccilib.org.print_todo(p2[0], msg)
0082
0083 @as3@
0084 expression E1, E2, E3;
0085 @@
0086
0087 array3_size(E1, E2, E3)
0088
0089 @as3_next@
0090 expression subE1 <= as3.E1;
0091 expression subE2 <= as3.E2;
0092 expression subE3 <= as3.E3;
0093 expression as3.E1, as3.E2, as3.E3, E4;
0094 assignment operator aop;
0095 position p1, p2;
0096 @@
0097
0098 * E1 * E2 * E3@p1
0099 ... when != \(subE1\|subE2\|subE3\) aop E4
0100 when != &\(subE1\|subE2\|subE3\)
0101 * array3_size(E1, E2, E3)@p2
0102
0103 @script:python depends on report@
0104 p1 << as3_next.p1;
0105 p2 << as3_next.p2;
0106 @@
0107
0108 msg = "WARNING: array3_size is used later (line %s) to compute the same size" % (p2[0].line)
0109 coccilib.report.print_report(p1[0], msg)
0110
0111 @script:python depends on org@
0112 p1 << as3_next.p1;
0113 p2 << as3_next.p2;
0114 @@
0115
0116 msg = "WARNING: array3_size is used later (line %s) to compute the same size" % (p2[0].line)
0117 coccilib.org.print_todo(p1[0], msg)
0118
0119 @as3_prev@
0120 expression subE1 <= as3.E1;
0121 expression subE2 <= as3.E2;
0122 expression subE3 <= as3.E3;
0123 expression as3.E1, as3.E2, as3.E3, E4;
0124 assignment operator aop;
0125 position p1, p2;
0126 @@
0127
0128 * array3_size(E1, E2, E3)@p1
0129 ... when != \(subE1\|subE2\|subE3\) aop E4
0130 when != &\(subE1\|subE2\|subE3\)
0131 * E1 * E2 * E3@p2
0132
0133 @script:python depends on report@
0134 p1 << as3_prev.p1;
0135 p2 << as3_prev.p2;
0136 @@
0137
0138 msg = "WARNING: array3_size is already used (line %s) to compute the same size" % (p1[0].line)
0139 coccilib.report.print_report(p2[0], msg)
0140
0141 @script:python depends on org@
0142 p1 << as3_prev.p1;
0143 p2 << as3_prev.p2;
0144 @@
0145
0146 msg = "WARNING: array3_size is already used (line %s) to compute the same size" % (p1[0].line)
0147 coccilib.org.print_todo(p2[0], msg)
0148
0149 @ss@
0150 expression E1, E2, E3;
0151 @@
0152
0153 struct_size(E1, E2, E3)
0154
0155 @ss_next@
0156 expression subE3 <= ss.E3;
0157 expression ss.E1, ss.E2, ss.E3, E4;
0158 assignment operator aop;
0159 position p1, p2;
0160 @@
0161
0162 * E1 * E2 + E3@p1
0163 ... when != subE3 aop E4
0164 when != &subE3
0165 * struct_size(E1, E2, E3)@p2
0166
0167 @script:python depends on report@
0168 p1 << ss_next.p1;
0169 p2 << ss_next.p2;
0170 @@
0171
0172 msg = "WARNING: struct_size is used later (line %s) to compute the same size" % (p2[0].line)
0173 coccilib.report.print_report(p1[0], msg)
0174
0175 @script:python depends on org@
0176 p1 << ss_next.p1;
0177 p2 << ss_next.p2;
0178 @@
0179
0180 msg = "WARNING: struct_size is used later (line %s) to compute the same size" % (p2[0].line)
0181 coccilib.org.print_todo(p1[0], msg)
0182
0183 @ss_prev@
0184 expression subE3 <= ss.E3;
0185 expression ss.E1, ss.E2, ss.E3, E4;
0186 assignment operator aop;
0187 position p1, p2;
0188 @@
0189
0190 * struct_size(E1, E2, E3)@p1
0191 ... when != subE3 aop E4
0192 when != &subE3
0193 * E1 * E2 + E3@p2
0194
0195 @script:python depends on report@
0196 p1 << ss_prev.p1;
0197 p2 << ss_prev.p2;
0198 @@
0199
0200 msg = "WARNING: struct_size is already used (line %s) to compute the same size" % (p1[0].line)
0201 coccilib.report.print_report(p2[0], msg)
0202
0203 @script:python depends on org@
0204 p1 << ss_prev.p1;
0205 p2 << ss_prev.p2;
0206 @@
0207
0208 msg = "WARNING: struct_size is already used (line %s) to compute the same size" % (p1[0].line)
0209 coccilib.org.print_todo(p2[0], msg)