162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only
262306a36Sopenharmony_ci///
362306a36Sopenharmony_ci/// Use kfree_sensitive, kvfree_sensitive rather than memset or
462306a36Sopenharmony_ci/// memzero_explicit followed by kfree.
562306a36Sopenharmony_ci///
662306a36Sopenharmony_ci// Confidence: High
762306a36Sopenharmony_ci// Copyright: (C) 2020 Denis Efremov ISPRAS
862306a36Sopenharmony_ci// Options: --no-includes --include-headers
962306a36Sopenharmony_ci//
1062306a36Sopenharmony_ci// Keywords: kfree_sensitive, kvfree_sensitive
1162306a36Sopenharmony_ci//
1262306a36Sopenharmony_ci
1362306a36Sopenharmony_civirtual context
1462306a36Sopenharmony_civirtual patch
1562306a36Sopenharmony_civirtual org
1662306a36Sopenharmony_civirtual report
1762306a36Sopenharmony_ci
1862306a36Sopenharmony_ci@initialize:python@
1962306a36Sopenharmony_ci@@
2062306a36Sopenharmony_ci# kmalloc_oob_in_memset uses memset to explicitly trigger out-of-bounds access
2162306a36Sopenharmony_cifilter = frozenset(['kmalloc_oob_in_memset',
2262306a36Sopenharmony_ci		    'kfree_sensitive', 'kvfree_sensitive'])
2362306a36Sopenharmony_ci
2462306a36Sopenharmony_cidef relevant(p):
2562306a36Sopenharmony_ci    return not (filter & {el.current_element for el in p})
2662306a36Sopenharmony_ci
2762306a36Sopenharmony_ci@cond@
2862306a36Sopenharmony_ciposition ok;
2962306a36Sopenharmony_ci@@
3062306a36Sopenharmony_ci
3162306a36Sopenharmony_ciif (...)
3262306a36Sopenharmony_ci  \(memset@ok\|memzero_explicit@ok\)(...);
3362306a36Sopenharmony_ci
3462306a36Sopenharmony_ci@r depends on !patch forall@
3562306a36Sopenharmony_ciexpression E;
3662306a36Sopenharmony_ciposition p : script:python() { relevant(p) };
3762306a36Sopenharmony_ciposition m != cond.ok;
3862306a36Sopenharmony_citype T;
3962306a36Sopenharmony_ci@@
4062306a36Sopenharmony_ci
4162306a36Sopenharmony_ci(
4262306a36Sopenharmony_ci* memset@m((T)E, 0, ...);
4362306a36Sopenharmony_ci|
4462306a36Sopenharmony_ci* memzero_explicit@m((T)E, ...);
4562306a36Sopenharmony_ci)
4662306a36Sopenharmony_ci  ... when != E
4762306a36Sopenharmony_ci      when strict
4862306a36Sopenharmony_ci* \(kfree\|vfree\|kvfree\)(E)@p;
4962306a36Sopenharmony_ci
5062306a36Sopenharmony_ci@rp_memzero depends on patch@
5162306a36Sopenharmony_ciexpression E, size;
5262306a36Sopenharmony_ciposition p : script:python() { relevant(p) };
5362306a36Sopenharmony_ciposition m != cond.ok;
5462306a36Sopenharmony_citype T;
5562306a36Sopenharmony_ci@@
5662306a36Sopenharmony_ci
5762306a36Sopenharmony_ci- memzero_explicit@m((T)E, size);
5862306a36Sopenharmony_ci  ... when != E
5962306a36Sopenharmony_ci      when strict
6062306a36Sopenharmony_ci(
6162306a36Sopenharmony_ci- kfree(E)@p;
6262306a36Sopenharmony_ci+ kfree_sensitive(E);
6362306a36Sopenharmony_ci|
6462306a36Sopenharmony_ci- \(vfree\|kvfree\)(E)@p;
6562306a36Sopenharmony_ci+ kvfree_sensitive(E, size);
6662306a36Sopenharmony_ci)
6762306a36Sopenharmony_ci
6862306a36Sopenharmony_ci@rp_memset depends on patch@
6962306a36Sopenharmony_ciexpression E, size;
7062306a36Sopenharmony_ciposition p : script:python() { relevant(p) };
7162306a36Sopenharmony_ciposition m != cond.ok;
7262306a36Sopenharmony_citype T;
7362306a36Sopenharmony_ci@@
7462306a36Sopenharmony_ci
7562306a36Sopenharmony_ci- memset@m((T)E, 0, size);
7662306a36Sopenharmony_ci  ... when != E
7762306a36Sopenharmony_ci      when strict
7862306a36Sopenharmony_ci(
7962306a36Sopenharmony_ci- kfree(E)@p;
8062306a36Sopenharmony_ci+ kfree_sensitive(E);
8162306a36Sopenharmony_ci|
8262306a36Sopenharmony_ci- \(vfree\|kvfree\)(E)@p;
8362306a36Sopenharmony_ci+ kvfree_sensitive(E, size);
8462306a36Sopenharmony_ci)
8562306a36Sopenharmony_ci
8662306a36Sopenharmony_ci@script:python depends on report@
8762306a36Sopenharmony_cip << r.p;
8862306a36Sopenharmony_cim << r.m;
8962306a36Sopenharmony_ci@@
9062306a36Sopenharmony_ci
9162306a36Sopenharmony_cimsg = "WARNING opportunity for kfree_sensitive/kvfree_sensitive (memset at line %s)"
9262306a36Sopenharmony_cicoccilib.report.print_report(p[0], msg % (m[0].line))
9362306a36Sopenharmony_ci
9462306a36Sopenharmony_ci@script:python depends on org@
9562306a36Sopenharmony_cip << r.p;
9662306a36Sopenharmony_cim << r.m;
9762306a36Sopenharmony_ci@@
9862306a36Sopenharmony_ci
9962306a36Sopenharmony_cimsg = "WARNING opportunity for kfree_sensitive/kvfree_sensitive (memset at line %s)"
10062306a36Sopenharmony_cicoccilib.org.print_todo(p[0], msg % (m[0].line))
101