DF-0079 / fix_run.log
================================================================================
DF-0079 โ FIX VALIDATION RUN LOG (single-fix kernel #1)
================================================================================
Test: re-run the SAME PoC (./df0079) on the patched kernel; the
infinite-loop DoS must NOT reproduce โ write() must return in
finite time. Contrast with the unpatched #0 baseline (write hangs
forever, full-system DoS, only reset recovers).
Patched kernel (kern.version):
DragonFly 6.5-DEVELOPMENT #1: Thu Jul 2 15:52:03 UTC 2026
root@dfbsd:/usr/obj/usr/src/sys/X86_64_GENERIC
kernel.stripped sha256 = 7f49550e41a1fba71b19d49f44f4d5f6144e720657a68c4a215b233a04d9b677
(built from /usr/src with fix.diff applied: sys/kern/kern_memio.c:225
u_int c; -> size_t c;)
PoC build (as maxx, uid 1001):
$ cd poc/DF-0079 && sh ./build.sh
BUILD_OK: -rwxr-xr-x 1 maxx maxx 9104 Jul 2 15:58 df0079
BUILD_EXIT=0
================================================================================
Run #1 โ single proc, /dev/null (the original trigger)
================================================================================
[15:58:13] calling ./df0079 (single proc, /dev/null) on PATCHED #1 kernel
DF-0079: triggering /dev/null infinite-loop DoS, 1 procs
DF-0079: pid=856 calling write(fd, 0x1, 2^32)
write returned 4294967296 (unexpected!)
0.00 real 0.00 user 0.00 sys
TRIGGER_EXIT=0
guest status immediately after: UP, responsive, load ~0.1
================================================================================
Run #2 โ single proc, /dev/null (determinism)
================================================================================
DF-0079: triggering /dev/null infinite-loop DoS, 1 procs
DF-0079: pid=915 calling write(fd, 0x1, 2^32)
write returned 4294967296 (unexpected!)
0.00 real 0.00 user 0.00 sys
EXIT=0
================================================================================
Run #3 โ single proc, /dev/null (determinism)
================================================================================
DF-0079: triggering /dev/null infinite-loop DoS, 1 procs
DF-0079: pid=921 calling write(fd, 0x1, 2^32)
write returned 4294967296 (unexpected!)
0.00 real 0.00 user 0.00 sys
EXIT=0
================================================================================
Run #4 โ /dev/zero variant (case 12, same u_int truncation root cause)
================================================================================
DF-0079: triggering /dev/zero infinite-loop DoS, 1 procs
DF-0079: pid=927 calling write(fd, 0x1, 2^32)
write returned 4294967296 (unexpected!)
0.00 real 0.00 user 0.00 sys
EXIT=0
================================================================================
Run #5 โ fork-2 variant (would wedge 2 CPUs on the unpatched kernel)
================================================================================
DF-0079: triggering /dev/null infinite-loop DoS, 2 procs
DF-0079: pid=933 calling write(fd, 0x1, 2^32)
DF-0079: spawned 2 wedged children on /dev/null
write returned 4294967296 (unexpected!)
write returned 4294967296 (unexpected!)
0.00 real 0.00 user 0.00 sys
EXIT=0
(both children returned cleanly; no CPU pegged; guest load ~0.12)
================================================================================
Final guest state after all 5 runs
================================================================================
status: up
Thu Jul 2 15:58:51 UTC 2026
3:58PM up 1 min, 0 users, load averages: 0.12, 0.05, 0.02
(no df0079 processes lingering; no CPU pegged; box fully responsive)
================================================================================
VERDICT: FIXED
================================================================================
On the unpatched #0 kernel: a single `write(/dev/null, 0x1, 2^32)` by uid 1001
pegged one CPU at 100% in-kernel (mmrw) FOREVER; ssh to BOTH maxx and root
was starved within ~1 s (Connection reset / timeout 124); `vm.sh status`
reported `down`; only `vm.sh reset` recovered. Reproduced deterministically.
On the single-fix #1 kernel: the SAME write returns 4294967296 (= 2^32) in
0.00 s real (sub-millisecond), EXIT=0, across 5 runs (single /dev/null x3,
/dev/zero x1, fork-2 x1). Guest stays UP and responsive; load stays ~0.1.
Mechanism of the fix: widening `c` from `u_int` (32-bit) to `size_t` (64-bit)
at sys/kern/kern_memio.c:225 means `c = iov->iov_len` (= 2^32) no longer
truncates to 0. The bookkeeping at :380/382 subtracts the full 2^32, draining
uio_resid to 0 in a single iteration, so the `while (uio_resid > 0)` predicate
at :232 exits and mmrw returns. This closes /dev/null (:298), /dev/zero
(:364) AND /dev/kmem (:264, root-only) in one change. The other in-function
uses of `c` (uiomove/read_random/add_buffer_randomness_src at
:253/:289/:309/:314/:319/:328/:354/:372) all operate on values already
bounded by min(..., PAGE_SIZE), so widening c changes no bounded-path
behaviour โ confirmed by the clean rc=0 build (fix_build.log).
nativekernel build: rc=0, no errors (see fix_build.log, 35510 lines).
kern_memio.o rebuilt at 15:50 (post-patch); mmrw/mmwrite symbols present.
================================================================================