Skip to content

Commit f58191b

Browse files
MrVanintel-lab-lkp
authored andcommitted
mm, slub: avoid zeroing kmalloc redzone
With commit 946fa0d ("mm/slub: extend redzone check to extra allocated kmalloc space than requested"), setting orig_size treats the wasted space (object_size - orig_size) as redzones. But (in check_object()) when orig_size is set to zero, the entire object is perceived as a redzone. To a valid allocated kmalloc space, when init_on_free=1, the wasted space and the orig_size should not be cleared to 0, otherwise there will be kernel dump: [ 0.000000] ============================================================================= [ 0.000000] BUG kmalloc-8 (Not tainted): kmalloc Redzone overwritten [ 0.000000] ----------------------------------------------------------------------------- [ 0.000000] [ 0.000000] 0xffff000010032858-0xffff00001003285f @offset=2136. First byte 0x0 instead of 0xcc [ 0.000000] FIX kmalloc-8: Restoring kmalloc Redzone 0xffff000010032858-0xffff00001003285f=0xcc [ 0.000000] Slab 0xfffffdffc0400c80 objects=36 used=23 fp=0xffff000010032a18 flags=0x3fffe0000000200(workingset|node=0|zone=0|lastcpupid=0x1ffff) [ 0.000000] Object 0xffff000010032858 @offset=2136 fp=0xffff0000100328c8 [ 0.000000] [ 0.000000] Redzone ffff000010032850: cc cc cc cc cc cc cc cc ........ [ 0.000000] Object ffff000010032858: cc cc cc cc cc cc cc cc ........ [ 0.000000] Redzone ffff000010032860: cc cc cc cc cc cc cc cc ........ [ 0.000000] Padding ffff0000100328b4: 00 00 00 00 00 00 00 00 00 00 00 00 ............ [ 0.000000] CPU: 0 UID: 0 PID: 0 Comm: swapper/0 Not tainted 6.11.0-rc3-next-20240814-00004-g61844c55c3f4 torvalds#144 [ 0.000000] Hardware name: NXP i.MX95 19X19 board (DT) [ 0.000000] Call trace: [ 0.000000] dump_backtrace+0x90/0xe8 [ 0.000000] show_stack+0x18/0x24 [ 0.000000] dump_stack_lvl+0x74/0x8c [ 0.000000] dump_stack+0x18/0x24 [ 0.000000] print_trailer+0x150/0x218 [ 0.000000] check_object+0xe4/0x454 [ 0.000000] free_to_partial_list+0x2f8/0x5ec To address the issue, use orig_size to clear the used area. And restore the value of orig_size after clear the remaining area. When CONFIG_SLUB_DEBUG not defined, (get_orig_size()' directly returns s->object_size. So when using memset to init the area, the size can simply be orig_size, as orig_size returns object_size when CONFIG_SLUB_DEBUG not enabled. And orig_size can never be bigger than object_size. Fixes: 946fa0d ("mm/slub: extend redzone check to extra allocated kmalloc space than requested") Signed-off-by: Peng Fan <[email protected]>
1 parent c79c858 commit f58191b

File tree

1 file changed

+18
-2
lines changed

1 file changed

+18
-2
lines changed

mm/slub.c

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1895,6 +1895,15 @@ static inline void inc_slabs_node(struct kmem_cache *s, int node,
18951895
static inline void dec_slabs_node(struct kmem_cache *s, int node,
18961896
int objects) {}
18971897

1898+
static inline unsigned int get_orig_size(struct kmem_cache *s, void *object)
1899+
{
1900+
return s->object_size;
1901+
}
1902+
1903+
static inline void set_orig_size(struct kmem_cache *s, void *object,
1904+
unsigned int orig_size)
1905+
{}
1906+
18981907
#ifndef CONFIG_SLUB_TINY
18991908
static bool freelist_corrupted(struct kmem_cache *s, struct slab *slab,
19001909
void **freelist, void *nextfree)
@@ -2286,14 +2295,21 @@ bool slab_free_hook(struct kmem_cache *s, void *x, bool init,
22862295
*/
22872296
if (unlikely(init)) {
22882297
int rsize;
2289-
unsigned int inuse;
2298+
unsigned int inuse, orig_size;
22902299

22912300
inuse = get_info_end(s);
2301+
orig_size = get_orig_size(s, x);
22922302
if (!kasan_has_integrated_init())
2293-
memset(kasan_reset_tag(x), 0, s->object_size);
2303+
memset(kasan_reset_tag(x), 0, orig_size);
22942304
rsize = (s->flags & SLAB_RED_ZONE) ? s->red_left_pad : 0;
22952305
memset((char *)kasan_reset_tag(x) + inuse, 0,
22962306
s->size - inuse - rsize);
2307+
/*
2308+
* Restore orig_size, otherwize kmalloc redzone overwritten
2309+
* would be reported
2310+
*/
2311+
set_orig_size(s, x, orig_size);
2312+
22972313
}
22982314
/* KASAN might put x into memory quarantine, delaying its reuse. */
22992315
return !kasan_slab_free(s, x, init, still_accessible);

0 commit comments

Comments
 (0)