144d8870fSDenis Efremov// SPDX-License-Identifier: GPL-2.0-only 244d8870fSDenis Efremov/// 344d8870fSDenis Efremov/// Find if/else condition with kmalloc/vmalloc calls. 444d8870fSDenis Efremov/// Suggest to use kvmalloc instead. Same for kvfree. 544d8870fSDenis Efremov/// 644d8870fSDenis Efremov// Confidence: High 744d8870fSDenis Efremov// Copyright: (C) 2020 Denis Efremov ISPRAS 844d8870fSDenis Efremov// Options: --no-includes --include-headers 944d8870fSDenis Efremov// 1044d8870fSDenis Efremov 1144d8870fSDenis Efremovvirtual patch 1244d8870fSDenis Efremovvirtual report 1344d8870fSDenis Efremovvirtual org 1444d8870fSDenis Efremovvirtual context 1544d8870fSDenis Efremov 1644d8870fSDenis Efremov@initialize:python@ 1744d8870fSDenis Efremov@@ 1844d8870fSDenis Efremovfilter = frozenset(['kvfree']) 1944d8870fSDenis Efremov 2044d8870fSDenis Efremovdef relevant(p): 2144d8870fSDenis Efremov return not (filter & {el.current_element for el in p}) 2244d8870fSDenis Efremov 2344d8870fSDenis Efremov@kvmalloc depends on !patch@ 2444d8870fSDenis Efremovexpression E, E1, size; 2544d8870fSDenis Efremovidentifier flags; 2644d8870fSDenis Efremovbinary operator cmp = {<=, <, ==, >, >=}; 2744d8870fSDenis Efremovidentifier x; 2844d8870fSDenis Efremovtype T; 2944d8870fSDenis Efremovposition p; 3044d8870fSDenis Efremov@@ 3144d8870fSDenis Efremov 3244d8870fSDenis Efremov( 3344d8870fSDenis Efremov* if (size cmp E1 || ...)@p { 3444d8870fSDenis Efremov ... 3544d8870fSDenis Efremov* E = \(kmalloc\|kzalloc\|kcalloc\|kmalloc_node\|kzalloc_node\| 3644d8870fSDenis Efremov* kmalloc_array\|kmalloc_array_node\|kcalloc_node\) 3744d8870fSDenis Efremov* (..., size, \(flags\|GFP_KERNEL\|\(GFP_KERNEL\|flags\)|__GFP_NOWARN\), ...) 3844d8870fSDenis Efremov ... 3944d8870fSDenis Efremov } else { 4044d8870fSDenis Efremov ... 4144d8870fSDenis Efremov* E = \(vmalloc\|vzalloc\|vmalloc_node\|vzalloc_node\)(..., size, ...) 4244d8870fSDenis Efremov ... 4344d8870fSDenis Efremov } 4444d8870fSDenis Efremov| 4544d8870fSDenis Efremov* E = \(kmalloc\|kzalloc\|kcalloc\|kmalloc_node\|kzalloc_node\| 4644d8870fSDenis Efremov* kmalloc_array\|kmalloc_array_node\|kcalloc_node\) 4744d8870fSDenis Efremov* (..., size, \(flags\|GFP_KERNEL\|\(GFP_KERNEL\|flags\)|__GFP_NOWARN\), ...) 4844d8870fSDenis Efremov ... when != E = E1 4944d8870fSDenis Efremov when != size = E1 5044d8870fSDenis Efremov when any 5144d8870fSDenis Efremov* if (E == NULL)@p { 5244d8870fSDenis Efremov ... 5344d8870fSDenis Efremov* E = \(vmalloc\|vzalloc\|vmalloc_node\|vzalloc_node\)(..., size, ...) 5444d8870fSDenis Efremov ... 5544d8870fSDenis Efremov } 5644d8870fSDenis Efremov| 5744d8870fSDenis Efremov* T x = \(kmalloc\|kzalloc\|kcalloc\|kmalloc_node\|kzalloc_node\| 5844d8870fSDenis Efremov* kmalloc_array\|kmalloc_array_node\|kcalloc_node\) 5944d8870fSDenis Efremov* (..., size, \(flags\|GFP_KERNEL\|\(GFP_KERNEL\|flags\)|__GFP_NOWARN\), ...); 6044d8870fSDenis Efremov ... when != x = E1 6144d8870fSDenis Efremov when != size = E1 6244d8870fSDenis Efremov when any 6344d8870fSDenis Efremov* if (x == NULL)@p { 6444d8870fSDenis Efremov ... 6544d8870fSDenis Efremov* x = \(vmalloc\|vzalloc\|vmalloc_node\|vzalloc_node\)(..., size, ...) 6644d8870fSDenis Efremov ... 6744d8870fSDenis Efremov } 6844d8870fSDenis Efremov) 6944d8870fSDenis Efremov 7044d8870fSDenis Efremov@kvfree depends on !patch@ 7144d8870fSDenis Efremovexpression E; 7244d8870fSDenis Efremovposition p : script:python() { relevant(p) }; 7344d8870fSDenis Efremov@@ 7444d8870fSDenis Efremov 7544d8870fSDenis Efremov* if (is_vmalloc_addr(E))@p { 7644d8870fSDenis Efremov ... 7744d8870fSDenis Efremov* vfree(E) 7844d8870fSDenis Efremov ... 7944d8870fSDenis Efremov } else { 8044d8870fSDenis Efremov ... when != krealloc(E, ...) 8144d8870fSDenis Efremov when any 82*9eec0792SWeizhao Ouyang* \(kfree\|kfree_sensitive\)(E) 8344d8870fSDenis Efremov ... 8444d8870fSDenis Efremov } 8544d8870fSDenis Efremov 8644d8870fSDenis Efremov@depends on patch@ 8744d8870fSDenis Efremovexpression E, E1, size, node; 8844d8870fSDenis Efremovbinary operator cmp = {<=, <, ==, >, >=}; 8944d8870fSDenis Efremovidentifier flags, x; 9044d8870fSDenis Efremovtype T; 9144d8870fSDenis Efremov@@ 9244d8870fSDenis Efremov 9344d8870fSDenis Efremov( 9444d8870fSDenis Efremov- if (size cmp E1) 9544d8870fSDenis Efremov- E = kmalloc(size, flags); 9644d8870fSDenis Efremov- else 9744d8870fSDenis Efremov- E = vmalloc(size); 9844d8870fSDenis Efremov+ E = kvmalloc(size, flags); 9944d8870fSDenis Efremov| 10044d8870fSDenis Efremov- if (size cmp E1) 10144d8870fSDenis Efremov- E = kmalloc(size, \(GFP_KERNEL\|GFP_KERNEL|__GFP_NOWARN\)); 10244d8870fSDenis Efremov- else 10344d8870fSDenis Efremov- E = vmalloc(size); 10444d8870fSDenis Efremov+ E = kvmalloc(size, GFP_KERNEL); 10544d8870fSDenis Efremov| 10644d8870fSDenis Efremov- E = kmalloc(size, flags | __GFP_NOWARN); 10744d8870fSDenis Efremov- if (E == NULL) 10844d8870fSDenis Efremov- E = vmalloc(size); 10944d8870fSDenis Efremov+ E = kvmalloc(size, flags); 11044d8870fSDenis Efremov| 11144d8870fSDenis Efremov- E = kmalloc(size, \(GFP_KERNEL\|GFP_KERNEL|__GFP_NOWARN\)); 11244d8870fSDenis Efremov- if (E == NULL) 11344d8870fSDenis Efremov- E = vmalloc(size); 11444d8870fSDenis Efremov+ E = kvmalloc(size, GFP_KERNEL); 11544d8870fSDenis Efremov| 11644d8870fSDenis Efremov- T x = kmalloc(size, flags | __GFP_NOWARN); 11744d8870fSDenis Efremov- if (x == NULL) 11844d8870fSDenis Efremov- x = vmalloc(size); 11944d8870fSDenis Efremov+ T x = kvmalloc(size, flags); 12044d8870fSDenis Efremov| 12144d8870fSDenis Efremov- T x = kmalloc(size, \(GFP_KERNEL\|GFP_KERNEL|__GFP_NOWARN\)); 12244d8870fSDenis Efremov- if (x == NULL) 12344d8870fSDenis Efremov- x = vmalloc(size); 12444d8870fSDenis Efremov+ T x = kvmalloc(size, GFP_KERNEL); 12544d8870fSDenis Efremov| 12644d8870fSDenis Efremov- if (size cmp E1) 12744d8870fSDenis Efremov- E = kzalloc(size, flags); 12844d8870fSDenis Efremov- else 12944d8870fSDenis Efremov- E = vzalloc(size); 13044d8870fSDenis Efremov+ E = kvzalloc(size, flags); 13144d8870fSDenis Efremov| 13244d8870fSDenis Efremov- if (size cmp E1) 13344d8870fSDenis Efremov- E = kzalloc(size, \(GFP_KERNEL\|GFP_KERNEL|__GFP_NOWARN\)); 13444d8870fSDenis Efremov- else 13544d8870fSDenis Efremov- E = vzalloc(size); 13644d8870fSDenis Efremov+ E = kvzalloc(size, GFP_KERNEL); 13744d8870fSDenis Efremov| 13844d8870fSDenis Efremov- E = kzalloc(size, flags | __GFP_NOWARN); 13944d8870fSDenis Efremov- if (E == NULL) 14044d8870fSDenis Efremov- E = vzalloc(size); 14144d8870fSDenis Efremov+ E = kvzalloc(size, flags); 14244d8870fSDenis Efremov| 14344d8870fSDenis Efremov- E = kzalloc(size, \(GFP_KERNEL\|GFP_KERNEL|__GFP_NOWARN\)); 14444d8870fSDenis Efremov- if (E == NULL) 14544d8870fSDenis Efremov- E = vzalloc(size); 14644d8870fSDenis Efremov+ E = kvzalloc(size, GFP_KERNEL); 14744d8870fSDenis Efremov| 14844d8870fSDenis Efremov- T x = kzalloc(size, flags | __GFP_NOWARN); 14944d8870fSDenis Efremov- if (x == NULL) 15044d8870fSDenis Efremov- x = vzalloc(size); 15144d8870fSDenis Efremov+ T x = kvzalloc(size, flags); 15244d8870fSDenis Efremov| 15344d8870fSDenis Efremov- T x = kzalloc(size, \(GFP_KERNEL\|GFP_KERNEL|__GFP_NOWARN\)); 15444d8870fSDenis Efremov- if (x == NULL) 15544d8870fSDenis Efremov- x = vzalloc(size); 15644d8870fSDenis Efremov+ T x = kvzalloc(size, GFP_KERNEL); 15744d8870fSDenis Efremov| 15844d8870fSDenis Efremov- if (size cmp E1) 15944d8870fSDenis Efremov- E = kmalloc_node(size, flags, node); 16044d8870fSDenis Efremov- else 16144d8870fSDenis Efremov- E = vmalloc_node(size, node); 16244d8870fSDenis Efremov+ E = kvmalloc_node(size, flags, node); 16344d8870fSDenis Efremov| 16444d8870fSDenis Efremov- if (size cmp E1) 16544d8870fSDenis Efremov- E = kmalloc_node(size, \(GFP_KERNEL\|GFP_KERNEL|__GFP_NOWARN\), node); 16644d8870fSDenis Efremov- else 16744d8870fSDenis Efremov- E = vmalloc_node(size, node); 16844d8870fSDenis Efremov+ E = kvmalloc_node(size, GFP_KERNEL, node); 16944d8870fSDenis Efremov| 17044d8870fSDenis Efremov- E = kmalloc_node(size, flags | __GFP_NOWARN, node); 17144d8870fSDenis Efremov- if (E == NULL) 17244d8870fSDenis Efremov- E = vmalloc_node(size, node); 17344d8870fSDenis Efremov+ E = kvmalloc_node(size, flags, node); 17444d8870fSDenis Efremov| 17544d8870fSDenis Efremov- E = kmalloc_node(size, \(GFP_KERNEL\|GFP_KERNEL|__GFP_NOWARN\), node); 17644d8870fSDenis Efremov- if (E == NULL) 17744d8870fSDenis Efremov- E = vmalloc_node(size, node); 17844d8870fSDenis Efremov+ E = kvmalloc_node(size, GFP_KERNEL, node); 17944d8870fSDenis Efremov| 18044d8870fSDenis Efremov- T x = kmalloc_node(size, flags | __GFP_NOWARN, node); 18144d8870fSDenis Efremov- if (x == NULL) 18244d8870fSDenis Efremov- x = vmalloc_node(size, node); 18344d8870fSDenis Efremov+ T x = kvmalloc_node(size, flags, node); 18444d8870fSDenis Efremov| 18544d8870fSDenis Efremov- T x = kmalloc_node(size, \(GFP_KERNEL\|GFP_KERNEL|__GFP_NOWARN\), node); 18644d8870fSDenis Efremov- if (x == NULL) 18744d8870fSDenis Efremov- x = vmalloc_node(size, node); 18844d8870fSDenis Efremov+ T x = kvmalloc_node(size, GFP_KERNEL, node); 18944d8870fSDenis Efremov| 19044d8870fSDenis Efremov- if (size cmp E1) 19144d8870fSDenis Efremov- E = kvzalloc_node(size, flags, node); 19244d8870fSDenis Efremov- else 19344d8870fSDenis Efremov- E = vzalloc_node(size, node); 19444d8870fSDenis Efremov+ E = kvzalloc_node(size, flags, node); 19544d8870fSDenis Efremov| 19644d8870fSDenis Efremov- if (size cmp E1) 19744d8870fSDenis Efremov- E = kvzalloc_node(size, \(GFP_KERNEL\|GFP_KERNEL|__GFP_NOWARN\), node); 19844d8870fSDenis Efremov- else 19944d8870fSDenis Efremov- E = vzalloc_node(size, node); 20044d8870fSDenis Efremov+ E = kvzalloc_node(size, GFP_KERNEL, node); 20144d8870fSDenis Efremov| 20244d8870fSDenis Efremov- E = kvzalloc_node(size, flags | __GFP_NOWARN, node); 20344d8870fSDenis Efremov- if (E == NULL) 20444d8870fSDenis Efremov- E = vzalloc_node(size, node); 20544d8870fSDenis Efremov+ E = kvzalloc_node(size, flags, node); 20644d8870fSDenis Efremov| 20744d8870fSDenis Efremov- E = kvzalloc_node(size, \(GFP_KERNEL\|GFP_KERNEL|__GFP_NOWARN\), node); 20844d8870fSDenis Efremov- if (E == NULL) 20944d8870fSDenis Efremov- E = vzalloc_node(size, node); 21044d8870fSDenis Efremov+ E = kvzalloc_node(size, GFP_KERNEL, node); 21144d8870fSDenis Efremov| 21244d8870fSDenis Efremov- T x = kvzalloc_node(size, flags | __GFP_NOWARN, node); 21344d8870fSDenis Efremov- if (x == NULL) 21444d8870fSDenis Efremov- x = vzalloc_node(size, node); 21544d8870fSDenis Efremov+ T x = kvzalloc_node(size, flags, node); 21644d8870fSDenis Efremov| 21744d8870fSDenis Efremov- T x = kvzalloc_node(size, \(GFP_KERNEL\|GFP_KERNEL|__GFP_NOWARN\), node); 21844d8870fSDenis Efremov- if (x == NULL) 21944d8870fSDenis Efremov- x = vzalloc_node(size, node); 22044d8870fSDenis Efremov+ T x = kvzalloc_node(size, GFP_KERNEL, node); 22144d8870fSDenis Efremov) 22244d8870fSDenis Efremov 22344d8870fSDenis Efremov@depends on patch@ 22444d8870fSDenis Efremovexpression E; 22544d8870fSDenis Efremovposition p : script:python() { relevant(p) }; 22644d8870fSDenis Efremov@@ 22744d8870fSDenis Efremov 22844d8870fSDenis Efremov- if (is_vmalloc_addr(E))@p 22944d8870fSDenis Efremov- vfree(E); 23044d8870fSDenis Efremov- else 23144d8870fSDenis Efremov- kfree(E); 23244d8870fSDenis Efremov+ kvfree(E); 23344d8870fSDenis Efremov 23444d8870fSDenis Efremov@script: python depends on report@ 23544d8870fSDenis Efremovp << kvmalloc.p; 23644d8870fSDenis Efremov@@ 23744d8870fSDenis Efremov 23844d8870fSDenis Efremovcoccilib.report.print_report(p[0], "WARNING opportunity for kvmalloc") 23944d8870fSDenis Efremov 24044d8870fSDenis Efremov@script: python depends on org@ 24144d8870fSDenis Efremovp << kvmalloc.p; 24244d8870fSDenis Efremov@@ 24344d8870fSDenis Efremov 24444d8870fSDenis Efremovcoccilib.org.print_todo(p[0], "WARNING opportunity for kvmalloc") 24544d8870fSDenis Efremov 24644d8870fSDenis Efremov@script: python depends on report@ 24744d8870fSDenis Efremovp << kvfree.p; 24844d8870fSDenis Efremov@@ 24944d8870fSDenis Efremov 25044d8870fSDenis Efremovcoccilib.report.print_report(p[0], "WARNING opportunity for kvfree") 25144d8870fSDenis Efremov 25244d8870fSDenis Efremov@script: python depends on org@ 25344d8870fSDenis Efremovp << kvfree.p; 25444d8870fSDenis Efremov@@ 25544d8870fSDenis Efremov 25644d8870fSDenis Efremovcoccilib.org.print_todo(p[0], "WARNING opportunity for kvfree") 257