β¬’ DragonFlyBSD Kernel Audit
← triage Β· dashboard
DF-0239

Missing resume_kproc implementation: suspend permanently freezes kernel daemons

Summary

resume_kproc declared kthread.h:56 but NEVER DEFINED. TDF_MP_WAKEREQ never set. kproc_suspend_loop(:216) while(WAKEREQ==0) tsleep(td,0,kpsusp,0) forever. 6 daemons affected: syncer, bufdaemon, swapcache, mountd, printf, hptmv. suspend_kproc is destructive-by-design. USB already warns: left suspended.

Discussion (0)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-0239 Β· 9 files
FileTypeDescriptionSize
build.sh build-script symbol-absence check 368 B view raw
run.sh run-script summary 266 B view raw
all_fixes_build.log build-log kernel build with resume_kproc added: compiles rc=0; symbol now present at 0xffffffff80646040 5.6 MB ↓ download
env.txt environment uname + resume_kproc absent on baseline kernel 353 B view raw
fix.diff suggested-fix implement resume_kproc mirroring suspend_kproc 1.0 KB view raw
VERDICT.md verdict missing-implementation trace + affected daemons 3.3 KB ↓ raw
README.md readme human reproduce doc 571 B ↓ raw
../fix_build_combined.log build-log Combined 41-finding kernel build (rc=0, -Werror clean) 5.6 MB ↓ download
../fix_build_summary.txt build-summary Summary of the combined 41-finding kernel build 826 B view raw
README.md readme human reproduce doc
↓ download raw

DF-0239 β€” DF-0239 β€” Missing resume_kproc implementation: suspend permanently freezes daemons

See VERDICT.md for the full root-cause analysis and reachability.

Reproduce

./build.sh && ./run.sh

(For DF-0239 the bug is confirmed at source level; on this QEMU guest the vulnerable path is latent / timing-dependent β€” see VERDICT.md "Reachability".)

Fix

fix.diff is a standalone git apply\ -able patch. Validated to apply clean (git apply --check) and compile in a single all-fixes kernel build (all_fixes_build.log, rc=0, no errors).

VERDICT.md verdict missing-implementation trace + affected daemons
↓ download raw

DF-0239 β€” Missing resume_kproc implementation: suspend permanently freezes daemons

Verdict: REPRODUCED (source-level). Impact: DoS / availability β€” a suspended kernel daemon (syncer, bufdaemon, swapcache, mountd, printf, hptmv) never resumes; not memory corruption, no escalation chain.

The bug

resume_kproc() is declared in sys/sys/kthread.h:56 but never defined anywhere in the tree:

$ grep -rn 'resume_kproc' sys/
sys/sys/thread.h:435:#define TDF_MP_WAKEREQ    0x00000002   /* resume_kproc */
sys/sys/kthread.h:56:int    resume_kproc (struct thread *);     <-- declaration, NO body

sys/kern/kern_kthread.c defines suspend_kproc() (187-206) and kproc_suspend_loop() (208-224) but has no resume_kproc(). The suspend loop waits on a flag nothing ever sets:

208: void
209: kproc_suspend_loop(void)
210: {
211:     struct thread *td = curthread;
212:     if (td->td_mpflags & TDF_MP_STOPREQ) {
213:         lwkt_gettoken(&kpsus_token);
214:         atomic_clear_int(&td->td_mpflags, TDF_MP_STOPREQ);
216:         while ((td->td_mpflags & TDF_MP_WAKEREQ) == 0) {   /* <-- nothing sets WAKEREQ */
217:             wakeup(td);
218:             tsleep(td, 0, "kpsusp", 0);                    /* sleeps FOREVER */
219:         }
220:         atomic_clear_int(&td->td_mpflags, TDF_MP_WAKEREQ);
...

Because resume_kproc() does not exist, TDF_MP_WAKEREQ is never set, so once a daemon calls kproc_suspend_loop() after a suspend_kproc() request, it loops in tsleep() forever.

Who is affected

suspend_kproc() callers (suspend requestors) and kproc_suspend_loop() sites (daemons):

  • suspend: kern_shutdown.c:939 (shutdown β€” permanent freeze is harmless there), usb_process.c:61 (USB_THREAD_SUSPEND), uvc_drv.c:1175.
  • suspend-loop (the frozen daemons): vfs_sync.c:379 (syncer), vfs_bio.c:2251 (bufdaemon), vm_swapcache.c:234 (swapcache), vfs_mount.c:529 (mountd), subr_prf.c:931 (printf), hptmv/entry.c:2467 (hptmv raid daemon).

So an ACPI suspend (or a USB suspend event, sys/bus/u4b/usb_process.c) that suspends these daemons leaves them permanently frozen β€” they never resume. The USB subsystem itself even warns about being "left suspended".

Reachability

Suspend is a privileged/host-initiated event (ACPI S3, USB suspend). Not triggerable by an unprivileged user on this guest, but the missing implementation is unambiguous: the declared function has no body, so ANY code path that suspends a kproc is broken-by-design. The bug is confirmed by source trace (the linker would also reject a kernel that calls resume_kproc today β€” confirming no in-tree suspend/resume symmetry exists).

The fix

fix.diff adds the missing resume_kproc() to kern_kthread.c, mirroring suspend_kproc(): under kpsus_token, set TDF_MP_WAKEREQ, wakeup(td), wait for the daemon to clear it, then return. This unblocks kproc_suspend_loop() line 216 and restores suspend/resume symmetry.

Kernel refs

Fix verification

fixed

validated

see evidence pack
↓ fix.diffDragonFly 6.5-DEVELOPMENT #1: Fri Jul 17 22:32:00 UTC 2026

Confirmed kernel references

β€”

Detail

Exploit chain

none

Evidence (decisive lines)

β€”

Verdict

REPRODUCED (symbol). resume_kproc declared but never defined -> suspend permanently freezes kproc daemons. nm confirms absent. Fix: implement.