[Bug 277360] use-after-free or MPASS() failure during tarfs mount

From: <bugzilla-noreply_at_freebsd.org>
Date: Tue, 27 Feb 2024 18:26:00 UTC
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=277360

            Bug ID: 277360
           Summary: use-after-free or MPASS() failure during tarfs mount
           Product: Base System
           Version: CURRENT
          Hardware: Any
                OS: Any
            Status: New
          Severity: Affects Some People
          Priority: ---
         Component: kern
          Assignee: bugs@FreeBSD.org
          Reporter: rtm@lcs.mit.edu

Created attachment 248798
  --> https://bugs.freebsd.org/bugzilla/attachment.cgi?id=248798&action=edit
corrupt tar image that triggers a tarfs use-after-free

I've attached a tar image which, if mounted with tarfs on an
INVARIANTS kernel, fails this MPASS() in tarfs_lookup_path():

        MPASS(name != NULL && namelen != 0);

On a non-INVARIANTS kernel, this image causes tarfs to use memory
after freeing it. tarfs_alloc_mount() encounters an error from
tarfs_alloc_one(), and calls tarfs_free_mount(). The latter frees
everything on tmp->allnodes. But if the root tarfs_node is early on
the list, then tarfs_free_node()'s recursive call

       case VDIR:
                ...;
                if (tnp->parent != NULL && tnp->parent != tnp)
                        tarfs_free_node(tnp->parent);

can use a tnp->parent that is the now-freed root tarfs_node.

Without INVARIANTS:

# uname -a
FreeBSD  15.0-CURRENT FreeBSD 15.0-CURRENT #221
main-n250978-0a0623e9c824-dirty: Tue Feb 27 09:42:26 EST 2024    
rtm@zika:/usr/obj/usr/rtm/symbsd/src/riscv.riscv64/sys/RTM riscv
# mount -t tarfs tarfs2a.tar /mnt
panic: pmap_kextract: No l2
KDB: stack backtrace:
db_trace_self() at db_trace_self
db_trace_self_wrapper() at db_trace_self_wrapper+0x36
kdb_backtrace() at kdb_backtrace+0x2c
vpanic() at vpanic+0x120
panic() at panic+0x26
pmap_kextract() at pmap_kextract+0xfa
free() at free+0x4e
tarfs_free_node() at tarfs_free_node+0x8e
tarfs_free_node() at tarfs_free_node+0x7a
tarfs_alloc_mount() at tarfs_alloc_mount+0x100a
tarfs_mount() at tarfs_mount+0x344
vfs_domount_first() at vfs_domount_first+0x20e
vfs_domount() at vfs_domount+0x278
vfs_donmount() at vfs_donmount+0x89e
sys_nmount() at sys_nmount+0x5a
do_trap_user() at do_trap_user+0x23a
cpu_exception_handler_user() at cpu_exception_handler_user+0x72
--- syscall (378, FreeBSD ELF64, nmount)

With INVARIANTS:

panic: Assertion name != NULL && namelen != 0 failed at
/usr/src/sys/fs/tarfs/tarfs_vfsops.c:299
KDB: stack backtrace:
db_trace_self_wrapper() at db_trace_self_wrapper+0x2b/frame 0xfffffe01255e72c0
vpanic() at vpanic+0x135/frame 0xfffffe01255e73f0
panic() at panic+0x43/frame 0xfffffe01255e7450
tarfs_lookup_path() at tarfs_lookup_path+0x362/frame 0xfffffe01255e74f0
tarfs_alloc_mount() at tarfs_alloc_mount+0x19c3/frame 0xfffffe01255e78d0
tarfs_mount() at tarfs_mount+0x407/frame 0xfffffe01255e7ad0
vfs_domount_first() at vfs_domount_first+0x258/frame 0xfffffe01255e7c10
vfs_domount() at vfs_domount+0x318/frame 0xfffffe01255e7d30
vfs_donmount() at vfs_donmount+0x8dd/frame 0xfffffe01255e7dc0
sys_nmount() at sys_nmount+0x6c/frame 0xfffffe01255e7e00
amd64_syscall() at amd64_syscall+0x153/frame 0xfffffe01255e7f30
fast_syscall_common() at fast_syscall_common+0xf8/frame 0xfffffe01255e7f30
--- syscall (378, FreeBSD ELF64, nmount), rip = 0x25b598c3f23a, rsp =
0x25b59668f6e8, rbp = 0x25b59668fc50 ---

-- 
You are receiving this mail because:
You are the assignee for the bug.