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