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