{
  "finding_id": "DF-2845",
  "status": "reproduced",
  "reproduced": 1,
  "impact": "panic",
  "confidence": "certain",
  "verdict": "sbuf_drain() (sys/kern/subr_sbuf.c:324-351) validates the drain callback's return only with a KASSERT (:336-337) that is compiled out of production kernels. Demonstrated on a purpose-built no-INVARIANTS DragonFly kernel: a drain returning 0 ('consumed nothing, no error') let sbuf_put_byte() write 224 bytes past a 32-byte FIXEDLEN sbuf allocation (s_len=255 vs s_size=32) while sbuf_cat() returned 0 with s_error=0 - a silent, unbounded, content-controlled linear kernel-heap overflow. On an INVARIANTS kernel the same trigger panics 'Bad drain amount 0 for sbuf' with stack sbuf_cat->sbuf_put_byte->sbuf_drain. No in-tree drain misbehaves (sbuf_sysctl_drain returns len or -error) and installing one requires root (KLD/custom kernel), so there is no unprivileged uid0 route today - this is a hardening gap whose failure mode is full kernel heap corruption for any future or 3rd-party drain regression. fix.diff adds a runtime check (len==0 || len>s_len -> s_error=EDOOFUS) and was validated in-guest: identical trigger on the patched no-INVARIANTS kernel stays in-bounds (s_len=31) and propagates rc=-1/EDOOFUS.",
  "exploit_chain": "Trigger chain (root-gated): kldload (or compile in) a drain callback that returns 0 on a sbuf used for formatting -> every appended byte past s_size-1 lands beyond the heap allocation with attacker-influenced content, no error signaled. No unprivileged in-tree path to a misbehaving drain exists, so no uid0 chain; ceiling is kernel-heap corruption primitive behind a root-loaded/future-buggy drain.",
  "evidence": [
    "run.log: 'DF2845: [4] sbuf_cat rc=0 s_error=0 s_len=255 s_size=32' + 'OVERFLOW CONFIRMED: 224 byte(s) written past the end of the 32-byte heap allocation' (unpatched no-INVARIANTS kernel; 224 drain calls each returning 0)",
    "panic.txt: 'panic: Bad drain amount 0 for sbuf 0xfffff80117a49380' with stack sbuf_drain<-sbuf_put_byte<-sbuf_cat<-df2845_sysctl (unpatched INVARIANTS kernel)",
    "run.2.log: 'DF2845: [4] sbuf_cat rc=-1 s_error=88 s_len=31 s_size=32' + 'BLOCKED' (patched no-INVARIANTS kernel, fix.diff applied)",
    "build.log: three in-guest nativekernel builds (no-INVARIANTS baseline, patched, INVARIANTS) and the KLD variant build"
  ],
  "kernel_refs": [
    "sys/kern/subr_sbuf.c:331",
    "sys/kern/subr_sbuf.c:336",
    "sys/kern/subr_sbuf.c:338",
    "sys/kern/subr_sbuf.c:349",
    "sys/kern/subr_sbuf.c:367",
    "sys/kern/subr_sbuf.c:379",
    "sys/kern/kern_sysctl.c:1616",
    "sys/kern/kern_sysctl.c:1631",
    "sys/sys/sbuf.h:81"
  ],
  "poc_changes": "Original sketch planned a KLD trigger; kldload of any freshly-built module crashes this snapshot's prebuilt kernel (GCC 8.3 toolchain vs Jul-2026 kernel; minimal hello-world KLD crashes identically at strcmp+0x10 in the loader before MOD_LOAD). Same test body was compiled into custom kernels via sys/conf/files + debug.df2845_trigger sysctl (df2845_test.c).",
  "attempts": 6,
  "guest_uname": "DragonFly dfbsd 6.5-DEVELOPMENT DragonFly 6.5-DEVELOPMENT #0: Wed Sep  2 07:44:03 UTC 2026     root@dfbsd:/usr/obj/usr/src/sys/DF2845_NOINV  x86_64",
  "runtime_sec": 2820,
  "guest_dirty": 0,
  "build_cmd": "in-guest: make nativekernel KERNCONF=DF2845_NOINV -j6 (trigger compiled in via kern/df2845_test.c + sys/conf/files)",
  "run_cmd": "sysctl debug.df2845_trigger=1",
  "code_hash": "6b0655f63ea45fcd202cbcc2c393db3401c47d6b72e1e125583bda6d366b516d",
  "notes": "Impact field mapped to 'panic' per the status table (INVARIANTS run: ssh died, guest wedged in ddb after panic); the more important result is the SILENT 224-byte heap overflow on the production-style kernel with sbuf_cat returning success. Guest was reset to with-src snapshot after verification (guest_dirty=0). fix_kernel_uname below is the patched no-INVARIANTS kernel #1 07:54:44 build.",
  "recommended_fix": "Replace the sbuf_drain() KASSERT with a runtime check: if (len == 0 || len > s->s_len) { s->s_error = EDOOFUS; return (s->s_error); }",
  "fix_status": "fixed",
  "fix_kernel_uname": "DragonFly dfbsd 6.5-DEVELOPMENT #1: Wed Sep  2 07:54:44 UTC 2026 root@dfbsd:/usr/obj/usr/src/sys/DF2845_NOINV (fix.diff applied) x86_64",
  "fix_baseline_reproduced": 1,
  "fix_patched_reproduced": 0,
  "fix_verdict": "Patched kernel: identical trigger leaves s_len=31/s_size=32 (in-bounds), sets s_error=EDOOFUS(88), sbuf_cat returns -1, zero OOB bytes. Baseline (same config, unpatched) overflowed by 224 bytes silently. Bad behavior gone.",
  "fix_evidence": [
    "run.2.log: 'DF2845: [4] sbuf_cat rc=-1 s_error=88 s_len=31 s_size=32 ... BLOCKED'",
    "fix.diff: runtime validation replacing KASSERT at sys/kern/subr_sbuf.c:336"
  ]
}
