KASAN: slab-use-after-free Read in sanity_check_extent_cache

From: Ubisectech Sirius
Date: Sun Mar 31 2024 - 21:37:48 EST


Hello.
We are Ubisectech Sirius Team, the vulnerability lab of China ValiantSec. Recently, our team has discovered a issue in Linux kernel 6.7. Attached to the email were a PoC file of the issue.

Stack dump:

[ 182.605274][ T8239] ==================================================================
[ 182.606318][ T8239] BUG: KASAN: slab-use-after-free in sanity_check_extent_cache (fs/f2fs/extent_cache.c:44)
[ 182.607409][ T8239] Read of size 4 at addr ffff88804e5026fc by task poc/8239
[ 182.608334][ T8239]
[ 182.608656][ T8239] CPU: 0 PID: 8239 Comm: poc Not tainted 6.7.0 #1
[ 182.609482][ T8239] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.15.0-1 04/01/2014
[ 182.610577][ T8239] Call Trace:
[ 182.610994][ T8239] <TASK>
[ 182.611370][ T8239] dump_stack_lvl (lib/dump_stack.c:112 (discriminator 1))
[ 182.611972][ T8239] print_report (mm/kasan/report.c:378 mm/kasan/report.c:488)
[ 182.612557][ T8239] ? __virt_addr_valid (arch/x86/mm/physaddr.c:66)
[ 182.613234][ T8239] ? __phys_addr (arch/x86/mm/physaddr.c:32 (discriminator 4))
[ 182.613840][ T8239] ? sanity_check_extent_cache (fs/f2fs/extent_cache.c:44)
[ 182.614599][ T8239] kasan_report (mm/kasan/report.c:603)
[ 182.615161][ T8239] ? sanity_check_extent_cache (fs/f2fs/extent_cache.c:44)
[ 182.615928][ T8239] sanity_check_extent_cache (fs/f2fs/extent_cache.c:44)
[ 182.616644][ T8239] f2fs_iget (fs/f2fs/f2fs.h:1977 fs/f2fs/inode.c:521 fs/f2fs/inode.c:560)
[ 182.617213][ T8239] f2fs_nfs_get_inode (fs/f2fs/super.c:3238 fs/f2fs/super.c:3223)
[ 182.617848][ T8239] ? __pfx_f2fs_nfs_get_inode (fs/f2fs/super.c:3225)
[ 182.618558][ T8239] generic_fh_to_dentry (fs/libfs.c:1413)
[ 182.619190][ T8239] exportfs_decode_fh_raw (fs/exportfs/expfs.c:444)
[ 182.619935][ T8239] ? __pfx_vfs_dentry_acceptable (fs/fhandle.c:138)
[ 182.620748][ T8239] ? __pfx_f2fs_fh_to_dentry (fs/f2fs/super.c:3250)
[ 182.621453][ T8239] ? __pfx_exportfs_decode_fh_raw (fs/exportfs/expfs.c:433)
[ 182.622200][ T8239] ? __pfx___lock_acquire (kernel/locking/lockdep.c:4993)
[ 182.622864][ T8239] ? find_held_lock (kernel/locking/lockdep.c:5244)
[ 182.623511][ T8239] ? __fget_files (fs/file.c:1008 fs/file.c:1036)
[ 182.624104][ T8239] ? __pfx_lock_release (kernel/locking/lockdep.c:5762)
[ 182.624804][ T8239] ? __pfx_lock_release (kernel/locking/lockdep.c:5762)
[ 182.625463][ T8239] ? __pfx_vfs_dentry_acceptable (fs/fhandle.c:138)
[ 182.626197][ T8239] exportfs_decode_fh (./include/linux/err.h:72 fs/exportfs/expfs.c:586)
[ 182.626823][ T8239] do_handle_open (fs/fhandle.c:159 fs/fhandle.c:210 fs/fhandle.c:226)
[ 182.627534][ T8239] ? __pfx_do_handle_open (fs/fhandle.c:220)
[ 182.628186][ T8239] ? __pfx_do_raw_spin_lock (kernel/locking/spinlock_debug.c:114)
[ 182.628868][ T8239] ? syscall_enter_from_user_mode+0x7f/0x120
[ 182.629630][ T8239] do_syscall_64 (./arch/x86/include/asm/processor.h:532 ./arch/x86/include/asm/processor.h:537 ./arch/x86/include/asm/entry-common.h:41 ./include/linux/entry-common.h:108 ./include/linux/entry-common.h:194 arch/x86/entry/common.c:79)
[ 182.630193][ T8239] entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:129)
[ 182.630931][ T8239] RIP: 0033:0x7f759aef9f29
[ 182.631505][ T8239] Code: 00 c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d 37 8f 0d 00 f7 d8 64 89 01 48
All code
========
0: 00 c3 add %al,%bl
2: 66 2e 0f 1f 84 00 00 cs nopw 0x0(%rax,%rax,1)
9: 00 00 00
c: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1)
11: 48 89 f8 mov %rdi,%rax
14: 48 89 f7 mov %rsi,%rdi
17: 48 89 d6 mov %rdx,%rsi
1a: 48 89 ca mov %rcx,%rdx
1d: 4d 89 c2 mov %r8,%r10
20: 4d 89 c8 mov %r9,%r8
23: 4c 8b 4c 24 08 mov 0x8(%rsp),%r9
28: 0f 05 syscall
2a:* 48 3d 01 f0 ff ff cmp $0xfffffffffffff001,%rax <-- trapping instruction
30: 73 01 jae 0x33
32: c3 ret
33: 48 8b 0d 37 8f 0d 00 mov 0xd8f37(%rip),%rcx # 0xd8f71
3a: f7 d8 neg %eax
3c: 64 89 01 mov %eax,%fs:(%rcx)
3f: 48 rex.W

