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