acpi_asus_detach removes the wrong ACPI notify handler: installed handler survives detach and fires into freed/unloaded driver state (use-after-free)
Summary
attach installs sc->model->n_func (acpi_asus_eeepc_notify for the EeePC model) but detach removes hardcoded acpi_asus_notify - ACPICA removal matches the triple so it fails with an ignored error and the real handler stays registered. After the softc is freed, the next firmware notify runs the EeePC handler over freed memory (UAF read/write) or into unmapped module text after kldunload. Record-and-remove-the-installed-handler fix.
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-4409 Β· 5 files| File | Type | Description | Size | |
|---|---|---|---|---|
| README.md | β | 2.4 KB | β raw | |
| VERDICT.md | β | 2.4 KB | β raw | |
| env.txt | β | 1.9 KB | view raw | |
| fix.diff | β | 1.3 KB | view raw | |
| verdict.json | β | 2.5 KB | view raw |
DF-4409 β acpi_asus detach removes the wrong notify handler: installed handler survives and keeps firing into freed/unloaded driver state (use-after-free)
- File:
sys/dev/acpica/acpi_asus/acpi_asus.c(pass 2) - Class: CWE-416 (use after free) / CWE-666 (mismatched removal)
- Severity: Low β trigger requires root-initiated device detach or module unload while an ACPI notify fires (hotkey press on an EeePC/ASUS laptop); no unprivileged path to the detach itself.
Defect (path:line)
attach (acpi_asus.c:807-811):
if (sc->model->n_func == NULL)
sc->model->n_func = acpi_asus_notify;
AcpiInstallNotifyHandler(sc->handle, ACPI_SYSTEM_NOTIFY,
sc->model->n_func, dev); /* installs acpi_asus_eeepc_notify
for the EeePC model */
detach (acpi_asus.c:859-861):
/* Remove notify handler */
AcpiRemoveNotifyHandler(sc->handle, ACPI_SYSTEM_NOTIFY,
acpi_asus_notify); /* removes a DIFFERENT handler */
AcpiRemoveNotifyHandler matches on the (device, type, handler) triple.
For the EeePC model (acpi_eeepc_models[0].n_func = acpi_asus_eeepc_notify,
acpi_asus.c:455) the removal fails with AE_BAD_PARAMETER, which is
ignored. After detach completes:
- the newbus softc (context
dev/sc) is freed β the still-installed handler'scontextnow dangles; the next ACPI notify runsacpi_asus_eeepc_notifyβdevice_get_softc((device_t)context)(acpi_asus.c:1268) β use-after-free read/write of freed memory, under whatever now occupies the softc slot; - if the module was also unloaded (
kldunload acpi_asus), the handler address itself points into unmapped text β control-flow into freed kernel memory.
Secondary correctness note: even for non-EeePC models the pattern works only
by accident because attach overwrote the static table's n_func with
acpi_asus_notify (see DF-4411 β mutating acpi_asus_models[]/acpi_eeepc_models[]).
Build / run
Not runnable on the audit guest: no ATK0100/ASUS010 ACPI nodes (see
env.txt), so acpi_asus never attaches; kldunload/devctl detach requires
root. On matching hardware the PoC would be: kldunload acpi_asus (or devctl
detach) immediately followed by hotkey presses β panic in
acpi_asus_eeepc_notify or acpi_asus_notify.
Recommended fix
Remember the handler actually installed and remove exactly that β see
fix.diff.
DF-4409 VERDICT β untested (source-verified use-after-free; root-gated, firmware-gated)
Reproduced?
No. Status untested: requires (a) an ASUS/Samsung/EeePC laptop whose ACPI
exposes ATK0100/ASUS010 (the audit guest has none β verified live, env.txt)
and (b) a root-initiated detach / kldunload acpi_asus racing a firmware
notify. No unprivileged trigger.
Defect (certain from source)
- attach installs
sc->model->n_funcas theACPI_SYSTEM_NOTIFYhandler withdevas context (acpi_asus.c:810-811). For the EeePC model that isacpi_asus_eeepc_notify(acpi_asus.c:455, table entry "EEE"). - detach removes
acpi_asus_notifyβ a different function pointer (acpi_asus.c:860-861). ACPICA removes handlers by the (device, handler-type, handler) triple, so the call returnsAE_BAD_PARAMETERand the installed handler remains registered; the ignored return value hides this. - After
acpi_asus_detachreturns, newbus frees the softc. The surviving handler's next invocation (any hotkey/notify event) executesacpi_asus_eeepc_notify(acpi_asus.c:1261-1281):sc = device_get_softc((device_t)context)on freed memory, thenacpi_device_get_parent_softc(sc->dev)andacpi_asus_sysctl_set(sc, ...)writingsc->s_brnβ use-after-free read/write. With the module also unloaded, the handler text itself is gone β control transfer into unmapped memory. - Window: not merely theoretical β ACPI notifies are asynchronous EC events (lid/hotkey), and detach of a laptop-extra driver under an active ACPI namespace receives events routinely.
Impact ceiling
Root-gated panic / kernel memory corruption in freed softc (attacker needs root to detach; the freed-slot reuse is not attacker-shaped). DoS-class in practice; the UAF class justifies a memcorrupt-bucket filing for upstream correctness, but it is not an escalation primitive.
Fix
fix.diff: store the handler that was installed (sc->n_func) and remove
exactly that in detach. Also stops attach from writing into the shared
static model table (see DF-4411). Not validated on hardware
(fix_status: not_testable).
Fix status (batch validation)
Applied with the 36 sibling fix.diffs of this batch in findings/poc/_batch41/all_fixes.patch; single in-guest make -j6 nativekernel KERNCONF=X86_64_GENERIC completed RC=0 with zero errors under -Werror (full log: findings/poc/_batch41/fix_build8.log). Behavior A/B intentionally skipped for this Info-tier item.
Fix verification
not_testablefix.diff authored from source analysis; cannot be validated on the audit guest - acpi_asus only attaches on ATK0100/ASUS010 firmware, absent from the guest namespace.
findings/poc/DF-4409/fix.diff; env.txt
Confirmed kernel references
Detail
Exploit chain
root: kldunload acpi_asus (or devctl detach) while firmware notify pending -> handler survives removal -> notify fires into freed softc (UAF) / unmapped text. No unprivileged chain.
Evidence (decisive lines)
findings/poc/DF-4409/VERDICT.md (path:line trace), README.md, env.txt, fix.diff
Verified recommended fix
Record the installed handler in the softc (sc->n_func) and pass it to AcpiRemoveNotifyHandler verbatim in detach; see fix.diff.
Verdict
Source-verified use-after-free: acpi_asus_attach installs sc->model->n_func (= acpi_asus_eeepc_notify on EeePC, acpi_asus.c:455,810-811) with dev as context, but acpi_asus_detach removes hardcoded acpi_asus_notify (acpi_asus.c:860-861). ACPICA removal matches the (device,type,handler) triple, so it fails with an ignored AE_BAD_PARAMETER and the real handler survives detach. The next ACPI notify then runs acpi_asus_eeepc_notify over the freed softc (device_get_softc(context), acpi_asus.c:1268) - UAF read/write - or jumps into unloaded module text after kldunload. Untested at runtime: audit guest has zero ATK0100/ASUS010 ACPI nodes (env.txt) and the detach must be root-initiated, so no unprivileged trigger exists; practical ceiling is root-gated panic/corruption of freed softc memory.
No comments yet.