Code starting with the faulting instruction
===========================================
0: 48 3d 01 f0 ff ff cmp $0xfffffffffffff001,%rax
6: 73 01 jae 0x9
8: c3 ret
9: 48 8b 0d 37 8f 0d 00 mov 0xd8f37(%rip),%rcx # 0xd8f47
10: f7 d8 neg %eax
12: 64 89 01 mov %eax,%fs:(%rcx)
15: 48 rex.W
[ 182.633972][ T8239] RSP: 002b:00007f759addfe98 EFLAGS: 00000246 ORIG_RAX: 0000000000000130
[ 182.635008][ T8239] RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f759aef9f29
[ 182.636001][ T8239] RDX: 0000000000000000 RSI: 0000000020000240 RDI: 0000000000000004
[ 182.636980][ T8239] RBP: 00007f759addfec0 R08: 00007f759ade0700 R09: 0000000000000000
[ 182.637971][ T8239] R10: 00007f759ade0700 R11: 0000000000000246 R12: 00007ffe9ec3aa5e
[ 182.638962][ T8239] R13: 00007ffe9ec3aa5f R14: 00007f759addffc0 R15: 0000000000022000
[ 182.640022][ T8239] </TASK>
[ 182.640412][ T8239]
[ 182.640695][ T8239] Allocated by task 8231:
[ 182.641213][ T8239] kasan_save_stack (mm/kasan/common.c:47)
[ 182.641820][ T8239] kasan_set_track (mm/kasan/common.c:62)
[ 182.642409][ T8239] __kasan_slab_alloc (mm/kasan/common.c:312 mm/kasan/common.c:338)
[ 182.643073][ T8239] kmem_cache_alloc (mm/slub.c:3855)
[ 182.643736][ T8239] __grab_extent_tree (fs/f2fs/f2fs.h:2818 fs/f2fs/f2fs.h:2827 fs/f2fs/extent_cache.c:334)
[ 182.644429][ T8239] f2fs_init_read_extent_tree (fs/f2fs/extent_cache.c:407)
[ 182.645135][ T8239] f2fs_iget (fs/f2fs/f2fs.h:3207 fs/f2fs/inode.c:520 fs/f2fs/inode.c:560)
[ 182.645703][ T8239] f2fs_nfs_get_inode (fs/f2fs/super.c:3238 fs/f2fs/super.c:3223)
[ 182.646334][ T8239] generic_fh_to_dentry (fs/libfs.c:1413)
[ 182.646986][ T8239] exportfs_decode_fh_raw (fs/exportfs/expfs.c:444)
[ 182.647710][ T8239] exportfs_decode_fh (./include/linux/err.h:72 fs/exportfs/expfs.c:586)
[ 182.648359][ T8239] do_handle_open (fs/fhandle.c:159 fs/fhandle.c:210 fs/fhandle.c:226)
[ 182.648994][ T8239] do_syscall_64 (./arch/x86/include/asm/processor.h:532 ./arch/x86/include/asm/processor.h:537 ./arch/x86/include/asm/entry-common.h:41 ./include/linux/entry-common.h:108 ./include/linux/entry-common.h:194 arch/x86/entry/common.c:79)
[ 182.649570][ T8239] entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:129)
[ 182.650358][ T8239]
[ 182.650667][ T8239] Freed by task 8231:
[ 182.651189][ T8239] kasan_save_stack (mm/kasan/common.c:47)
[ 182.651820][ T8239] kasan_set_track (mm/kasan/common.c:62)
[ 182.652388][ T8239] kasan_save_free_info (mm/kasan/generic.c:499 mm/kasan/generic.c:577)
[ 182.653016][ T8239] ____kasan_slab_free+0x162/0x1c0
[ 182.653655][ T8239] slab_free_freelist_hook+0x95/0x1d0
[ 182.654341][ T8239] kmem_cache_free (./include/linux/kfence.h:58 ./include/linux/kfence.h:185 mm/slub.c:2085 mm/slub.c:4280 mm/slub.c:4344)
[ 182.654977][ T8239] __destroy_extent_tree (./include/linux/instrumented.h:96 (discriminator 2) ./include/linux/atomic/atomic-instrumented.h:592 (discriminator 2) fs/f2fs/extent_cache.c:1133 (discriminator 2))
[ 182.655678][ T8239] f2fs_destroy_extent_tree (fs/f2fs/extent_cache.c:1144)
[ 182.656397][ T8239] f2fs_evict_inode (fs/f2fs/inode.c:833 (discriminator 2))
[ 182.657038][ T8239] evict (fs/inode.c:667)
[ 182.657524][ T8239] iput.part.0 (fs/inode.c:485 fs/inode.c:1738 fs/inode.c:1767)
[ 182.658090][ T8239] iput (fs/inode.c:1769)
[ 182.658555][ T8239] f2fs_iget (fs/f2fs/inode.c:446 fs/f2fs/inode.c:560)
[ 182.659136][ T8239] f2fs_nfs_get_inode (fs/f2fs/super.c:3238 fs/f2fs/super.c:3223)
[ 182.659773][ T8239] generic_fh_to_dentry (fs/libfs.c:1413)
[ 182.660427][ T8239] exportfs_decode_fh_raw (fs/exportfs/expfs.c:444)
[ 182.661146][ T8239] exportfs_decode_fh (./include/linux/err.h:72 fs/exportfs/expfs.c:586)
[ 182.661782][ T8239] do_handle_open (fs/fhandle.c:159 fs/fhandle.c:210 fs/fhandle.c:226)
[ 182.662416][ T8239] do_syscall_64 (./arch/x86/include/asm/processor.h:532 ./arch/x86/include/asm/processor.h:537 ./arch/x86/include/asm/entry-common.h:41 ./include/linux/entry-common.h:108 ./include/linux/entry-common.h:194 arch/x86/entry/common.c:79)
[ 182.663027][ T8239] entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:129)
[ 182.663802][ T8239]
[ 182.664103][ T8239] The buggy address belongs to the object at ffff88804e502680
[ 182.664103][ T8239] which belongs to the cache f2fs_extent_tree of size 144
[ 182.665892][ T8239] The buggy address is located 124 bytes inside of
[ 182.665892][ T8239] freed 144-byte region [ffff88804e502680, ffff88804e502710)
[ 182.667615][ T8239]
[ 182.667921][ T8239] The buggy address belongs to the physical page:
[ 182.668760][ T8239] page:ffffea0001394080 refcount:1 mapcount:0 mapping:0000000000000000 index:0xffff88804e5025b0 pfn:0x4e502
[ 182.670141][ T8239] flags: 0x4fff00000000800(slab|node=1|zone=1|lastcpupid=0x7ff)
[ 182.671084][ T8239] page_type: 0xffffffff()
[ 182.671675][ T8239] raw: 04fff00000000800 ffff888017dff780 dead000000000122 0000000000000000
[ 182.672796][ T8239] raw: ffff88804e5025b0 000000008013000f 00000001ffffffff 0000000000000000
[ 182.673888][ T8239] page dumped because: kasan: bad access detected
[ 182.674663][ T8239] page_owner tracks the page as allocated
[ 182.675400][ T8239] page last allocated via order 0, migratetype Reclaimable, gfp_mask 0x12c50(GFP_NOFS|__GFP_NOWARN|__GFP_NORETRY|__GFP_RECLAIMABLE), pid 8061, tgid 8060 (poc), ts 170716468843, free_ts 0
[ 182.677709][ T8239] post_alloc_hook (./include/linux/page_owner.h:32 mm/page_alloc.c:1534)
[ 182.678313][ T8239] get_page_from_freelist (mm/page_alloc.c:1543 mm/page_alloc.c:3317)
[ 182.679005][ T8239] __alloc_pages (mm/page_alloc.c:4576)
[ 182.679623][ T8239] alloc_pages_mpol (mm/mempolicy.c:2253 (discriminator 1))
[ 182.680250][ T8239] new_slab (./include/linux/gfp.h:235 ./include/linux/gfp.h:261 mm/slub.c:2175 mm/slub.c:2338 mm/slub.c:2391)
[ 182.680807][ T8239] ___slab_alloc (mm/slub.c:511 mm/slub.c:2534 mm/slub.c:3536)
[ 182.681421][ T8239] __slab_alloc.constprop.0 (mm/slub.c:3610)
[ 182.682124][ T8239] kmem_cache_alloc (mm/slub.c:3663 mm/slub.c:3835 mm/slub.c:3852)
[ 182.682737][ T8239] __grab_extent_tree (fs/f2fs/f2fs.h:2818 fs/f2fs/f2fs.h:2827 fs/f2fs/extent_cache.c:334)
[ 182.683396][ T8239] f2fs_init_read_extent_tree (fs/f2fs/extent_cache.c:407)
[ 182.684129][ T8239] f2fs_iget (fs/f2fs/f2fs.h:3207 fs/f2fs/inode.c:520 fs/f2fs/inode.c:560)
[ 182.684747][ T8239] f2fs_nfs_get_inode (fs/f2fs/super.c:3238 fs/f2fs/super.c:3223)
[ 182.685385][ T8239] generic_fh_to_dentry (fs/libfs.c:1413)
[ 182.686053][ T8239] exportfs_decode_fh_raw (fs/exportfs/expfs.c:444)
[ 182.686741][ T8239] exportfs_decode_fh (./include/linux/err.h:72 fs/exportfs/expfs.c:586)
[ 182.687392][ T8239] do_handle_open (fs/fhandle.c:159 fs/fhandle.c:210 fs/fhandle.c:226)
[ 182.688010][ T8239] page_owner free stack trace missing
[ 182.688672][ T8239]
[ 182.688993][ T8239] Memory state around the buggy address:
[ 182.689741][ T8239] ffff88804e502580: fc fc fc fc fc fc fb fb fb fb fb fb fb fb fb fb
[ 182.690722][ T8239] ffff88804e502600: fb fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc
[ 182.691740][ T8239] >ffff88804e502680: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[ 182.692798][ T8239] ^
[ 182.693789][ T8239] ffff88804e502700: fb fb fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[ 182.694783][ T8239] ffff88804e502780: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[ 182.695815][ T8239] ==================================================================
[ 182.698239][ T8239] Kernel panic - not syncing: KASAN: panic_on_warn set ...
[ 182.699172][ T8239] CPU: 0 PID: 8239 Comm: poc Not tainted 6.7.0 #1
[ 182.699976][ T8239] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.15.0-1 04/01/2014
[ 182.701074][ T8239] Call Trace:
[ 182.701498][ T8239] <TASK>
[ 182.701894][ T8239] dump_stack_lvl (lib/dump_stack.c:112 (discriminator 1))
[ 182.702522][ T8239] panic (kernel/panic.c:348)
[ 182.703065][ T8239] ? __pfx_panic (kernel/panic.c:282)
[ 182.707975][ T8239] ? irqentry_exit (kernel/entry/common.c:352)
[ 182.708595][ T8239] ? preempt_schedule_thunk (arch/x86/entry/thunk_64.S:12)
[ 182.709286][ T8239] ? preempt_schedule_common (./arch/x86/include/asm/preempt.h:84 kernel/sched/core.c:6917)
[ 182.710013][ T8239] ? sanity_check_extent_cache (fs/f2fs/extent_cache.c:44)
[ 182.710792][ T8239] ? check_panic_on_warn (kernel/panic.c:240)
[ 182.711481][ T8239] ? sanity_check_extent_cache (fs/f2fs/extent_cache.c:44)
[ 182.712268][ T8239] check_panic_on_warn (kernel/panic.c:241)
[ 182.712921][ T8239] ? sanity_check_extent_cache (fs/f2fs/extent_cache.c:44)
[ 182.713673][ T8239] end_report (mm/kasan/report.c:226)
[ 182.714248][ T8239] kasan_report (./arch/x86/include/asm/smap.h:56 mm/kasan/report.c:606)
[ 182.714842][ T8239] ? sanity_check_extent_cache (fs/f2fs/extent_cache.c:44)
[ 182.715629][ T8239] sanity_check_extent_cache (fs/f2fs/extent_cache.c:44)
[ 182.716374][ T8239] f2fs_iget (fs/f2fs/f2fs.h:1977 fs/f2fs/inode.c:521 fs/f2fs/inode.c:560)
[ 182.716959][ T8239] f2fs_nfs_get_inode (fs/f2fs/super.c:3238 fs/f2fs/super.c:3223)
[ 182.717596][ T8239] ? __pfx_f2fs_nfs_get_inode (fs/f2fs/super.c:3225)
[ 182.718298][ T8239] generic_fh_to_dentry (fs/libfs.c:1413)
[ 182.718953][ T8239] exportfs_decode_fh_raw (fs/exportfs/expfs.c:444)
[ 182.719667][ T8239] ? __pfx_vfs_dentry_acceptable (fs/fhandle.c:138)
[ 182.720402][ T8239] ? __pfx_f2fs_fh_to_dentry (fs/f2fs/super.c:3250)
[ 182.721117][ T8239] ? __pfx_exportfs_decode_fh_raw (fs/exportfs/expfs.c:433)
[ 182.721900][ T8239] ? __pfx___lock_acquire (kernel/locking/lockdep.c:4993)
[ 182.722594][ T8239] ? find_held_lock (kernel/locking/lockdep.c:5244)
[ 182.723201][ T8239] ? __fget_files (fs/file.c:1008 fs/file.c:1036)
[ 182.723812][ T8239] ? __pfx_lock_release (kernel/locking/lockdep.c:5762)
[ 182.724466][ T8239] ? __pfx_lock_release (kernel/locking/lockdep.c:5762)
[ 182.725103][ T8239] ? __pfx_vfs_dentry_acceptable (fs/fhandle.c:138)
[ 182.725816][ T8239] exportfs_decode_fh (./include/linux/err.h:72 fs/exportfs/expfs.c:586)
[ 182.726439][ T8239] do_handle_open (fs/fhandle.c:159 fs/fhandle.c:210 fs/fhandle.c:226)
[ 182.727048][ T8239] ? __pfx_do_handle_open (fs/fhandle.c:220)
[ 182.727787][ T8239] ? __pfx_do_raw_spin_lock (kernel/locking/spinlock_debug.c:114)
[ 182.728492][ T8239] ? syscall_enter_from_user_mode+0x7f/0x120
[ 182.729250][ T8239] do_syscall_64 (./arch/x86/include/asm/processor.h:532 ./arch/x86/include/asm/processor.h:537 ./arch/x86/include/asm/entry-common.h:41 ./include/linux/entry-common.h:108 ./include/linux/entry-common.h:194 arch/x86/entry/common.c:79)
[ 182.729850][ T8239] entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:129)
[ 182.730609][ T8239] RIP: 0033:0x7f759aef9f29
[ 182.731167][ T8239] Code: 00 c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d 37 8f 0d 00 f7 d8 64 89 01 48
All code
========
0: 00 c3 add %al,%bl
2: 66 2e 0f 1f 84 00 00 cs nopw 0x0(%rax,%rax,1)
9: 00 00 00
c: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1)
11: 48 89 f8 mov %rdi,%rax
14: 48 89 f7 mov %rsi,%rdi
17: 48 89 d6 mov %rdx,%rsi
1a: 48 89 ca mov %rcx,%rdx
1d: 4d 89 c2 mov %r8,%r10
20: 4d 89 c8 mov %r9,%r8
23: 4c 8b 4c 24 08 mov 0x8(%rsp),%r9
28: 0f 05 syscall
2a:* 48 3d 01 f0 ff ff cmp $0xfffffffffffff001,%rax <-- trapping instruction
30: 73 01 jae 0x33
32: c3 ret
33: 48 8b 0d 37 8f 0d 00 mov 0xd8f37(%rip),%rcx # 0xd8f71
3a: f7 d8 neg %eax
3c: 64 89 01 mov %eax,%fs:(%rcx)
3f: 48 rex.W

