Bug 272840 - too-large root_icb.len on UDF file system causes crash
Summary: too-large root_icb.len on UDF file system causes crash
Status: Open
Alias: None
Product: Base System
Classification: Unclassified
Component: kern (show other bugs)
Version: CURRENT
Hardware: Any Any
: --- Affects Some People
Assignee: freebsd-bugs (Nobody)
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2023-07-31 11:13 UTC by Robert Morris
Modified: 2023-08-02 23:24 UTC (History)
2 users (show)

See Also:


Attachments
gzipped UDF image that causes a kernel crash when mounted (22.90 KB, application/octet-stream)
2023-07-31 11:14 UTC, Robert Morris
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Robert Morris 2023-07-31 11:13:13 UTC
The attached corrupt UDF image claims a root directory file entry
length of root_icb.len=64650 (one might expect 2048). During mount,
udf_readdevblks() rounds this up to 65536, and this line in getblkx()
increases it to 67584:

                        maxsize = size + (offset & PAGE_MASK);

getnewbuf_kva() further increases the size to 81920.

On an INVARIANTS kernel, this KASSERT fails in bufkva_alloc():

        KASSERT(maxsize <= maxbcachebuf,
            ("bufkva_alloc kva too large %d %u", maxsize, maxbcachebuf));

        panic: bufkva_alloc kva too large 81920 65536

On a non-INVARIANTS CURRENT kernel, this leads to a kernel page fault
during unmount. On a stock 13.1 kernel, nothing bad happens right away
but eventually file system problems arise.

Here's the back-trace on an INVARIANTS kernel:

# mdconfig -f udf4a.iso
# mount_udf /dev/md0 /mnt
panic: bufkva_alloc kva too large 81920 65536
panic() at panic+0x26
bufkva_alloc() at bufkva_alloc+0x104
getnewbuf_kva() at getnewbuf_kva+0x2a
getnewbuf() at getnewbuf+0xec
getblkx() at getblkx+0x188
breadn_flags() at breadn_flags+0x56
udf_readdevblks() at udf_readdevblks+0x52
udf_mountfs() at udf_mountfs+0x574
udf_mount() at udf_mount+0x19c
vfs_domount_first() at vfs_domount_first+0x1cc
vfs_domount() at vfs_domount+0x26c
vfs_donmount() at vfs_donmount+0x82c
sys_nmount() at sys_nmount+0x5e
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 (378, FreeBSD ELF64, nmount)
Comment 1 Robert Morris 2023-07-31 11:14:18 UTC
Created attachment 243731 [details]
gzipped UDF image that causes a kernel crash when mounted
Comment 2 Robert Morris 2023-07-31 11:41:11 UTC
This in udf_mountfs() ought to set "error":

        if (size < UDF_FENTRY_SIZE) {
          printf("Invalid root directory file entry length %u\n",
                 size);
          goto bail;
        }