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 11virtual patch 12virtual report 13virtual org 14virtual context 15 16@initialize:python@ 17@@ 18filter = frozenset(['kvfree']) 19 20def relevant(p): 21 return not (filter & {el.current_element for el in p}) 22 23@kvmalloc depends on !patch@ 24expression E, E1, size; 25identifier flags; 26binary operator cmp = {<=, <, ==, >, >=}; 27identifier x; 28type T; 29position 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@ 71expression E; 72position 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@ 87expression E, E1, size, node; 88binary operator cmp = {<=, <, ==, >, >=}; 89identifier flags, x; 90type 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@ 224expression E; 225position 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@ 235p << kvmalloc.p; 236@@ 237 238coccilib.report.print_report(p[0], "WARNING opportunity for kvmalloc") 239 240@script: python depends on org@ 241p << kvmalloc.p; 242@@ 243 244coccilib.org.print_todo(p[0], "WARNING opportunity for kvmalloc") 245 246@script: python depends on report@ 247p << kvfree.p; 248@@ 249 250coccilib.report.print_report(p[0], "WARNING opportunity for kvfree") 251 252@script: python depends on org@ 253p << kvfree.p; 254@@ 255 256coccilib.org.print_todo(p[0], "WARNING opportunity for kvfree") 257