Code starting with the faulting instruction
===========================================
0: 48 3d 01 f0 ff ff cmp $0xfffffffffffff001,%rax
6: 73 01 jae 0x9
8: c3 ret
9: 48 8b 0d 37 8f 0d 00 mov 0xd8f37(%rip),%rcx # 0xd8f47
10: f7 d8 neg %eax
12: 64 89 01 mov %eax,%fs:(%rcx)
15: 48 rex.W
[ 182.733681][ T8239] RSP: 002b:00007f759addfe98 EFLAGS: 00000246 ORIG_RAX: 0000000000000130
[ 182.734711][ T8239] RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f759aef9f29
[ 182.735704][ T8239] RDX: 0000000000000000 RSI: 0000000020000240 RDI: 0000000000000004
[ 182.736668][ T8239] RBP: 00007f759addfec0 R08: 00007f759ade0700 R09: 0000000000000000
[ 182.737674][ T8239] R10: 00007f759ade0700 R11: 0000000000000246 R12: 00007ffe9ec3aa5e
[ 182.738665][ T8239] R13: 00007ffe9ec3aa5f R14: 00007f759addffc0 R15: 0000000000022000
[ 182.739657][ T8239] </TASK>
[ 182.741018][ T8239] Kernel Offset: disabled
[ 182.741589][ T8239] Rebooting in 86400 seconds..

Thank you for taking the time to read this email and we look forward to working with you further.

Attachment: poc.c
Description: Binary data