Re: BUG: general protection fault in __free_object
From: Thomas Gleixner
Date: Mon Sep 02 2024 - 05:21:28 EST
On Wed, Aug 28 2024 at 16:27, Xingyu Li wrote:
> We found a bug in Linux 6.10 using syzkaller. It is possibly a null
> pointer dereference bug.
> The reproducer is
> https://gist.github.com/freexxxyyy/5aefd53c6567415e9fe8c76cc2ad390c
Reproducer alone is not really helpful. This needs the corresponding
kernel config, the exact kernel version and a description of the
reproduction environment (compiler, qemu command line ....)
It does not reproduce here at all.
Also if it really reproduces, then have you checked against current
mainline as well?
> RIP: 0010:hlist_add_head include/linux/list.h:1032 [inline]
> RIP: 0010:__free_object+0x903/0xaa0 lib/debugobjects.c:396
> __debug_check_no_obj_freed lib/debugobjects.c:994 [inline]
> debug_check_no_obj_freed+0x135/0x530 lib/debugobjects.c:1019
> slab_free_hook mm/slub.c:2163 [inline]
> slab_free_freelist_hook mm/slub.c:2225 [inline]
> slab_free_bulk mm/slub.c:4462 [inline]
> kmem_cache_free_bulk+0x1bf/0x360 mm/slub.c:4676
The code in question is serialized against objpool modifications with
pool_lock. So nothing can change any of the related data.
if (obj_pool_free > debug_objects_pool_size &&
obj_nr_tofree < ODEBUG_FREE_WORK_MAX) {
for (i = 0; i < ODEBUG_BATCH_SIZE; i++) {
obj = __alloc_object(&obj_pool);
hlist_add_head(&obj->node, &obj_to_free); <- fail
debug_objects_pool_size is initialized to:
ODEBUG_POOL_SIZE + num_possible_cpus() * ODEBUG_BATCH_SIZE;
=
1024 + num_possible_cpus() * 16
The minimum size is 1040, so there are at least 1040 objects in
obj_pool. The loop allocates at max 16 objects, which means
__alloc_object(&obj_pool);
is guaranteed to return an object and cannot return NULL.
So the only reason why this can result in a NULL pointer dereference is
that the obj_to_free list is corrupted. No idea how that should happen.
Maybe some proper reproducer instructions shed some light to it.
Thanks,
tglx