[PATCH 6/9] mm: kmemleak: do not scan cpu_cache of struct kmem_cache

George Prekas
2023-01-23T17:05:22Z

The code already makes sure that kmemleak will not scan similar caches:
array_cache and alien_cache. For the cpu_cache, the code takes a
different approach using kmemleak_erase. This approach handles object
allocations but does not handle transfers to other caches and leads to
undetected leaks.

According to the comment in alloc_arraycache: [...] when such objects
are allocated or transferred to another cache the pointers are not
cleared and they could be counted as valid references during a kmemleak
scan. Therefore, kmemleak must not scan such objects.

Signed-off-by: George Prekas <george@enfabrica.net>
---
mm/slab.c | 13 +------------
1 file changed, 1 insertion(+), 12 deletions(-)

diff --git a/mm/slab.c b/mm/slab.c
index 29300fc1289a..a927e1a285d1 100644
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -1744,6 +1744,7 @@ static struct array_cache __percpu *alloc_kmem_cache_cpus(
for_each_possible_cpu(cpu) {
init_arraycache(per_cpu_ptr(cpu_cache, cpu),
entries, batchcount);
+ kmemleak_no_scan(per_cpu_ptr(cpu_cache, cpu));
}

return cpu_cache;
@@ -3023,20 +3024,8 @@ static inline void *____cache_alloc(struct kmem_cache *cachep, gfp_t flags)

STATS_INC_ALLOCMISS(cachep);
objp = cache_alloc_refill(cachep, flags);
- /*
- * the 'ac' may be updated by cache_alloc_refill(),
- * and kmemleak_erase() requires its correct value.
- */
- ac = cpu_cache_get(cachep);

out:
- /*
- * To avoid a false negative, if an object that is in one of the
- * per-CPU caches is leaked, we need to make sure kmemleak doesn't
- * treat the array pointers as a reference to the object.
- */
- if (objp)
- kmemleak_erase(&ac->entry[ac->avail]);
return objp;
}

--
2.37.1