โฌข DragonFlyBSD Kernel Audit
DF-1157 / fix_validation.txt
โ† back to finding โ†“ download raw
DF-1157 (wpi if_wpi.c) โ€” fix validation (combined nativekernel build)
=====================================================================
Baseline (#0 unpatched):  wpi_rx_done reads head->len (u16, unbounded),
   computes tail=(head+1)+len at if_wpi.c:1969 and dereferences tail->flags
   at :1970 BEFORE the lower-bound check at :1984; m_len=len at :2028.
   => OOB heap read past the 4KB MJUMPAGESIZE cluster + oversized mbuf walk.
   (Source-confirmed; NOT live-triggerable on this guest: no Intel 3945
    wpi adapter. wpi IS compiled into X86_64_GENERIC:272.)

Fix (#1 single-fix kernel, both wpi+nata fixes applied together):
   cd /usr/src && patch -p1 --forward < /root/df1157.diff   -> Hunk #1 @1966 OK
   make -j6 nativekernel KERNCONF=X86_64_GENERIC            -> NK_DONE rc=0
   if_wpi.o compiled clean under -Werror.
   cp kernel.stripped /boot/kernel/kernel ; boot
   kern.version = DragonFly 6.5-DEVELOPMENT #1: Fri Jul 17 06:10:36 UTC 2026

Before/after marker:
   BEFORE (#0): no upper bound on head->len; tail deref OOB reachable.
   AFTER  (#1): the bound check
       if ((head+1) + len + sizeof(wpi_rx_tail) > mtod(data->m) + MJUMPAGESIZE)
           goto fail1;
     is compiled in (UNCONDITIONAL โ€” not under WPI_DEBUG).  The "frame too long"
     debug string is absent from the binary only because DPRINTF is a no-op
     unless WPI_DEBUG is defined (if_wpi_debug.h:25,141); the protection itself
     (the if/goto) is always active.

fix_status: not_testable (runtime) โ€” no wpi adapter on this guest to drive the
   RX path. Validated at apply + compile + boot level: the guard is compiled
   into the booted #1 kernel and provably bounds head->len so (head+1)+len+tail
   never exceeds the 4KB cluster, eliminating the tail-deref OOB and the
   oversized m_len.