Overview
Mount crafted image can cause Null-Ptr-Deref in f2fs_recover_fsync_data function
Target
Linux kernel f2fs FileSystem
| Linux Version | Availablity |
|---|---|
| 5.0.21 | True |
Reproduce
mkdir mnt
mount poc_2019_19815.img ./mntRoot cause
static inline void f2fs_put_page(struct page *page, int unlock)
{
if (!page)
return;
if (unlock) {
f2fs_bug_on(F2FS_P_SB(page), !PageLocked(page));
unlock_page(page);
}
put_page(page);
}
static inline struct f2fs_sb_info *F2FS_P_SB(struct page *page)
{
[1] return F2FS_M_SB(page->mapping);
}
in function [1] page->mapping, can be NULL
Debugger / KASAN
Debugger view:
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── registers ────
$rax : 0xfffffffffffffffb → 0xfffffffffffffffb
$rbx : 0x0000000000000003 → 0x0000000000000003
$rcx : 0xffffffff8175e61d → 0x0133840f344bfff0 → 0x0133840f344bfff0
$rdx : 0x0000000000000000 → 0x0000000000000000
$rsp : 0xffff88806661f8b0 → 0xffff888064bd1100 → 0xffff888064bd1980 → 0xffffffff8312d9c0 → 0xffff88806d021100 → 0xffff88806d021980 → 0xffff88806d024400 → 0xffff88806d025500
$rbp : 0x00000000fffffffb → 0x00000000fffffffb
$rsi : 0x0000000000000004 → 0x0000000000000004
$rdi : 0x0000000000000003 → 0x0000000000000003
$rip : 0xffffffff8179b6f3 → 0x468b49ffb1f628e8 → 0x468b49ffb1f628e8
$r8 : 0xfffff94000327ec7 → 0x0000000000000000 → 0x0000000000000000
$r9 : 0xfffff94000327ec7 → 0x0000000000000000 → 0x0000000000000000
$r10 : 0x0000000000000001 → 0x0000000000000001
$r11 : 0xfffff94000327ec6 → 0x0000000000000000 → 0x0000000000000000
$r12 : 0xffff88806661f940 → 0xffff88806661f940 → [loop detected]
$r13 : 0xffff88806c96c930 → 0x0000400900000007 → 0x0000400900000007
$r14 : 0xfffffffffffffffb → 0xfffffffffffffffb
$r15 : 0xffff888064bd1100 → 0xffff888064bd1980 → 0xffffffff8312d9c0 → 0xffff88806d021100 → 0xffff88806d021980 → 0xffff88806d024400 → 0xffff88806d025500 → 0xffff88806d026600
$eflags: [zero carry parity adjust SIGN trap INTERRUPT direction overflow resume virtualx86 identification]
$cs: 0x0010 $ss: 0x0018 $ds: 0x0000 $es: 0x0000 $fs: 0x0000 $gs: 0x0000
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── stack ────
0xffff88806661f8b0│+0x0000: 0xffff888064bd1100 → 0xffff888064bd1980 → 0xffffffff8312d9c0 → 0xffff88806d021100 → 0xffff88806d021980 → 0xffff88806d024400 → 0xffff88806d025500 ← $rsp
0xffff88806661f8b8│+0x0008: 0x0000000000501206 → 0x0000000000501206
0xffff88806661f8c0│+0x0010: 0x0000000000000000 → 0x0000000000000000
0xffff88806661f8c8│+0x0018: 0x0000000000801ff6 → 0x0000000000801ff6
0xffff88806661f8d0│+0x0020: 0x0000000000000246 → 0x0000000000000246
0xffff88806661f8d8│+0x0028: 0xffff88806661f980 → 0xffff88806661f980 → [loop detected]
0xffff88806661f8e0│+0x0030: 0xffff88806661f9c0 → 0xffff88806661f9c0 → [loop detected]
0xffff88806661f8e8│+0x0038: 0x0000000012010000 → 0x0000000012010000
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── code:x86:64 ────
0xffffffff8179b6e9 <f2fs_recover_fsync_data+1561> div BYTE PTR [rdi+riz*2+0x49]
0xffffffff8179b6ed <f2fs_recover_fsync_data+1565> lea ebx, [rsi+0x8] [1]
0xffffffff8179b6f0 <f2fs_recover_fsync_data+1568> mov rdi, rbx
→ 0xffffffff8179b6f3 <f2fs_recover_fsync_data+1571> call 0xffffffff812bad20 <__asan_load8>
↳ 0xffffffff812bad20 <__asan_load8_noabort+0> movabs rax, 0xffff7fffffffffff
0xffffffff812bad2a <__asan_load8_noabort+10> mov rcx, QWORD PTR [rsp]
0xffffffff812bad2e <__asan_load8_noabort+14> cmp rdi, rax
0xffffffff812bad31 <__asan_load8_noabort+17> jbe 0xffffffff812bad64 <__asan_load8+68>
0xffffffff812bad33 <__asan_load8_noabort+19> lea rax, [rdi+0x7]
0xffffffff812bad37 <__asan_load8_noabort+23> mov rdx, rax
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── arguments ────
__asan_load8 (
long unsigned int var_0 = 0x0000000000000003 → 0x0000000000000003
)
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── source:./include/linux[...].h+193 ────
188 })
189
190 static __always_inline
191 void __read_once_size(const volatile void *p, void *res, int size)
192 {
→ 193 __READ_ONCE_SIZE;
194 }
KASAN log (the trailing NULL-pointer Oops panic that repeats the same frames is truncated):
[ 220.714471] F2FS-fs (loop0): Fix alignment : done, start(4096) end(436224000) block(8396800)
[ 220.717356] F2FS-fs (loop0): Wrong MAIN_AREA boundary, start(4096) end(16384) block(14848)
[ 220.719675] F2FS-fs (loop0): Cant find valid F2FS filesystem in 2th superblock
[ 220.754065] F2FS-fs (loop0): invalid cp_pack_total_block_count:33023
[ 232.122480] hrtimer: interrupt took 8468280 ns
[ 232.671931] attempt to access beyond end of device
[ 232.676755] loop0: rw=8192, want=41979960, limit=131072
[ 232.762826] ==================================================================
[ 232.762826] BUG: KASAN: null-ptr-deref in f2fs_recover_fsync_data+0x628/0xc10
[ 232.762826] Read of size 8 at addr 0000000000000003 by task mount/1855
[ 232.762826]
[ 232.762826] CPU: 1 PID: 1855 Comm: mount Not tainted 5.0.21 #2
[ 232.762826] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.10.2-1ubuntu1 04/01/2014
[ 232.762826] Call Trace:
[ 232.762826] dump_stack+0x5b/0x8b
[ 232.762826] ? f2fs_recover_fsync_data+0x628/0xc10
[ 232.762826] kasan_report+0x176/0x19b
[ 232.762826] ? f2fs_recover_fsync_data+0x628/0xc10
[ 232.762826] ? f2fs_recover_fsync_data+0x628/0xc10
[ 232.762826] f2fs_recover_fsync_data+0x628/0xc10
[ 232.762826] ? f2fs_space_for_roll_forward+0x50/0x50
[ 232.762826] ? _raw_write_lock+0x7f/0xe0
[ 232.762826] ? _raw_spin_lock_bh+0xf0/0xf0
[ 232.762826] ? rb_insert_color+0x27b/0x3d0
[ 232.762826] ? f2fs_remove_orphan_inode+0x10/0x10
[ 232.762826] ? f2fs_fill_super+0x278e/0x2d50
[ 232.762826] f2fs_fill_super+0x2c3f/0x2d50
[ 232.762826] ? f2fs_commit_super+0x2f0/0x2f0
[ 232.762826] ? sget_userns+0x614/0x640
[ 232.762826] ? set_blocksize+0x83/0x130
[ 232.762826] ? f2fs_commit_super+0x2f0/0x2f0
[ 232.762826] mount_bdev+0x1bb/0x200
[ 232.762826] mount_fs+0xac/0x210
[ 232.762826] ? emergency_thaw_all+0xa0/0xa0
[ 232.762826] ? memcpy+0x34/0x50
[ 232.762826] ? __init_waitqueue_head+0x29/0x30
[ 232.762826] vfs_kern_mount+0x5f/0x190
[ 232.762826] do_mount+0x30a/0x1500
[ 232.762826] ? copy_mount_string+0x20/0x20
[ 232.762826] ? __switch_to_asm+0x41/0x70
[ 232.762826] ? __switch_to_asm+0x35/0x70
[ 232.762826] ? __switch_to_asm+0x41/0x70
[ 232.762826] ? finish_task_switch+0xdd/0x320
[ 232.762826] ? __switch_to_asm+0x41/0x70
[ 232.762826] ? __switch_to_asm+0x35/0x70
[ 232.762826] ? kasan_unpoison_shadow+0x31/0x40
[ 232.762826] ? __kasan_kmalloc+0xd5/0xf0
[ 232.762826] ? strndup_user+0x3a/0x60
[ 232.762826] ? __kmalloc_track_caller+0xc7/0x1c0
[ 232.762826] ? _copy_from_user+0x61/0x90
[ 232.762826] ? memdup_user+0x39/0x60
[ 232.762826] ksys_mount+0x79/0xc0
[ 232.762826] __x64_sys_mount+0x5d/0x70
[ 232.762826] do_syscall_64+0x5e/0x150
[ 232.762826] entry_SYSCALL_64_after_hwframe+0x44/0xa9
[ 232.762826] RIP: 0033:0x7f00728ec48a
[ 232.762826] Code: 48 8b 0d 11 fa 2a 00 f7 d8 64 89 01 48 83 c8 ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 49 89 ca b8 a5 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d de f9 2a 00 f7 d8 64 89 01 48
[ 232.762826] RSP: 002b:00007fffd0ee76c8 EFLAGS: 00000202 ORIG_RAX: 00000000000000a5
[ 232.762826] RAX: ffffffffffffffda RBX: 0000560f63f2a080 RCX: 00007f00728ec48a
[ 232.762826] RDX: 0000560f63f2c760 RSI: 0000560f63f2bf60 RDI: 0000560f63f30230
[ 232.762826] RBP: 0000000000000000 R08: 0000000000000000 R09: 0000000000000020
[ 232.762826] R10: 00000000c0ed0000 R11: 0000000000000202 R12: 0000560f63f30230
[ 232.762826] R13: 0000560f63f2c760 R14: 0000000000000000 R15: 00000000ffffffff
[ 232.762826] ==================================================================
[ 232.762826] Disabling lock debugging due to kernel taint
...
Details
CVSS 5.5 (CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:N/I:N/A:H), CWE-476, published 2019-12-17, last modified 2024-11-21.
Attribution
Found as part of the Best of the Best (BoB) 8th bobfuzzer team project — a five-person team that ported the JANUS file-system fuzzer. This is team work, not sole authorship.