Re: [Linux Kernel Bug] KASAN: use-after-free Read in gfs2_rgrp_go_instantiate
From: Andreas Gruenbacher
Date: Tue Sep 01 2026 - 04:01:07 EST
Hello,
On Tue, Sep 1, 2026 at 9:47 AM Jiaming Zhang <r772577952@xxxxxxxxx> wrote:
> Dear Linux kernel developers and maintainers,
>
> We are writing to report an issue discovered in the GFS2 subsystem. The
> issue is reproducible on the latest version of linux (v7.3-rc1, commit
> cee9395acd8043be0644b25c34bfa86623f2b935). Below is the kernel report:
>
> gfs2: fsid=syz:syz.0: Corruption found in quota_change0file: duplicate
> identifier in slot 224440
> gfs2: fsid=syz:syz.0: found 1 quota changes
> ==================================================================
> BUG: KASAN: use-after-free in gfs2_bit_search fs/gfs2/rgrp.c:188 [inline]
> BUG: KASAN: use-after-free in gfs2_bitfit fs/gfs2/rgrp.c:249 [inline]
> BUG: KASAN: use-after-free in count_unlinked fs/gfs2/rgrp.c:1159 [inline]
> BUG: KASAN: use-after-free in gfs2_rgrp_go_instantiate+0xb0d/0x1340
> fs/gfs2/rgrp.c:1238
> Read of size 8 at addr ffff888027516000 by task syz-executor199/9470
>
> CPU: 0 UID: 0 PID: 9470 Comm: syz-executor199 Not tainted 7.3.0-rc1
> #35 PREEMPT(full)
> Hardware name: QEMU Ubuntu 24.04 PC v2 (i440FX + PIIX, arch_caps fix,
> 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
> Call Trace:
> <TASK>
> __dump_stack lib/dump_stack.c:94 [inline]
> dump_stack_lvl+0x10e/0x190 lib/dump_stack.c:120
> print_address_description mm/kasan/report.c:378 [inline]
> print_report+0x153/0x7e0 mm/kasan/report.c:482
> kasan_report+0x147/0x180 mm/kasan/report.c:595
> gfs2_bit_search fs/gfs2/rgrp.c:188 [inline]
> gfs2_bitfit fs/gfs2/rgrp.c:249 [inline]
> count_unlinked fs/gfs2/rgrp.c:1159 [inline]
> gfs2_rgrp_go_instantiate+0xb0d/0x1340 fs/gfs2/rgrp.c:1238
> gfs2_instantiate+0x168/0x220 fs/gfs2/glock.c:415
> gfs2_glock_holder_ready fs/gfs2/glock.c:1226 [inline]
> gfs2_glock_wait+0x1d4/0x2a0 fs/gfs2/glock.c:1246
> gfs2_glock_nq_init fs/gfs2/glock.h:253 [inline]
> gfs2_inplace_reserve+0xc41/0x3330 fs/gfs2/rgrp.c:2093
> do_sync+0x616/0xc60 fs/gfs2/quota.c:962
> gfs2_quota_sync+0x359/0x460 fs/gfs2/quota.c:1372
> gfs2_sync_fs+0x4c/0xb0 fs/gfs2/super.c:662
> sync_filesystem+0xf1/0x240 fs/sync.c:56
> generic_shutdown_super+0x77/0x2d0 fs/super.c:748
> kill_block_super+0x44/0xa0 fs/super.c:1918
> deactivate_locked_super+0xbc/0x110 fs/super.c:603
> cleanup_mnt+0x425/0x4c0 fs/namespace.c:1317
> task_work_run+0x1d4/0x260 kernel/task_work.c:233
> exit_task_work include/linux/task_work.h:40 [inline]
> do_exit+0x708/0x22a0 kernel/exit.c:1008
> do_group_exit+0x21c/0x2d0 kernel/exit.c:1151
> __do_sys_exit_group kernel/exit.c:1162 [inline]
> __se_sys_exit_group kernel/exit.c:1160 [inline]
> __x64_sys_exit_group+0x3f/0x40 kernel/exit.c:1160
> x64_sys_call+0x18c6/0x18d0 arch/x86/include/generated/asm/syscalls_64.h:232
> do_syscall_x64 arch/x86/entry/syscall_64.c:61 [inline]
> do_syscall_64+0x170/0x540 arch/x86/entry/syscall_64.c:84
> entry_SYSCALL_64_after_hwframe+0x77/0x7f
> RIP: 0033:0x7f5c39c96f2d
> Code: Unable to access opcode bytes at 0x7f5c39c96f03.
> RSP: 002b:00007ffc5256c978 EFLAGS: 00000206 ORIG_RAX: 00000000000000e7
> RAX: ffffffffffffffda RBX: 0000000000000001 RCX: 00007f5c39c96f2d
> RDX: 00000000000000e7 RSI: ffffffffffffffc0 RDI: 0000000000000001
> RBP: 00007ffc5256c9d0 R08: 0000000000000000 R09: 000000000003b2e1
> R10: 0000000000000000 R11: 0000000000000206 R12: 0000000000000000
> R13: 0000000000000001 R14: 0000000000000001 R15: 00007f5c39d6a600
> </TASK>
>
> The buggy address belongs to the physical page:
> page: refcount:0 mapcount:0 mapping:0000000000000000 index:0x7effc363f
> pfn:0x27516
> flags: 0xfff00000000000(node=0|zone=1|lastcpupid=0x7ff)
> raw: 00fff00000000000 ffffea00009d6108 ffffea00009d86c8 0000000000000000
> raw: 00000007effc363f 0000000000000000 00000000ffffffff 0000000000000000
> page dumped because: kasan: bad access detected
> page_owner tracks the page as freed
> page last allocated via order 0, migratetype Movable, gfp_mask
> 0x140cca(GFP_HIGHUSER_MOVABLE|__GFP_COMP), pid 9361, tgid 9361
> ((udev-worker)), ts 96351902392
> set_page_owner include/linux/page_owner.h:33 [inline]
> post_alloc_hook+0x205/0x260 mm/page_alloc.c:1871
> prep_new_page mm/page_alloc.c:1879 [inline]
> get_page_from_freelist+0x235b/0x23e0 mm/page_alloc.c:3943
> __alloc_frozen_pages_noprof+0x209/0x5a0 mm/page_alloc.c:5436
> alloc_pages_mpol+0x241/0x4a0 mm/mempolicy.c:2486
> folio_alloc_mpol_noprof+0x39/0x160 mm/mempolicy.c:2505
> vma_alloc_folio_noprof+0xdb/0x1e0 mm/mempolicy.c:2540
> folio_prealloc+0x30/0x180 mm/memory.c:-1
> wp_page_copy mm/memory.c:4007 [inline]
> do_wp_page+0x119f/0x4b00 mm/memory.c:4472
> handle_pte_fault mm/memory.c:6582 [inline]
> __handle_mm_fault mm/memory.c:6707 [inline]
> handle_mm_fault+0x15a7/0x36d0 mm/memory.c:6876
> do_user_addr_fault+0xa7e/0x1360 arch/x86/mm/fault.c:1343
> handle_page_fault arch/x86/mm/fault.c:1483 [inline]
> exc_page_fault+0x71/0xd0 arch/x86/mm/fault.c:1536
> asm_exc_page_fault+0x26/0x30 arch/x86/include/asm/idtentry.h:595
> page last free pid 9361 tgid 9361 ts 103418286503 stack trace:
> reset_page_owner include/linux/page_owner.h:26 [inline]
> __free_pages_prepare mm/page_alloc.c:1418 [inline]
> free_unref_folios+0xd80/0x14c0 mm/page_alloc.c:3022
> folios_put_refs+0x7b4/0x8a0 mm/folio.c:1034
> free_pages_and_swap_cache+0x25e/0x440 mm/swap_state.c:592
> __tlb_batch_free_encoded_pages mm/mmu_gather.c:138 [inline]
> tlb_batch_pages_flush mm/mmu_gather.c:151 [inline]
> tlb_flush_mmu_free mm/mmu_gather.c:417 [inline]
> tlb_flush_mmu+0x3a2/0x680 mm/mmu_gather.c:424
> tlb_finish_mmu+0xf9/0x230 mm/mmu_gather.c:549
> exit_mmap+0x473/0x9c0 mm/mmap.c:1328
> __mmput+0x118/0x430 kernel/fork.c:1193
> exit_mm+0x214/0x2e0 kernel/exit.c:614
> do_exit+0x69b/0x22a0 kernel/exit.c:996
> do_group_exit+0x21c/0x2d0 kernel/exit.c:1151
> __do_sys_exit_group kernel/exit.c:1162 [inline]
> __se_sys_exit_group kernel/exit.c:1160 [inline]
> __x64_sys_exit_group+0x3f/0x40 kernel/exit.c:1160
> x64_sys_call+0x18c6/0x18d0 arch/x86/include/generated/asm/syscalls_64.h:232
> do_syscall_x64 arch/x86/entry/syscall_64.c:61 [inline]
> do_syscall_64+0x170/0x540 arch/x86/entry/syscall_64.c:84
> entry_SYSCALL_64_after_hwframe+0x77/0x7f
>
> Memory state around the buggy address:
> ffff888027515f00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> ffff888027515f80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> >ffff888027516000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
> ^
> ffff888027516080: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
> ffff888027516100: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
> ==================================================================
>
> Following is the root cause analysis for this issue, note that the
> analysis is performed with the assistance of LLM, but we try our best to
> ensure the accuracy.
>
> A rindex entry's ri_bitbytes is not checked against sb_bsize.
> compute_bitstructs() splits ri_bitbytes across the blocks of the resource
> group and gives the remainder to the last bitmap, whose length bi_bytes can
> then exceed the size of the block that stores it. gfs2_bitfit() scans past
> the end of that buffer, which KASAN reports as a use-after-free.
>
> To fix this issue, a bitmap that does not fit in the block that holds it
> should be rejected:
>
> diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c
> index 5988a165a830..689ff5a4e0df 100644
> --- a/fs/gfs2/rgrp.c
> +++ b/fs/gfs2/rgrp.c
> @@ -804,6 +804,12 @@ static int compute_bitstructs(struct gfs2_rgrpd *rgd)
> bi->bi_blocks = bytes * GFS2_NBBY;
> }
>
> + /* A bitmap must fit in the block that holds it */
> + if (bytes > sdp->sd_sb.sb_bsize - bi->bi_offset) {
> + gfs2_consist_rgrpd(rgd);
> + return -EIO;
> + }
> +
> bytes_left -= bytes;
> }
this is already addressed by the following commit on for-next:
ea31b5336369 ("gfs2: Improve resource group validation and error handling")
https://git.kernel.org/pub/scm/linux/kernel/git/gfs2/linux-gfs2.git/commit/?id=ea31b5336369a76952767f1aa9f81a343de4d4ca
Thanks,
Andreas