[Bug 277420] write outside of buffer in tarfs_alloc_one() due to unchecked len

From: <bugzilla-noreply_at_freebsd.org>
Date: Fri, 01 Mar 2024 18:16:27 UTC
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=277420

            Bug ID: 277420
           Summary: write outside of buffer in tarfs_alloc_one() due to
                    unchecked len
           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 248855
  --> https://bugs.freebsd.org/bugzilla/attachment.cgi?id=248855&action=edit
image that causes tarfs_alloc_one() to write outside of a buffer

This sequence in tarfs_alloc_one():

                        size_t len = strtoul(line, &sep, 10);
                        ...
                        if (line + len > exthdr + sz) {
                                TARFS_DPF(ALLOC, "%s: exthdr overflow\n",
                                    __func__);
                                error = EINVAL;
                                goto bad;
                        }
                        eol = line + len - 1;
                        *eol = '\0';

Can cause the *eol assignment to write outside of the buffer if the
length in the tar file is huge enough that line + len wraps, e.g.
0xffffffffffffffff.

I've attached a demo image. It causes a redzone error on my machine with
patches D44161 and D44166.

# uname -a
FreeBSD  15.0-CURRENT FreeBSD 15.0-CURRENT #248
main-n250978-0a0623e9c824-dirty: Fri Mar  1 12:38:44 EST 2024    
rtm@zika:/usr/obj/usr/rtm/symbsd/src/riscv.riscv64/sys/RTM riscv
# mount -t tarfs tarfs11b.img /mnt
REDZONE: Buffer underflow detected. 1 byte corrupted before 0xffffffd007bd9580
(7 bytes allocated).
Allocation backtrace:
#0 0xffffffc000660432 at redzone_setup+0xac
#1 0xffffffc000315a5c at malloc+0xa6
#2 0xffffffc00027220c at tarfs_alloc_mount+0xa96
#3 0xffffffc0002710fc at tarfs_mount+0x584
#4 0xffffffc000404a10 at vfs_domount_first+0x20e
#5 0xffffffc000401360 at vfs_domount+0x278
#6 0xffffffc0003ffe58 at vfs_donmount+0x89e
#7 0xffffffc0003ff588 at sys_nmount+0x5a
#8 0xffffffc0006c15f2 at do_trap_user+0x23a
#9 0xffffffc0006b0132 at cpu_exception_handler_user+0x72
Free backtrace:
#0 0xffffffc0006606b0 at redzone_check+0x1f8
#1 0xffffffc000316130 at free+0x48
#2 0xffffffc0002729fe at tarfs_alloc_mount+0x1288
#3 0xffffffc0002710fc at tarfs_mount+0x584
#4 0xffffffc000404a10 at vfs_domount_first+0x20e
#5 0xffffffc000401360 at vfs_domount+0x278
#6 0xffffffc0003ffe58 at vfs_donmount+0x89e
#7 0xffffffc0003ff588 at sys_nmount+0x5a
#8 0xffffffc0006c15f2 at do_trap_user+0x23a
#9 0xffffffc0006b0132 at cpu_exception_handler_user+0x72
panic: Stopping here.
panic() at panic+0x26
redzone_check() at redzone_check+0x382
free() at free+0x48
tarfs_alloc_mount() at tarfs_alloc_mount+0x1288
tarfs_mount() at tarfs_mount+0x584
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)

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