public inbox for ntfs3@lists.linux.dev
 help / color / mirror / Atom feed
From: rtm@csail.mit.edu
To: almaz.alexandrovich@paragon-software.com
Cc: ntfs3@lists.linux.dev
Subject: fs/ntfs3/dif.c ntfs_read_hdr() uses INDEX_HDR fields without enough checks
Date: Fri, 19 Jan 2024 16:14:41 -0500	[thread overview]
Message-ID: <27327.1705698881@localhost> (raw)

[-- Attachment #1: Type: text/plain, Size: 3392 bytes --]

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@csail.mit.edu


[-- Attachment #2: ntfs23a.img.gz --]
[-- Type: application/octet-stream, Size: 124384 bytes --]

                 reply	other threads:[~2024-01-19 21:14 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=27327.1705698881@localhost \
    --to=rtm@csail.mit.edu \
    --cc=almaz.alexandrovich@paragon-software.com \
    --cc=ntfs3@lists.linux.dev \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox