fs/ntfs3/dif.c ntfs_read_hdr() uses INDEX_HDR fields without enough checks

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



I've attached a corrupt ntfs image that, when mounted with the kernel
ntfs3 module and ls -l'd, causes ntfs_read_hdr() to read through a
wild pointer. KASAN or something similar may be needed to see this.

The ntfs image causes ntfs_readdir() to pass this hdr to
ntfs_read_hdr():

(gdb) print/x *hdr
$2 = {de_off = 0x40000000, used = 0x7ffffff0, total = 0x7fffffff, flags = 0x1, 
  res = {0x0, 0x0, 0x0}}

The de_off value is much too big, yet it's smaller than hdr->used, so
the checks in ntfs_read_hdr() pass. e incorporates de_off, so that
reading e->size causes a wild pointer dereference:

    u32 off = le32_to_cpu(hdr->de_off);
      ...;
        e = Add2Ptr(hdr, off);
        e_size = le16_to_cpu(e->size);

hdr_find_e() in fs/ntfs3/index.c has similar code.

# gunzip ntfs23a.img.gz
# mount -t ntfs3 -o loop,rw ntfs23a.img /mnt 
# ls -l /mnt

==================================================================
BUG: KASAN: use-after-free in ntfs_read_hdr+0x60b/0xa90
Read of size 2 at addr ffff88815e2a2960 by task ls/1276

CPU: 9 PID: 1276 Comm: ls Not tainted 6.7.0-11091-g296455ade1fd #5
Hardware name: FreeBSD BHYVE/BHYVE, BIOS 13.0 11/10/2020
Call Trace:
 <TASK>
 dump_stack_lvl+0x37/0x50
 print_report+0xcc/0x610
 ? __virt_addr_valid+0x1ce/0x2a0
 ? ntfs_read_hdr+0x60b/0xa90
 kasan_report+0xb0/0xe0
 ? ntfs_read_hdr+0x60b/0xa90
 ntfs_read_hdr+0x60b/0xa90
 ? kmem_cache_alloc+0xde/0x250
 ntfs_readdir+0x90d/0xd00
 ? __pfx_filldir64+0x10/0x10
 ? __pfx_ntfs_readdir+0x10/0x10
 ? __pfx_down_read_killable+0x10/0x10
 ? mutex_lock+0x8d/0xe0
 iterate_dir+0x1b1/0x510
 __x64_sys_getdents64+0x12d/0x230
 ? __pfx___x64_sys_getdents64+0x10/0x10
 ? __pfx_filldir64+0x10/0x10
 ? do_user_addr_fault+0x3a1/0x8d0
 do_syscall_64+0x56/0x120
 entry_SYSCALL_64_after_hwframe+0x6e/0x76
RIP: 0033:0x7eff21fac647
Code: ac fa ff 4c 89 e0 5b 5d 41 5c c3 0f 1f 84 00 00 00 00 00 f3 0f 1e fa b8 ff ff ff 7f 48 39 c2 48 0f 47 d0 b8 d9 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 01 c3 48 8b 15 b9 27 13 00 f7 d8 64 89 02 48
RSP: 002b:00007ffcd21b9848 EFLAGS: 00000293 ORIG_RAX: 00000000000000d9
RAX: ffffffffffffffda RBX: 00005595f8e47df0 RCX: 00007eff21fac647
RDX: 0000000000008000 RSI: 00005595f8e47df0 RDI: 0000000000000003
RBP: 00005595f8e47dc4 R08: 0000000000090800 R09: 00005595f8e47dc0
R10: 0000000000000078 R11: 0000000000000293 R12: fffffffffffffe98
R13: 0000000000000000 R14: 00005595f8e47dc0 R15: 0000000000000000
 </TASK>

The buggy address belongs to the physical page:
page:ffffea000578a880 refcount:0 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x15e2a2
flags: 0x200000000000000(node=0|zone=2)
page_type: 0xffffffff()
raw: 0200000000000000 ffffea000578a888 ffffea000578a888 0000000000000000
raw: 0000000000000000 0000000000000000 00000000ffffffff 0000000000000000
page dumped because: kasan: bad access detected

Memory state around the buggy address:
 ffff88815e2a2800: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
 ffff88815e2a2880: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
>ffff88815e2a2900: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
                                                       ^
 ffff88815e2a2980: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
 ffff88815e2a2a00: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
==================================================================
Disabling lock debugging due to kernel taint

Robert Morris
rtm@xxxxxxxxxxxxx

Attachment: ntfs23a.img.gz
Description: Binary data


[Index of Archives]     [Linux Driver Backports]     [DMA Engine]     [Linux GPIO]     [Linux SPI]     [Video for Linux]     [Linux USB Devel]     [Linux Coverity]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]
  Powered by Linux