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