# DF-5150 — acpi_lid has no device_detach: ACPI notify handler (context = softc) and PRW wake GPE are never removed (DF-5091 mirror)

**File:** `sys/dev/acpica/acpi_lid.c` (pass 2)
**Severity:** Low (structural; no reachable teardown path today) · **Confidence:** certain
**Status:** not_reproduced (runtime) — see `verdict.json` / `VERDICT.md`

## What

`acpi_lid_attach()` installs an ACPICA notify handler with `context = sc`
(`AcpiInstallNotifyHandler(sc->lid_handle, ACPI_DEVICE_NOTIFY,
acpi_lid_notify_handler, sc)`, sys/dev/acpica/acpi_lid.c:121-122), enables
the PRW wake GPE (acpi_lid.c:126-127), and the driver has **no
`device_detach`** (methods table at acpi_lid.c:66-74). The handler defers
`sc` into `AcpiOsExecute()` (acpi_lid.c:194-195).

## Why it matters

Exactly the DF-5091 (acpi_button) / DF-5074 (acpi_acad) / DF-5006 (acpi_cpu)
family: the handler holds a raw softc pointer forever, pinning the driver;
if a detach path is ever added (or ACPICA teardown ever runs), lid notify →
`acpi_lid_notify_handler` → queued `acpi_lid_notify_status_changed(sc)`
fires after the softc is freed → UAF with firmware-influenced timing.
Today it is structurally non-UAF: unloading the builtin acpi code is
impossible and a module build aborts at the missing child detach.

## Build / Run / Expected

```sh
./build.sh          # nothing to build (structural finding; sh -n syntax check)
./run.sh            # runs trigger.sh as root on the QEMU guest
```

Expected (see `run.log`): `acpi/acpi_lid` driver registered in the builtin
kernel (kldstat -v id 274); **no** acpi_lid device instance (dmesg empty);
**zero** PNP0C0D entries in the QEMU DSDT (acpidump) — the firmware
declares no lid, so the handler is never even installed on this guest;
`kldunload acpi` → "can't find file"; guest stays up.

## Fix

`fix.diff` — add `acpi_lid_detach()` mirroring attach (remove the notify
handler, disable the wake GPE) and register `DEVMETHOD(device_detach, …)`.
`git apply --check` clean against `sys/` (not applied).

## Artifacts

`trigger.sh` `build.sh` `run.sh` `build.log` `run.log` `env.txt` `fix.diff`
`manifest.json` `verdict.json` `VERDICT.md`
