17f904d7eSThomas Gleixner// SPDX-License-Identifier: GPL-2.0-only 27703692eSNicolas Palix/// 37c2aa611SJulia Lawall/// A variable is dereferenced under a NULL test. 47c2aa611SJulia Lawall/// Even though it is known to be NULL. 57703692eSNicolas Palix/// 67703692eSNicolas Palix// Confidence: Moderate 77f904d7eSThomas Gleixner// Copyright: (C) 2010 Nicolas Palix, DIKU. 87f904d7eSThomas Gleixner// Copyright: (C) 2010 Julia Lawall, DIKU. 97f904d7eSThomas Gleixner// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. 10*f01701ceSJulia Lawall// URL: https://coccinelle.gitlabpages.inria.fr/website 117703692eSNicolas Palix// Comments: -I ... -all_includes can give more complete results 127703692eSNicolas Palix// Options: 137703692eSNicolas Palix 147703692eSNicolas Palixvirtual context 157703692eSNicolas Palixvirtual org 167703692eSNicolas Palixvirtual report 177703692eSNicolas Palix 187703692eSNicolas Palix// The following two rules are separate, because both can match a single 197703692eSNicolas Palix// expression in different ways 20a1087ef6SJulia Lawall@pr1 expression@ 2121195f8eSJulia Lawallexpression E; 227703692eSNicolas Palixidentifier f; 237703692eSNicolas Palixposition p1; 247703692eSNicolas Palix@@ 257703692eSNicolas Palix 267703692eSNicolas Palix (E != NULL && ...) ? <+...E->f@p1...+> : ... 277703692eSNicolas Palix 28a1087ef6SJulia Lawall@pr2 expression@ 2921195f8eSJulia Lawallexpression E; 307703692eSNicolas Palixidentifier f; 317703692eSNicolas Palixposition p2; 327703692eSNicolas Palix@@ 337703692eSNicolas Palix 347703692eSNicolas Palix( 357703692eSNicolas Palix (E != NULL) && ... && <+...E->f@p2...+> 367703692eSNicolas Palix| 377703692eSNicolas Palix (E == NULL) || ... || <+...E->f@p2...+> 387703692eSNicolas Palix| 397703692eSNicolas Palix sizeof(<+...E->f@p2...+>) 407703692eSNicolas Palix) 417703692eSNicolas Palix 4221195f8eSJulia Lawall@ifm@ 4321195f8eSJulia Lawallexpression *E; 4421195f8eSJulia Lawallstatement S1,S2; 4521195f8eSJulia Lawallposition p1; 4621195f8eSJulia Lawall@@ 4721195f8eSJulia Lawall 4821195f8eSJulia Lawallif@p1 ((E == NULL && ...) || ...) S1 else S2 4921195f8eSJulia Lawall 507703692eSNicolas Palix// For org and report modes 517703692eSNicolas Palix 52a1087ef6SJulia Lawall@r depends on !context && (org || report) exists@ 537703692eSNicolas Palixexpression subE <= ifm.E; 547703692eSNicolas Palixexpression *ifm.E; 557703692eSNicolas Palixexpression E1,E2; 567703692eSNicolas Palixidentifier f; 577703692eSNicolas Palixstatement S1,S2,S3,S4; 587703692eSNicolas Palixiterator iter; 597703692eSNicolas Palixposition p!={pr1.p1,pr2.p2}; 607703692eSNicolas Palixposition ifm.p1; 617703692eSNicolas Palix@@ 627703692eSNicolas Palix 637703692eSNicolas Palixif@p1 ((E == NULL && ...) || ...) 647703692eSNicolas Palix{ 657703692eSNicolas Palix ... when != if (...) S1 else S2 667703692eSNicolas Palix( 677703692eSNicolas Palix iter(subE,...) S4 // no use 687703692eSNicolas Palix| 697703692eSNicolas Palix list_remove_head(E2,subE,...) 707703692eSNicolas Palix| 717703692eSNicolas Palix subE = E1 727703692eSNicolas Palix| 737703692eSNicolas Palix for(subE = E1;...;...) S4 747703692eSNicolas Palix| 757703692eSNicolas Palix subE++ 767703692eSNicolas Palix| 777703692eSNicolas Palix ++subE 787703692eSNicolas Palix| 797703692eSNicolas Palix --subE 807703692eSNicolas Palix| 817703692eSNicolas Palix subE-- 827703692eSNicolas Palix| 837703692eSNicolas Palix &subE 847703692eSNicolas Palix| 857703692eSNicolas Palix E->f@p // bad use 867703692eSNicolas Palix) 877703692eSNicolas Palix ... when any 887703692eSNicolas Palix return ...; 897703692eSNicolas Palix} 907703692eSNicolas Palixelse S3 917703692eSNicolas Palix 92a1087ef6SJulia Lawall@script:python depends on !context && !org && report@ 937703692eSNicolas Palixp << r.p; 947703692eSNicolas Palixp1 << ifm.p1; 957703692eSNicolas Palixx << ifm.E; 967703692eSNicolas Palix@@ 977703692eSNicolas Palix 987703692eSNicolas Palixmsg="ERROR: %s is NULL but dereferenced." % (x) 997703692eSNicolas Palixcoccilib.report.print_report(p[0], msg) 1007703692eSNicolas Palixcocci.include_match(False) 1017703692eSNicolas Palix 102a1087ef6SJulia Lawall@script:python depends on !context && org && !report@ 1037703692eSNicolas Palixp << r.p; 1047703692eSNicolas Palixp1 << ifm.p1; 1057703692eSNicolas Palixx << ifm.E; 1067703692eSNicolas Palix@@ 1077703692eSNicolas Palix 1087703692eSNicolas Palixmsg="ERROR: %s is NULL but dereferenced." % (x) 1097703692eSNicolas Palixmsg_safe=msg.replace("[","@(").replace("]",")") 1107703692eSNicolas Palixcocci.print_main(msg_safe,p) 1117703692eSNicolas Palixcocci.include_match(False) 1127703692eSNicolas Palix 113a1087ef6SJulia Lawall@s depends on !context && (org || report) exists@ 1147703692eSNicolas Palixexpression subE <= ifm.E; 1157703692eSNicolas Palixexpression *ifm.E; 1167703692eSNicolas Palixexpression E1,E2; 1177703692eSNicolas Palixidentifier f; 1187703692eSNicolas Palixstatement S1,S2,S3,S4; 1197703692eSNicolas Palixiterator iter; 1207703692eSNicolas Palixposition p!={pr1.p1,pr2.p2}; 1217703692eSNicolas Palixposition ifm.p1; 1227703692eSNicolas Palix@@ 1237703692eSNicolas Palix 1247703692eSNicolas Palixif@p1 ((E == NULL && ...) || ...) 1257703692eSNicolas Palix{ 1267703692eSNicolas Palix ... when != if (...) S1 else S2 1277703692eSNicolas Palix( 1287703692eSNicolas Palix iter(subE,...) S4 // no use 1297703692eSNicolas Palix| 1307703692eSNicolas Palix list_remove_head(E2,subE,...) 1317703692eSNicolas Palix| 1327703692eSNicolas Palix subE = E1 1337703692eSNicolas Palix| 1347703692eSNicolas Palix for(subE = E1;...;...) S4 1357703692eSNicolas Palix| 1367703692eSNicolas Palix subE++ 1377703692eSNicolas Palix| 1387703692eSNicolas Palix ++subE 1397703692eSNicolas Palix| 1407703692eSNicolas Palix --subE 1417703692eSNicolas Palix| 1427703692eSNicolas Palix subE-- 1437703692eSNicolas Palix| 1447703692eSNicolas Palix &subE 1457703692eSNicolas Palix| 1467703692eSNicolas Palix E->f@p // bad use 1477703692eSNicolas Palix) 1487703692eSNicolas Palix ... when any 1497703692eSNicolas Palix} 1507703692eSNicolas Palixelse S3 1517703692eSNicolas Palix 152a1087ef6SJulia Lawall@script:python depends on !context && !org && report@ 1537703692eSNicolas Palixp << s.p; 1547703692eSNicolas Palixp1 << ifm.p1; 1557703692eSNicolas Palixx << ifm.E; 1567703692eSNicolas Palix@@ 1577703692eSNicolas Palix 1587703692eSNicolas Palixmsg="ERROR: %s is NULL but dereferenced." % (x) 1597703692eSNicolas Palixcoccilib.report.print_report(p[0], msg) 1607703692eSNicolas Palix 161a1087ef6SJulia Lawall@script:python depends on !context && org && !report@ 1627703692eSNicolas Palixp << s.p; 1637703692eSNicolas Palixp1 << ifm.p1; 1647703692eSNicolas Palixx << ifm.E; 1657703692eSNicolas Palix@@ 1667703692eSNicolas Palix 1677703692eSNicolas Palixmsg="ERROR: %s is NULL but dereferenced." % (x) 1687703692eSNicolas Palixmsg_safe=msg.replace("[","@(").replace("]",")") 1697703692eSNicolas Palixcocci.print_main(msg_safe,p) 1707703692eSNicolas Palix 1717703692eSNicolas Palix// For context mode 1727703692eSNicolas Palix 173a1087ef6SJulia Lawall@depends on context && !org && !report exists@ 1747703692eSNicolas Palixexpression subE <= ifm.E; 1757703692eSNicolas Palixexpression *ifm.E; 1767703692eSNicolas Palixexpression E1,E2; 1777703692eSNicolas Palixidentifier f; 1787703692eSNicolas Palixstatement S1,S2,S3,S4; 1797703692eSNicolas Palixiterator iter; 1807703692eSNicolas Palixposition p!={pr1.p1,pr2.p2}; 1817703692eSNicolas Palixposition ifm.p1; 1827703692eSNicolas Palix@@ 1837703692eSNicolas Palix 1847703692eSNicolas Palixif@p1 ((E == NULL && ...) || ...) 1857703692eSNicolas Palix{ 1867703692eSNicolas Palix ... when != if (...) S1 else S2 1877703692eSNicolas Palix( 1887703692eSNicolas Palix iter(subE,...) S4 // no use 1897703692eSNicolas Palix| 1907703692eSNicolas Palix list_remove_head(E2,subE,...) 1917703692eSNicolas Palix| 1927703692eSNicolas Palix subE = E1 1937703692eSNicolas Palix| 1947703692eSNicolas Palix for(subE = E1;...;...) S4 1957703692eSNicolas Palix| 1967703692eSNicolas Palix subE++ 1977703692eSNicolas Palix| 1987703692eSNicolas Palix ++subE 1997703692eSNicolas Palix| 2007703692eSNicolas Palix --subE 2017703692eSNicolas Palix| 2027703692eSNicolas Palix subE-- 2037703692eSNicolas Palix| 2047703692eSNicolas Palix &subE 2057703692eSNicolas Palix| 2067703692eSNicolas Palix* E->f@p // bad use 2077703692eSNicolas Palix) 2087703692eSNicolas Palix ... when any 2097703692eSNicolas Palix return ...; 2107703692eSNicolas Palix} 2117703692eSNicolas Palixelse S3 2127703692eSNicolas Palix 2137703692eSNicolas Palix// The following three rules are duplicates of ifm, pr1 and pr2 respectively. 2147703692eSNicolas Palix// It is need because the previous rule as already made a "change". 2157703692eSNicolas Palix 216a2b0fe74SJulia Lawall@pr11 depends on context && !org && !report expression@ 21721195f8eSJulia Lawallexpression E; 2187703692eSNicolas Palixidentifier f; 2197703692eSNicolas Palixposition p1; 2207703692eSNicolas Palix@@ 2217703692eSNicolas Palix 2227703692eSNicolas Palix (E != NULL && ...) ? <+...E->f@p1...+> : ... 2237703692eSNicolas Palix 224a2b0fe74SJulia Lawall@pr12 depends on context && !org && !report expression@ 22521195f8eSJulia Lawallexpression E; 2267703692eSNicolas Palixidentifier f; 2277703692eSNicolas Palixposition p2; 2287703692eSNicolas Palix@@ 2297703692eSNicolas Palix 2307703692eSNicolas Palix( 2317703692eSNicolas Palix (E != NULL) && ... && <+...E->f@p2...+> 2327703692eSNicolas Palix| 2337703692eSNicolas Palix (E == NULL) || ... || <+...E->f@p2...+> 2347703692eSNicolas Palix| 2357703692eSNicolas Palix sizeof(<+...E->f@p2...+>) 2367703692eSNicolas Palix) 2377703692eSNicolas Palix 23821195f8eSJulia Lawall@ifm1 depends on context && !org && !report@ 23921195f8eSJulia Lawallexpression *E; 24021195f8eSJulia Lawallstatement S1,S2; 24121195f8eSJulia Lawallposition p1; 24221195f8eSJulia Lawall@@ 24321195f8eSJulia Lawall 24421195f8eSJulia Lawallif@p1 ((E == NULL && ...) || ...) S1 else S2 24521195f8eSJulia Lawall 246a1087ef6SJulia Lawall@depends on context && !org && !report exists@ 2477703692eSNicolas Palixexpression subE <= ifm1.E; 2487703692eSNicolas Palixexpression *ifm1.E; 2497703692eSNicolas Palixexpression E1,E2; 2507703692eSNicolas Palixidentifier f; 2517703692eSNicolas Palixstatement S1,S2,S3,S4; 2527703692eSNicolas Palixiterator iter; 2537703692eSNicolas Palixposition p!={pr11.p1,pr12.p2}; 2547703692eSNicolas Palixposition ifm1.p1; 2557703692eSNicolas Palix@@ 2567703692eSNicolas Palix 2577703692eSNicolas Palixif@p1 ((E == NULL && ...) || ...) 2587703692eSNicolas Palix{ 2597703692eSNicolas Palix ... when != if (...) S1 else S2 2607703692eSNicolas Palix( 2617703692eSNicolas Palix iter(subE,...) S4 // no use 2627703692eSNicolas Palix| 2637703692eSNicolas Palix list_remove_head(E2,subE,...) 2647703692eSNicolas Palix| 2657703692eSNicolas Palix subE = E1 2667703692eSNicolas Palix| 2677703692eSNicolas Palix for(subE = E1;...;...) S4 2687703692eSNicolas Palix| 2697703692eSNicolas Palix subE++ 2707703692eSNicolas Palix| 2717703692eSNicolas Palix ++subE 2727703692eSNicolas Palix| 2737703692eSNicolas Palix --subE 2747703692eSNicolas Palix| 2757703692eSNicolas Palix subE-- 2767703692eSNicolas Palix| 2777703692eSNicolas Palix &subE 2787703692eSNicolas Palix| 2797703692eSNicolas Palix* E->f@p // bad use 2807703692eSNicolas Palix) 2817703692eSNicolas Palix ... when any 2827703692eSNicolas Palix} 2837703692eSNicolas Palixelse S3 284