[Bug 273133] corrupt cd9660 disk can overflow cd9660_lookup()'s altname[] buffer

From: <bugzilla-noreply_at_freebsd.org>
Date: Mon, 14 Aug 2023 12:09:41 UTC
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=273133

            Bug ID: 273133
           Summary: corrupt cd9660 disk can overflow cd9660_lookup()'s
                    altname[] buffer
           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 244094
  --> https://bugs.freebsd.org/bugzilla/attachment.cgi?id=244094&action=edit
cd9660 image that causes a buffer overflow in cd9660_lookup()

I've attached a cd image that causes a kernel stack buffer overflow:

# gunzip cd5a.iso.gz
# mdconfig cd5a.iso
# mount_cd9660 /dev/md0 /mnt
# ls -l /mnt/x
panic: stack overflow detected; backtrace may be corrupted
panic() at panic+0x26
__stack_chk_fail() at __stack_chk_fail+0x14
cd9660_lookup() at cd9660_lookup+0x684
VOP_CACHEDLOOKUP_APV() at VOP_CACHEDLOOKUP_APV+0x32
VOP_CACHEDLOOKUP() at VOP_CACHEDLOOKUP+0x2a
vfs_cache_lookup() at vfs_cache_lookup+0x8c
VOP_LOOKUP_APV() at VOP_LOOKUP_APV+0x32
VOP_LOOKUP() at VOP_LOOKUP+0x2a
vfs_lookup() at vfs_lookup+0x318
namei() at namei+0x198
kern_statat() at kern_statat+0xb6
sys_fstatat() at sys_fstatat+0x1c
syscallenter() at syscallenter+0xe0
ecall_handler() at ecall_handler+0x18
do_trap_user() at do_trap_user+0xf2
cpu_exception_handler_user() at cpu_exception_handler_user+0x72
--- syscall (552, FreeBSD ELF64, fstatat)

What seems to be happening is that cd9660_lookup() passes
altname[NAME_MAX=255] to cd9660_rrip_getname(), which calls
cd9660_rrip_loop(), which ends up calling both cd9660_rrip_altname()
and cd9660_rrip_defname(). The call to altname memcpy's wlen=250 bytes
into ana->outbuf (== altname), increases ana->outbuf by 250, but then
returns 0:

        memcpy(ana->outbuf, inbuf, wlen);
        ana->outbuf += wlen;

        if (!cont) {
            ...;
        }
        return 0;

The return 0 causes cd9660_rrip_loop() to call cd9660_rrip_defname(),
which calls isofntrans(), which copies 53 bytes into ana->outbuf, even
though there are only 5 byte of space left.

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