DragonFlyBSD Kernel Audit
DF-0831 / fix_run.log
← back to finding ↓ download raw
== DF-0831 FIX VALIDATION (patched udf.ko, single-fix module) ==
Kernel: DragonFly 6.5-DEVELOPMENT #0 GENERIC, INVARIANTS ON, with fix.diff
        applied to sys/vfs/udf/udf_vnops.c and udf.ko rebuilt + kldloaded.

# cc patch = add at udf_vnops.c:552:
#       if (frag_size < 0)
#           frag_size = 0;
# (clamps the negative frag_size before the int->size_t bcopy length promotion)

Same PoC (crafted multi-extent UDF image + readdir) that PANICS on the
unpatched kernel now runs cleanly:

$ mount_udf -o ro /dev/vn0 /mnt   &&   ls -la /mnt   (as maxx / root)
VN_OK
MOUNT_OK
=== readdir (getdents) probe ===
  entry: d_ino=1 d_type=4 name='.'     <- FID_A parent
  entry: d_ino=1 d_type=4 name='..'    <- FID_A parent
  entry: d_ino=4 d_type=0 name='AB'    <- FID_B (the non-aligned FID that overshoots)
  entry: d_ino=5 d_type=0 name='X'     <- FID_C (terminal, read from extent 1)
readdir total=4 errno=0
guest uptime: 3:24AM up 11 mins

== BEFORE/AFTER ==
UNPATCHED (#0 baseline):  mount + ls  ->  Fatal trap 12 page fault in
                           memmove+0x24f <- udf_readdir  (bcopy size_t(-3))
                           [guest dead at db>]
PATCHED   (fix.diff):      mount + ls  ->  4 dirents returned, errno=0,
                           NO panic, guest stays up.
=> fix closes the bug. (ls -l "Cannot allocate memory" on AB/X is unrelated:
   those file inodes (lb_num 4/5) have no File Entry in this minimal image, so
   udf_vget returns ENOMEM on stat -- a property of the tiny test image, not
   the readdir path, which is clean.)