From: Sebastian Andrzej Siewior Date: Thu, 4 Sep 2025 14:35:14 +0000 (+0200) Subject: mm/percpu: add a simple double-free check for per-CPU memory X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=c03a56471d4c886c511f090dc19181343c47be39;p=users%2Fjedix%2Flinux-maple.git mm/percpu: add a simple double-free check for per-CPU memory The free path clears the allocation bits in pcpu_chunk::alloc_map. A simple double free check would be to check if the bits, which are about to be cleared, are already cleared. Check if the bit is already cleared. Issue a warning and abort free in that case. Link: https://lkml.kernel.org/r/20250904143514.Yk6Ap-jy@linutronix.de Signed-off-by: Sebastian Andrzej Siewior Cc: Christoph Lameter (Ampere) Cc: Dennis Zhou Cc: Tejun Heo Signed-off-by: Andrew Morton --- diff --git a/mm/percpu.c b/mm/percpu.c index 81462ce5866e..9d3f1a8d908d 100644 --- a/mm/percpu.c +++ b/mm/percpu.c @@ -1276,7 +1276,7 @@ static int pcpu_alloc_area(struct pcpu_chunk *chunk, int alloc_bits, static int pcpu_free_area(struct pcpu_chunk *chunk, int off) { struct pcpu_block_md *chunk_md = &chunk->chunk_md; - int bit_off, bits, end, oslot, freed; + int bit_off, bits, end, oslot, freed, free_bit; lockdep_assert_held(&pcpu_lock); pcpu_stats_area_dealloc(chunk); @@ -1289,6 +1289,11 @@ static int pcpu_free_area(struct pcpu_chunk *chunk, int off) end = find_next_bit(chunk->bound_map, pcpu_chunk_map_bits(chunk), bit_off + 1); bits = end - bit_off; + + free_bit = find_next_bit(chunk->alloc_map, end, bit_off); + if (WARN(free_bit != bit_off, "Trying to free already free memory")) + return 0; + bitmap_clear(chunk->alloc_map, bit_off, bits); freed = bits * PCPU_MIN_ALLOC_SIZE;