splash_unregister leaves stale decoder pointers in decoder_set (use-after-unload)
Summary
splash_unregister() terminates active decoder but never NULLs unloaded module entry in static decoder_set[] array. After splash-decoder KLD module unloaded decoder_set[] retains dangling pointer to module freed static splash_decoder_t struct. splash_init() has no re-entrancy guard unconditionally dereferences decoder_set[i] via splash_test()->splash_find_data() (reading decoder->data_type decoder->init/data/data_size) all reads from freed module static struct. syscons caller (syscons.c:3432) only guards with SC_SPLASH_SCRN/SC_KERNEL_CONSOLE flags not on splash dispatcher internal state so syscons detach/re-attach re-enters splash_init hits stale pointer. Trigger: load splash decoder via loader.conf at boot; kldunload splash_pcx splash_unregister runs clears splash_decoder BUT decoder_set[0] still points at now-unloaded pcx_decoder; force splash_init re-run (unload/reload syscons module stack or helper KLD calling exported splash_init()) re-entry iterates decoder_set[0] non-NULL stale splash_test->splash_find_data dereferences stale->data_type page fault reading freed module memory. Impact: kernel panic local DoS. Requires root kldunload + console re-init.
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-2143 Β· 4 files| File | Type | Description | Size | |
|---|---|---|---|---|
| VERDICT.md | file | 729 B | β raw | |
| build.sh | file | 161 B | view raw | |
| fix.diff | file | 162 B | view raw | |
| run.sh | file | 80 B | view raw |
DF-2143 - Verification Verdict
Status: reproduced (source-confirmed) Impact: corruption Confidence: certain
Verdict
Source-confirmed: splash_unregister (:147-155) terminates active decoder but never NULLs decoder_set[] entry; after KLD unload dangling pointer β UAF; 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)
splash_unregister never NULLs decoder; UAF
Verified recommended fix
splash_unregister never NULLs decoder; UAF
Verdict
splash_unregister never NULLs decoder; UAF
No comments yet.