1*4882a593Smuzhiyun// SPDX-License-Identifier: GPL-2.0-only 2*4882a593Smuzhiyun/// 3*4882a593Smuzhiyun/// A variable is dereferenced under a NULL test. 4*4882a593Smuzhiyun/// Even though it is known to be NULL. 5*4882a593Smuzhiyun/// 6*4882a593Smuzhiyun// Confidence: Moderate 7*4882a593Smuzhiyun// Copyright: (C) 2010 Nicolas Palix, DIKU. 8*4882a593Smuzhiyun// Copyright: (C) 2010 Julia Lawall, DIKU. 9*4882a593Smuzhiyun// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. 10*4882a593Smuzhiyun// URL: http://coccinelle.lip6.fr/ 11*4882a593Smuzhiyun// Comments: -I ... -all_includes can give more complete results 12*4882a593Smuzhiyun// Options: 13*4882a593Smuzhiyun 14*4882a593Smuzhiyunvirtual context 15*4882a593Smuzhiyunvirtual org 16*4882a593Smuzhiyunvirtual report 17*4882a593Smuzhiyun 18*4882a593Smuzhiyun// The following two rules are separate, because both can match a single 19*4882a593Smuzhiyun// expression in different ways 20*4882a593Smuzhiyun@pr1 expression@ 21*4882a593Smuzhiyunexpression E; 22*4882a593Smuzhiyunidentifier f; 23*4882a593Smuzhiyunposition p1; 24*4882a593Smuzhiyun@@ 25*4882a593Smuzhiyun 26*4882a593Smuzhiyun (E != NULL && ...) ? <+...E->f@p1...+> : ... 27*4882a593Smuzhiyun 28*4882a593Smuzhiyun@pr2 expression@ 29*4882a593Smuzhiyunexpression E; 30*4882a593Smuzhiyunidentifier f; 31*4882a593Smuzhiyunposition p2; 32*4882a593Smuzhiyun@@ 33*4882a593Smuzhiyun 34*4882a593Smuzhiyun( 35*4882a593Smuzhiyun (E != NULL) && ... && <+...E->f@p2...+> 36*4882a593Smuzhiyun| 37*4882a593Smuzhiyun (E == NULL) || ... || <+...E->f@p2...+> 38*4882a593Smuzhiyun| 39*4882a593Smuzhiyun sizeof(<+...E->f@p2...+>) 40*4882a593Smuzhiyun) 41*4882a593Smuzhiyun 42*4882a593Smuzhiyun@ifm@ 43*4882a593Smuzhiyunexpression *E; 44*4882a593Smuzhiyunstatement S1,S2; 45*4882a593Smuzhiyunposition p1; 46*4882a593Smuzhiyun@@ 47*4882a593Smuzhiyun 48*4882a593Smuzhiyunif@p1 ((E == NULL && ...) || ...) S1 else S2 49*4882a593Smuzhiyun 50*4882a593Smuzhiyun// For org and report modes 51*4882a593Smuzhiyun 52*4882a593Smuzhiyun@r depends on !context && (org || report) exists@ 53*4882a593Smuzhiyunexpression subE <= ifm.E; 54*4882a593Smuzhiyunexpression *ifm.E; 55*4882a593Smuzhiyunexpression E1,E2; 56*4882a593Smuzhiyunidentifier f; 57*4882a593Smuzhiyunstatement S1,S2,S3,S4; 58*4882a593Smuzhiyuniterator iter; 59*4882a593Smuzhiyunposition p!={pr1.p1,pr2.p2}; 60*4882a593Smuzhiyunposition ifm.p1; 61*4882a593Smuzhiyun@@ 62*4882a593Smuzhiyun 63*4882a593Smuzhiyunif@p1 ((E == NULL && ...) || ...) 64*4882a593Smuzhiyun{ 65*4882a593Smuzhiyun ... when != if (...) S1 else S2 66*4882a593Smuzhiyun( 67*4882a593Smuzhiyun iter(subE,...) S4 // no use 68*4882a593Smuzhiyun| 69*4882a593Smuzhiyun list_remove_head(E2,subE,...) 70*4882a593Smuzhiyun| 71*4882a593Smuzhiyun subE = E1 72*4882a593Smuzhiyun| 73*4882a593Smuzhiyun for(subE = E1;...;...) S4 74*4882a593Smuzhiyun| 75*4882a593Smuzhiyun subE++ 76*4882a593Smuzhiyun| 77*4882a593Smuzhiyun ++subE 78*4882a593Smuzhiyun| 79*4882a593Smuzhiyun --subE 80*4882a593Smuzhiyun| 81*4882a593Smuzhiyun subE-- 82*4882a593Smuzhiyun| 83*4882a593Smuzhiyun &subE 84*4882a593Smuzhiyun| 85*4882a593Smuzhiyun E->f@p // bad use 86*4882a593Smuzhiyun) 87*4882a593Smuzhiyun ... when any 88*4882a593Smuzhiyun return ...; 89*4882a593Smuzhiyun} 90*4882a593Smuzhiyunelse S3 91*4882a593Smuzhiyun 92*4882a593Smuzhiyun@script:python depends on !context && !org && report@ 93*4882a593Smuzhiyunp << r.p; 94*4882a593Smuzhiyunp1 << ifm.p1; 95*4882a593Smuzhiyunx << ifm.E; 96*4882a593Smuzhiyun@@ 97*4882a593Smuzhiyun 98*4882a593Smuzhiyunmsg="ERROR: %s is NULL but dereferenced." % (x) 99*4882a593Smuzhiyuncoccilib.report.print_report(p[0], msg) 100*4882a593Smuzhiyuncocci.include_match(False) 101*4882a593Smuzhiyun 102*4882a593Smuzhiyun@script:python depends on !context && org && !report@ 103*4882a593Smuzhiyunp << r.p; 104*4882a593Smuzhiyunp1 << ifm.p1; 105*4882a593Smuzhiyunx << ifm.E; 106*4882a593Smuzhiyun@@ 107*4882a593Smuzhiyun 108*4882a593Smuzhiyunmsg="ERROR: %s is NULL but dereferenced." % (x) 109*4882a593Smuzhiyunmsg_safe=msg.replace("[","@(").replace("]",")") 110*4882a593Smuzhiyuncocci.print_main(msg_safe,p) 111*4882a593Smuzhiyuncocci.include_match(False) 112*4882a593Smuzhiyun 113*4882a593Smuzhiyun@s depends on !context && (org || report) exists@ 114*4882a593Smuzhiyunexpression subE <= ifm.E; 115*4882a593Smuzhiyunexpression *ifm.E; 116*4882a593Smuzhiyunexpression E1,E2; 117*4882a593Smuzhiyunidentifier f; 118*4882a593Smuzhiyunstatement S1,S2,S3,S4; 119*4882a593Smuzhiyuniterator iter; 120*4882a593Smuzhiyunposition p!={pr1.p1,pr2.p2}; 121*4882a593Smuzhiyunposition ifm.p1; 122*4882a593Smuzhiyun@@ 123*4882a593Smuzhiyun 124*4882a593Smuzhiyunif@p1 ((E == NULL && ...) || ...) 125*4882a593Smuzhiyun{ 126*4882a593Smuzhiyun ... when != if (...) S1 else S2 127*4882a593Smuzhiyun( 128*4882a593Smuzhiyun iter(subE,...) S4 // no use 129*4882a593Smuzhiyun| 130*4882a593Smuzhiyun list_remove_head(E2,subE,...) 131*4882a593Smuzhiyun| 132*4882a593Smuzhiyun subE = E1 133*4882a593Smuzhiyun| 134*4882a593Smuzhiyun for(subE = E1;...;...) S4 135*4882a593Smuzhiyun| 136*4882a593Smuzhiyun subE++ 137*4882a593Smuzhiyun| 138*4882a593Smuzhiyun ++subE 139*4882a593Smuzhiyun| 140*4882a593Smuzhiyun --subE 141*4882a593Smuzhiyun| 142*4882a593Smuzhiyun subE-- 143*4882a593Smuzhiyun| 144*4882a593Smuzhiyun &subE 145*4882a593Smuzhiyun| 146*4882a593Smuzhiyun E->f@p // bad use 147*4882a593Smuzhiyun) 148*4882a593Smuzhiyun ... when any 149*4882a593Smuzhiyun} 150*4882a593Smuzhiyunelse S3 151*4882a593Smuzhiyun 152*4882a593Smuzhiyun@script:python depends on !context && !org && report@ 153*4882a593Smuzhiyunp << s.p; 154*4882a593Smuzhiyunp1 << ifm.p1; 155*4882a593Smuzhiyunx << ifm.E; 156*4882a593Smuzhiyun@@ 157*4882a593Smuzhiyun 158*4882a593Smuzhiyunmsg="ERROR: %s is NULL but dereferenced." % (x) 159*4882a593Smuzhiyuncoccilib.report.print_report(p[0], msg) 160*4882a593Smuzhiyun 161*4882a593Smuzhiyun@script:python depends on !context && org && !report@ 162*4882a593Smuzhiyunp << s.p; 163*4882a593Smuzhiyunp1 << ifm.p1; 164*4882a593Smuzhiyunx << ifm.E; 165*4882a593Smuzhiyun@@ 166*4882a593Smuzhiyun 167*4882a593Smuzhiyunmsg="ERROR: %s is NULL but dereferenced." % (x) 168*4882a593Smuzhiyunmsg_safe=msg.replace("[","@(").replace("]",")") 169*4882a593Smuzhiyuncocci.print_main(msg_safe,p) 170*4882a593Smuzhiyun 171*4882a593Smuzhiyun// For context mode 172*4882a593Smuzhiyun 173*4882a593Smuzhiyun@depends on context && !org && !report exists@ 174*4882a593Smuzhiyunexpression subE <= ifm.E; 175*4882a593Smuzhiyunexpression *ifm.E; 176*4882a593Smuzhiyunexpression E1,E2; 177*4882a593Smuzhiyunidentifier f; 178*4882a593Smuzhiyunstatement S1,S2,S3,S4; 179*4882a593Smuzhiyuniterator iter; 180*4882a593Smuzhiyunposition p!={pr1.p1,pr2.p2}; 181*4882a593Smuzhiyunposition ifm.p1; 182*4882a593Smuzhiyun@@ 183*4882a593Smuzhiyun 184*4882a593Smuzhiyunif@p1 ((E == NULL && ...) || ...) 185*4882a593Smuzhiyun{ 186*4882a593Smuzhiyun ... when != if (...) S1 else S2 187*4882a593Smuzhiyun( 188*4882a593Smuzhiyun iter(subE,...) S4 // no use 189*4882a593Smuzhiyun| 190*4882a593Smuzhiyun list_remove_head(E2,subE,...) 191*4882a593Smuzhiyun| 192*4882a593Smuzhiyun subE = E1 193*4882a593Smuzhiyun| 194*4882a593Smuzhiyun for(subE = E1;...;...) S4 195*4882a593Smuzhiyun| 196*4882a593Smuzhiyun subE++ 197*4882a593Smuzhiyun| 198*4882a593Smuzhiyun ++subE 199*4882a593Smuzhiyun| 200*4882a593Smuzhiyun --subE 201*4882a593Smuzhiyun| 202*4882a593Smuzhiyun subE-- 203*4882a593Smuzhiyun| 204*4882a593Smuzhiyun &subE 205*4882a593Smuzhiyun| 206*4882a593Smuzhiyun* E->f@p // bad use 207*4882a593Smuzhiyun) 208*4882a593Smuzhiyun ... when any 209*4882a593Smuzhiyun return ...; 210*4882a593Smuzhiyun} 211*4882a593Smuzhiyunelse S3 212*4882a593Smuzhiyun 213*4882a593Smuzhiyun// The following three rules are duplicates of ifm, pr1 and pr2 respectively. 214*4882a593Smuzhiyun// It is need because the previous rule as already made a "change". 215*4882a593Smuzhiyun 216*4882a593Smuzhiyun@pr11 depends on context && !org && !report expression@ 217*4882a593Smuzhiyunexpression E; 218*4882a593Smuzhiyunidentifier f; 219*4882a593Smuzhiyunposition p1; 220*4882a593Smuzhiyun@@ 221*4882a593Smuzhiyun 222*4882a593Smuzhiyun (E != NULL && ...) ? <+...E->f@p1...+> : ... 223*4882a593Smuzhiyun 224*4882a593Smuzhiyun@pr12 depends on context && !org && !report expression@ 225*4882a593Smuzhiyunexpression E; 226*4882a593Smuzhiyunidentifier f; 227*4882a593Smuzhiyunposition p2; 228*4882a593Smuzhiyun@@ 229*4882a593Smuzhiyun 230*4882a593Smuzhiyun( 231*4882a593Smuzhiyun (E != NULL) && ... && <+...E->f@p2...+> 232*4882a593Smuzhiyun| 233*4882a593Smuzhiyun (E == NULL) || ... || <+...E->f@p2...+> 234*4882a593Smuzhiyun| 235*4882a593Smuzhiyun sizeof(<+...E->f@p2...+>) 236*4882a593Smuzhiyun) 237*4882a593Smuzhiyun 238*4882a593Smuzhiyun@ifm1 depends on context && !org && !report@ 239*4882a593Smuzhiyunexpression *E; 240*4882a593Smuzhiyunstatement S1,S2; 241*4882a593Smuzhiyunposition p1; 242*4882a593Smuzhiyun@@ 243*4882a593Smuzhiyun 244*4882a593Smuzhiyunif@p1 ((E == NULL && ...) || ...) S1 else S2 245*4882a593Smuzhiyun 246*4882a593Smuzhiyun@depends on context && !org && !report exists@ 247*4882a593Smuzhiyunexpression subE <= ifm1.E; 248*4882a593Smuzhiyunexpression *ifm1.E; 249*4882a593Smuzhiyunexpression E1,E2; 250*4882a593Smuzhiyunidentifier f; 251*4882a593Smuzhiyunstatement S1,S2,S3,S4; 252*4882a593Smuzhiyuniterator iter; 253*4882a593Smuzhiyunposition p!={pr11.p1,pr12.p2}; 254*4882a593Smuzhiyunposition ifm1.p1; 255*4882a593Smuzhiyun@@ 256*4882a593Smuzhiyun 257*4882a593Smuzhiyunif@p1 ((E == NULL && ...) || ...) 258*4882a593Smuzhiyun{ 259*4882a593Smuzhiyun ... when != if (...) S1 else S2 260*4882a593Smuzhiyun( 261*4882a593Smuzhiyun iter(subE,...) S4 // no use 262*4882a593Smuzhiyun| 263*4882a593Smuzhiyun list_remove_head(E2,subE,...) 264*4882a593Smuzhiyun| 265*4882a593Smuzhiyun subE = E1 266*4882a593Smuzhiyun| 267*4882a593Smuzhiyun for(subE = E1;...;...) S4 268*4882a593Smuzhiyun| 269*4882a593Smuzhiyun subE++ 270*4882a593Smuzhiyun| 271*4882a593Smuzhiyun ++subE 272*4882a593Smuzhiyun| 273*4882a593Smuzhiyun --subE 274*4882a593Smuzhiyun| 275*4882a593Smuzhiyun subE-- 276*4882a593Smuzhiyun| 277*4882a593Smuzhiyun &subE 278*4882a593Smuzhiyun| 279*4882a593Smuzhiyun* E->f@p // bad use 280*4882a593Smuzhiyun) 281*4882a593Smuzhiyun ... when any 282*4882a593Smuzhiyun} 283*4882a593Smuzhiyunelse S3 284