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