DF-2368 / verdict.json
{ "finding_id": "DF-2368", "status": "reproduced", "reproduced": 1, "impact": "panic", "confidence": "certain", "verdict": "Both halves reproduced on the stock INVARIANTS guest through the real kernel API via a kernel-compiled sysctl rig. (1) rijndael_set_key with keyBits outside 128/192/256 panics at the KASSERT in rijndaelKeySetupEnc (rijndael-alg-fst.c:738) - the only validation present; on production INVARIANTS-free kernels that assert compiles out and the function returns 0, so rijndael_set_key stores Nr=0 with a partially written schedule. (2) With the Nr=0 state the rijndaelEncrypt round loop (r = Nr>>1 = 0, break test on --r) never terminates and walked rk forward 32 bytes per iteration, reading 4128 bytes past the end of the 488-byte rijndael_ctx before a fatal kernel-mode read fault inside rijndaelEncrypt+0x1d9 - exactly the claimed OOB runaway. Not unprivileged-reachable today: all in-tree callers pre-validate key size (wlan_ccmp 16 bytes, cryptoapi 128/192/256, rijndael_makeKey), so this is a latent kernel-DoS landmine at the KPI boundary as filed (Low). Privesc closed: the loop performs OOB reads only, no write primitive, no data returned to userspace - no escalation chain. Fix validated A/B on the same guest: invalid sizes rejected with zeroed schedules, Nr=0 encrypts return immediately, and all 16 FIPS-197/SP800-38A KATs bit-identical.", "exploit_chain": "", "evidence": "panic.setkey0.txt (panic: Invalid key size (0) with rijndael_set_key -> rijndaelKeySetupEnc backtrace); panic.poison.txt and panic.direct.txt (Fatal trap 12 page fault while in kernel mode, fault VA 0x800475000 = 4128 bytes past the ctx, Stopped at rijndaelEncrypt+0x1d9 xorl -0x8(%rdi),%ecx); kat_baseline_dmesg.txt (16/16 KAT control); fixrun_dmesg.txt (fixed kernel A/B: setkey 0/1/127/257 rejected, poison/direct SURVIVED, 16/16 KAT identical); fix.diff; build_baseline.log/build_fixed.log", "kernel_refs": [ "sys/crypto/rijndael/rijndael-alg-fst.c:734", "sys/crypto/rijndael/rijndael-alg-fst.c:738", "sys/crypto/rijndael/rijndael-alg-fst.c:814", "sys/crypto/rijndael/rijndael-alg-fst.c:862", "sys/crypto/rijndael/rijndael-alg-fst.c:951", "sys/crypto/rijndael/rijndael-alg-fst.c:978", "sys/crypto/rijndael/rijndael-alg-fst.c:979", "sys/crypto/rijndael/rijndael-api.c:37", "sys/crypto/rijndael/rijndael-api.c:41", "sys/crypto/cryptoapi/cryptoapi.c:305", "sys/crypto/cryptoapi/cryptoapi.c:399", "sys/netproto/802_11/wlan_ccmp/ieee80211_crypto_ccmp.c:130" ], "poc_changes": "Original filing had no runnable PoC (poc_path null). Rig authored from scratch: kernel-compiled sysctl harness because runtime kldload GPFs on this guest; make buildkernel fails on this snapshot without buildworld so the documented nativekernel path was used; three compile iterations were needed (Werror sequence-point on index logging, kernel __va_list instead of va_list).", "attempts": 3, "guest_uname": "DragonFly dfbsd 6.5-DEVELOPMENT DragonFly 6.5-DEVELOPMENT #1: Mon Oct 19 02:17:08 UTC 2026 root@dfbsd:/usr/obj/usr/src/sys/X86_64_GENERIC x86_64", "runtime_sec": 2280, "guest_dirty": 0, "build_cmd": "cd /root/rig && sh build.sh (installs rig into /usr/src, make -j6 nativekernel KERNCONF=X86_64_GENERIC, make installkernel, cc -O -o /root/rijnh rijnh.c)", "run_cmd": "/root/rijnh setkey 0 ; /root/rijnh poison ; /root/rijnh direct ; /root/rijnh kat", "code_hash": "1bcb06fab7f0552321352a960a146d4d301c0e9475dc31608ba41f0af45e5f2a", "notes": "Recover from each panic with vm.sh reset harness-kernel (snapshot taken right after rig-kernel install). Fixed-kernel snapshot kept as fixed-kernel. Guest returned to pristine with-src snapshot at the end. Privesc assessment: closed - read-only OOB walk, terminal fatal trap, no write primitive.", "recommended_fix": "Runtime keyBits validation returning -1 in rijndaelKeySetupEnc/Dec plus rejection (Nr=0, zeroed schedules) in rijndael_set_key and an Nr sanity guard in rijndaelEncrypt/rijndaelDecrypt, exactly as in fix.diff" } |