[PATCH] fs/ntfs3: Fix potential use-after-free in ntfs_init_from_boot()

From: Shigeru Yoshida
Date: Sat Aug 12 2023 - 11:49:13 EST


KASAN found the following issue:

BUG: KASAN: use-after-free in memcmp+0x172/0x1c0
Read of size 8 at addr ffff88802d88a002 by task repro/4557

CPU: 0 PID: 4557 Comm: repro Not tainted 6.5.0-rc5-00296-gf8de32cc060b-dirty #20
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.2-1.fc38 04/01/2014
Call Trace:
<TASK>
dump_stack_lvl+0xd3/0x1b0
print_report+0xc4/0x630
? __virt_addr_valid+0x5e/0x2d0
? __phys_addr+0xc6/0x140
kasan_report+0xda/0x110
? memcmp+0x172/0x1c0
? memcmp+0x172/0x1c0
memcmp+0x172/0x1c0
? __bread_gfp+0x79/0x310
ntfs_fill_super+0x722/0x43a0
? put_ntfs+0x330/0x330
? vsprintf+0x30/0x30
? set_blocksize+0x2c0/0x360
get_tree_bdev+0x43e/0x7d0
? put_ntfs+0x330/0x330
vfs_get_tree+0x88/0x350
path_mount+0x69f/0x1ec0
? kmem_cache_free+0xf0/0x4a0
? finish_automount+0xa50/0xa50
? putname+0x105/0x140
__x64_sys_mount+0x293/0x310
? copy_mnt_ns+0xb60/0xb60
? syscall_enter_from_user_mode+0x26/0x80
do_syscall_64+0x39/0xb0
entry_SYSCALL_64_after_hwframe+0x63/0xcd
RIP: 0033:0x7f2d6bf29eaa
Code: 48 8b 0d 71 df 0a 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 c8
RSP: 002b:00007ffcf8924638 EFLAGS: 00000202 ORIG_RAX: 00000000000000a5
RAX: ffffffffffffffda RBX: 0000000000423e00 RCX: 00007f2d6bf29eaa
RDX: 0000000020000080 RSI: 00000000200000c0 RDI: 00007ffcf8924770
RBP: 00007ffcf8924800 R08: 00007ffcf8924670 R09: 0000000000000000
R10: 0000000000000040 R11: 0000000000000202 R12: 00007ffcf8924978
R13: 00007ffcf8924988 R14: 0000000000402c65 R15: 00007f2d6c014a60
</TASK>

dev_size variable is used to calculate the LBO of the alternative boot
in ntfs_init_from_boot(). dev_size is set to the number of bytes of
the device, but it can be modified when the NTFS sector size and the
media sector size are different. So, using dev_size can cause the
above issue in that case.

This patch fixes this issue by resetting dev_size to the actual number
of bytes of the device before calculating the LBO of the alternative
boot.

Fixes: 6a4cd3ea7d77 ("fs/ntfs3: Alternative boot if primary boot is corrupted")
Signed-off-by: Shigeru Yoshida <syoshida@xxxxxxxxxx>
---
fs/ntfs3/super.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/fs/ntfs3/super.c b/fs/ntfs3/super.c
index 1a02072b6b0e..43b698353840 100644
--- a/fs/ntfs3/super.c
+++ b/fs/ntfs3/super.c
@@ -1067,7 +1067,10 @@ static int ntfs_init_from_boot(struct super_block *sb, u32 sector_size,
out:
if (err == -EINVAL && !bh->b_blocknr && dev_size > PAGE_SHIFT) {
u32 block_size = min_t(u32, sector_size, PAGE_SIZE);
- u64 lbo = dev_size - sizeof(*boot);
+ u64 lbo;
+
+ dev_size = bdev_nr_bytes(sb->s_bdev);
+ lbo = dev_size - sizeof(*boot);

/*
* Try alternative boot (last sector)
--
2.41.0