kvmalloc.cocci 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. ///
  3. /// Find if/else condition with kmalloc/vmalloc calls.
  4. /// Suggest to use kvmalloc instead. Same for kvfree.
  5. ///
  6. // Confidence: High
  7. // Copyright: (C) 2020 Denis Efremov ISPRAS
  8. // Options: --no-includes --include-headers
  9. //
  10. virtual patch
  11. virtual report
  12. virtual org
  13. virtual context
  14. @initialize:python@
  15. @@
  16. filter = frozenset(['kvfree'])
  17. def relevant(p):
  18. return not (filter & {el.current_element for el in p})
  19. @kvmalloc depends on !patch@
  20. expression E, E1, size;
  21. identifier flags;
  22. binary operator cmp = {<=, <, ==, >, >=};
  23. identifier x;
  24. type T;
  25. position p;
  26. @@
  27. (
  28. * if (size cmp E1 || ...)@p {
  29. ...
  30. * E = \(kmalloc\|kzalloc\|kcalloc\|kmalloc_node\|kzalloc_node\|
  31. * kmalloc_array\|kmalloc_array_node\|kcalloc_node\)
  32. * (..., size, \(flags\|GFP_KERNEL\|\(GFP_KERNEL\|flags\)|__GFP_NOWARN\), ...)
  33. ...
  34. } else {
  35. ...
  36. * E = \(vmalloc\|vzalloc\|vmalloc_node\|vzalloc_node\)(..., size, ...)
  37. ...
  38. }
  39. |
  40. * E = \(kmalloc\|kzalloc\|kcalloc\|kmalloc_node\|kzalloc_node\|
  41. * kmalloc_array\|kmalloc_array_node\|kcalloc_node\)
  42. * (..., size, \(flags\|GFP_KERNEL\|\(GFP_KERNEL\|flags\)|__GFP_NOWARN\), ...)
  43. ... when != E = E1
  44. when != size = E1
  45. when any
  46. * if (E == NULL)@p {
  47. ...
  48. * E = \(vmalloc\|vzalloc\|vmalloc_node\|vzalloc_node\)(..., size, ...)
  49. ...
  50. }
  51. |
  52. * T x = \(kmalloc\|kzalloc\|kcalloc\|kmalloc_node\|kzalloc_node\|
  53. * kmalloc_array\|kmalloc_array_node\|kcalloc_node\)
  54. * (..., size, \(flags\|GFP_KERNEL\|\(GFP_KERNEL\|flags\)|__GFP_NOWARN\), ...);
  55. ... when != x = E1
  56. when != size = E1
  57. when any
  58. * if (x == NULL)@p {
  59. ...
  60. * x = \(vmalloc\|vzalloc\|vmalloc_node\|vzalloc_node\)(..., size, ...)
  61. ...
  62. }
  63. )
  64. @kvfree depends on !patch@
  65. expression E;
  66. position p : script:python() { relevant(p) };
  67. @@
  68. * if (is_vmalloc_addr(E))@p {
  69. ...
  70. * vfree(E)
  71. ...
  72. } else {
  73. ... when != krealloc(E, ...)
  74. when any
  75. * \(kfree\|kfree_sensitive\)(E)
  76. ...
  77. }
  78. @depends on patch@
  79. expression E, E1, size, node;
  80. binary operator cmp = {<=, <, ==, >, >=};
  81. identifier flags, x;
  82. type T;
  83. @@
  84. (
  85. - if (size cmp E1)
  86. - E = kmalloc(size, flags);
  87. - else
  88. - E = vmalloc(size);
  89. + E = kvmalloc(size, flags);
  90. |
  91. - if (size cmp E1)
  92. - E = kmalloc(size, \(GFP_KERNEL\|GFP_KERNEL|__GFP_NOWARN\));
  93. - else
  94. - E = vmalloc(size);
  95. + E = kvmalloc(size, GFP_KERNEL);
  96. |
  97. - E = kmalloc(size, flags | __GFP_NOWARN);
  98. - if (E == NULL)
  99. - E = vmalloc(size);
  100. + E = kvmalloc(size, flags);
  101. |
  102. - E = kmalloc(size, \(GFP_KERNEL\|GFP_KERNEL|__GFP_NOWARN\));
  103. - if (E == NULL)
  104. - E = vmalloc(size);
  105. + E = kvmalloc(size, GFP_KERNEL);
  106. |
  107. - T x = kmalloc(size, flags | __GFP_NOWARN);
  108. - if (x == NULL)
  109. - x = vmalloc(size);
  110. + T x = kvmalloc(size, flags);
  111. |
  112. - T x = kmalloc(size, \(GFP_KERNEL\|GFP_KERNEL|__GFP_NOWARN\));
  113. - if (x == NULL)
  114. - x = vmalloc(size);
  115. + T x = kvmalloc(size, GFP_KERNEL);
  116. |
  117. - if (size cmp E1)
  118. - E = kzalloc(size, flags);
  119. - else
  120. - E = vzalloc(size);
  121. + E = kvzalloc(size, flags);
  122. |
  123. - if (size cmp E1)
  124. - E = kzalloc(size, \(GFP_KERNEL\|GFP_KERNEL|__GFP_NOWARN\));
  125. - else
  126. - E = vzalloc(size);
  127. + E = kvzalloc(size, GFP_KERNEL);
  128. |
  129. - E = kzalloc(size, flags | __GFP_NOWARN);
  130. - if (E == NULL)
  131. - E = vzalloc(size);
  132. + E = kvzalloc(size, flags);
  133. |
  134. - E = kzalloc(size, \(GFP_KERNEL\|GFP_KERNEL|__GFP_NOWARN\));
  135. - if (E == NULL)
  136. - E = vzalloc(size);
  137. + E = kvzalloc(size, GFP_KERNEL);
  138. |
  139. - T x = kzalloc(size, flags | __GFP_NOWARN);
  140. - if (x == NULL)
  141. - x = vzalloc(size);
  142. + T x = kvzalloc(size, flags);
  143. |
  144. - T x = kzalloc(size, \(GFP_KERNEL\|GFP_KERNEL|__GFP_NOWARN\));
  145. - if (x == NULL)
  146. - x = vzalloc(size);
  147. + T x = kvzalloc(size, GFP_KERNEL);
  148. |
  149. - if (size cmp E1)
  150. - E = kmalloc_node(size, flags, node);
  151. - else
  152. - E = vmalloc_node(size, node);
  153. + E = kvmalloc_node(size, flags, node);
  154. |
  155. - if (size cmp E1)
  156. - E = kmalloc_node(size, \(GFP_KERNEL\|GFP_KERNEL|__GFP_NOWARN\), node);
  157. - else
  158. - E = vmalloc_node(size, node);
  159. + E = kvmalloc_node(size, GFP_KERNEL, node);
  160. |
  161. - E = kmalloc_node(size, flags | __GFP_NOWARN, node);
  162. - if (E == NULL)
  163. - E = vmalloc_node(size, node);
  164. + E = kvmalloc_node(size, flags, node);
  165. |
  166. - E = kmalloc_node(size, \(GFP_KERNEL\|GFP_KERNEL|__GFP_NOWARN\), node);
  167. - if (E == NULL)
  168. - E = vmalloc_node(size, node);
  169. + E = kvmalloc_node(size, GFP_KERNEL, node);
  170. |
  171. - T x = kmalloc_node(size, flags | __GFP_NOWARN, node);
  172. - if (x == NULL)
  173. - x = vmalloc_node(size, node);
  174. + T x = kvmalloc_node(size, flags, node);
  175. |
  176. - T x = kmalloc_node(size, \(GFP_KERNEL\|GFP_KERNEL|__GFP_NOWARN\), node);
  177. - if (x == NULL)
  178. - x = vmalloc_node(size, node);
  179. + T x = kvmalloc_node(size, GFP_KERNEL, node);
  180. |
  181. - if (size cmp E1)
  182. - E = kvzalloc_node(size, flags, node);
  183. - else
  184. - E = vzalloc_node(size, node);
  185. + E = kvzalloc_node(size, flags, node);
  186. |
  187. - if (size cmp E1)
  188. - E = kvzalloc_node(size, \(GFP_KERNEL\|GFP_KERNEL|__GFP_NOWARN\), node);
  189. - else
  190. - E = vzalloc_node(size, node);
  191. + E = kvzalloc_node(size, GFP_KERNEL, node);
  192. |
  193. - E = kvzalloc_node(size, flags | __GFP_NOWARN, node);
  194. - if (E == NULL)
  195. - E = vzalloc_node(size, node);
  196. + E = kvzalloc_node(size, flags, node);
  197. |
  198. - E = kvzalloc_node(size, \(GFP_KERNEL\|GFP_KERNEL|__GFP_NOWARN\), node);
  199. - if (E == NULL)
  200. - E = vzalloc_node(size, node);
  201. + E = kvzalloc_node(size, GFP_KERNEL, node);
  202. |
  203. - T x = kvzalloc_node(size, flags | __GFP_NOWARN, node);
  204. - if (x == NULL)
  205. - x = vzalloc_node(size, node);
  206. + T x = kvzalloc_node(size, flags, node);
  207. |
  208. - T x = kvzalloc_node(size, \(GFP_KERNEL\|GFP_KERNEL|__GFP_NOWARN\), node);
  209. - if (x == NULL)
  210. - x = vzalloc_node(size, node);
  211. + T x = kvzalloc_node(size, GFP_KERNEL, node);
  212. )
  213. @depends on patch@
  214. expression E;
  215. position p : script:python() { relevant(p) };
  216. @@
  217. - if (is_vmalloc_addr(E))@p
  218. - vfree(E);
  219. - else
  220. - kfree(E);
  221. + kvfree(E);
  222. @script: python depends on report@
  223. p << kvmalloc.p;
  224. @@
  225. coccilib.report.print_report(p[0], "WARNING opportunity for kvmalloc")
  226. @script: python depends on org@
  227. p << kvmalloc.p;
  228. @@
  229. coccilib.org.print_todo(p[0], "WARNING opportunity for kvmalloc")
  230. @script: python depends on report@
  231. p << kvfree.p;
  232. @@
  233. coccilib.report.print_report(p[0], "WARNING opportunity for kvfree")
  234. @script: python depends on org@
  235. p << kvfree.p;
  236. @@
  237. coccilib.org.print_todo(p[0], "WARNING opportunity for kvfree")