1// SPDX-License-Identifier: GPL-2.0-only 2/// 3/// Use kfree_sensitive, kvfree_sensitive rather than memset or 4/// memzero_explicit followed by kfree. 5/// 6// Confidence: High 7// Copyright: (C) 2020 Denis Efremov ISPRAS 8// Options: --no-includes --include-headers 9// 10// Keywords: kfree_sensitive, kvfree_sensitive 11// 12 13virtual context 14virtual patch 15virtual org 16virtual report 17 18@initialize:python@ 19@@ 20# kmalloc_oob_in_memset uses memset to explicitly trigger out-of-bounds access 21filter = frozenset(['kmalloc_oob_in_memset', 22 'kfree_sensitive', 'kvfree_sensitive']) 23 24def relevant(p): 25 return not (filter & {el.current_element for el in p}) 26 27@cond@ 28position ok; 29@@ 30 31if (...) 32 \(memset@ok\|memzero_explicit@ok\)(...); 33 34@r depends on !patch forall@ 35expression E; 36position p : script:python() { relevant(p) }; 37position m != cond.ok; 38type T; 39@@ 40 41( 42* memset@m((T)E, 0, ...); 43| 44* memzero_explicit@m((T)E, ...); 45) 46 ... when != E 47 when strict 48* \(kfree\|vfree\|kvfree\)(E)@p; 49 50@rp_memzero depends on patch@ 51expression E, size; 52position p : script:python() { relevant(p) }; 53position m != cond.ok; 54type T; 55@@ 56 57- memzero_explicit@m((T)E, size); 58 ... when != E 59 when strict 60( 61- kfree(E)@p; 62+ kfree_sensitive(E); 63| 64- \(vfree\|kvfree\)(E)@p; 65+ kvfree_sensitive(E, size); 66) 67 68@rp_memset depends on patch@ 69expression E, size; 70position p : script:python() { relevant(p) }; 71position m != cond.ok; 72type T; 73@@ 74 75- memset@m((T)E, 0, size); 76 ... when != E 77 when strict 78( 79- kfree(E)@p; 80+ kfree_sensitive(E); 81| 82- \(vfree\|kvfree\)(E)@p; 83+ kvfree_sensitive(E, size); 84) 85 86@script:python depends on report@ 87p << r.p; 88m << r.m; 89@@ 90 91msg = "WARNING opportunity for kfree_sensitive/kvfree_sensitive (memset at line %s)" 92coccilib.report.print_report(p[0], msg % (m[0].line)) 93 94@script:python depends on org@ 95p << r.p; 96m << r.m; 97@@ 98 99msg = "WARNING opportunity for kfree_sensitive/kvfree_sensitive (memset at line %s)" 100coccilib.org.print_todo(p[0], msg % (m[0].line)) 101