https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=287802

            Bug ID: 287802
           Summary: udf_getfid can bcopy off the end of the destination
           Product: Base System
           Version: CURRENT
          Hardware: Any
                OS: Any
            Status: New
          Severity: Affects Some People
          Priority: ---
         Component: kern
          Assignee: [email protected]
          Reporter: [email protected]

In udf_getfid(), it's possible for frag_size to be negative,
interpreted by bcopy as a huge unsigned:

                frag_size = ds->size - ds->off;
                ...
                bcopy(fid, ds->buf, frag_size);

because ds->size can be zero but ds->off non-zero, from a previous
udf_getfid()'s call to

                /* Fetch the next allocation */
                ds->offset += ds->size;
                ds->size = 0;
                error = udf_readatoffset(ds->node, &ds->size, ds->offset,
                    &ds->bp, &ds->data);

Here's a demo with a corrupt UDF image:

# uname -a
FreeBSD xxx 15.0-CURRENT FreeBSD 15.0-CURRENT #29
main-n275520-a78ba87dd019-dirty: Fri May 23 17:52:21 AST 2025    
root@stock14:/usr/obj/usr/src/amd64.amd64/sys/GENERIC amd64
# fetch http://www.rtmrtm.org/rtm/udf53a.iso
# mdconfig -f udf53a.iso
# mount_udf /dev/md0 /mnt
# ls -l /mnt
panic: vm_fault_lookup: fault on nofault entry, addr: 0xfffffe0126fff000

A gdb backtrace:

#0  memcpy (dst0=0xffffffc09e3fa800, src0=0xffffffd001b302d8, 
    length=18446744073709551576) at /usr/rtm/symbsd/src/sys/libkern/bcopy.c:70
#1  0xffffffc000387f6a in udf_getfid (ds=0xffffffd014b6d3a8)
    at /usr/rtm/symbsd/src/sys/fs/udf/udf_vnops.c:702
#2  0xffffffc0003878b4 in udf_readdir (a=0xffffffc082cdeab0)
    at /usr/rtm/symbsd/src/sys/fs/udf/udf_vnops.c:817

(gdb) print *ds
$35 = {node = 0xffffffd014b367f8, udfmp = 0xffffffd001b15d00, bp = 0x0, 
  data = 0xffffffd001b302b0 "\001\001(\b\225\002\005\004\200", 
  buf = 0xffffffc09e3fa800 "", fsize = 2080, off = 40, this_off = 320, 
  offset = 160, size = 0, error = 0, fid_fragment = 0}
(gdb) print frag_size
$34 = -40

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

Reply via email to