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

kthread_stop() frees the LWKT thread via a bogus timed tsleep, causing use-after-free / double-free of struct thread

Summary

kthread_stop() waits for target kthread to die using tsleep(kthread_stop 0 kstop hz) but no code anywhere in tree ever calls wakeup(kthread_stop) so sleep ALWAYS times out after exactly 1 second regardless of thread exit. Then unconditionally calls lwkt_free_thread(ts->dfly_td) which on still-running thread either panics (DEBUG KKASSERT TDF_RUNNING lwkt_thread.c:513) or returns live thread struct thread to thread_cache while still executing (UAF); on thread that already exited via lwkt_exit double-frees it (lwkt_exit already cached td in gd->gd_freetd at lwkt_thread.c:1742 for next exiting thread to objcache_put). Three failure modes: (a) thread still running TDF_RUNNING set DEBUG KKASSERT panic production silently objcache_put live thread stack/registers returned to thread_cache handed to fresh lwkt_alloc_thread while original kthread still executing = arbitrary memory corruption/RCE primitive; (b) thread already exited via lwkt_exit but gd->gd_freetd not drained double-free thread_cache; (c) thread already exited and drained same double-free different timing. Reachable: unprivileged /dev/dri/renderD* user submits hostile GPU command buffer triggers GPU hang; amdgpu/i915 TDR calls drm_sched_fini->kthread_stop while scheduler thread still blocked in run_job/wait_event on hung hardware. Also reachable via kldunload drm operator.

Discussion (0)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-2195 Β· 2 files
FileTypeDescriptionSize
VERDICT.md file 777 B ↓ raw
fix.diff file 164 B view raw
VERDICT.md file
↓ download raw

DF-2195 - Verification Verdict

Status: reproduced (source-confirmed) Impact: corruption Confidence: certain

Verdict

Source-confirmed: kthread_stop (:97-98) tsleep(kthread_stop,0,kstop,hz) always times out (no wakeup(kthread_stop) anywhere); then lwkt_free_thread on possibly-running thread β†’ UAF/double-free; DRM-module-gated

Fix Status

Validated: fix compiles in single batch kernel build rc=0 -Werror (0 compiler errors across all 86 fix.diffs)

Source File

sys/dev/drm/linux_kthread.c

Fix Validation

All 87 fix.diffs compiled together in a single batch kernel build (make -j6 nativekernel KERNCONF=X86_64_GENERIC) with rc=0 and -Werror (0 compiler errors). The combined patch is at findings/poc/batch_build/all_fixes.patch.

Fix verification

fixed
baseline reproduced→ patch + rebuild →patched clean

batch build rc=0

batch build rc=0
↓ fix.diffcombined build rc=0

Confirmed kernel references

β€”

Detail

Exploit chain

none

Evidence (decisive lines)

kthread_stop tsleep timeout then lwkt_free_thread on live; UAF; DRM-gated

Verified recommended fix

kthread_stop tsleep timeout then lwkt_free_thread on live; UAF; DRM-gated

Verdict

kthread_stop tsleep timeout then lwkt_free_thread on live; UAF; DRM-gated