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)
PoC verification
Evidence pack
findings/poc/DF-2195 Β· 2 files| File | Type | Description | Size | |
|---|---|---|---|---|
| VERDICT.md | file | 777 B | β raw | |
| fix.diff | file | 164 B | view 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
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
fixedbatch build rc=0
batch 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
No comments yet.