deref_null.cocci 4.4 KB

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