# DF-2383 — UAF of softc in acpi_hp_notify vs. acpi_hp_detach

**File:** `sys/dev/acpica/acpi_hp/acpi_hp.c`
**Verdict:** **REPRODUCED** — see `VERDICT.md` + `verdict.json`

## Harness design (verbatim-interposition, kernel-compiled)

- `sys/dev/acpica/acpi_hp/acpi_hp.c` is compiled **VERBATIM** into the
  custom `HPHARNESS` kernel (stock INVARIANTS `X86_64_GENERIC` +
  `device acpi_hp` + `device hp_sim`); `build.sh` sha256-gates it at
  `58852b3530da0c99d3407428a75b5be0441e797a4bc1f21bb009faaf21fd429f`.
- `hp_sim.c` supplies the surrounding world:
  - a fake newbus bus driver literally named `acpi_wmi`, parented to the
    **real acpi0** through the real `BUS_ADD_CHILD` (proper ACPI ivars),
    so the verbatim `acpi_hp_attach` resolves its parent softc to the
    real `acpi_softc` and creates its sysctls under `hw.acpi.hp.*`
    exactly like on HP hardware;
  - the 7 `acpi_wmi_if` KBI methods with the lock protocol of the real
    `acpi_wmi.c` (`install` :408-431, `remove` :441-460 — no drain,
    `get_event_data` :466-495 + the DF-2383 stall hook,
    `evaluate_call` with controllable replies);
  - event injection mirroring `acpi_wmi_notify_handler` (:627-653):
    handler+ctx copied under the WMI lock, lock RELEASED, handler
    invoked — plus an optional dispatch delay;
  - a worker-kthread command plane (`hw.hpsim.cmd`): a sysctl handler
    must not create sysctls (`kernel_sysctl` holds `SYSCTL_SLOCK`
    across handlers), so create/destroy/scenario run in the worker and
    are observed via `hw.hpsim.cmd_done` / `hw.hpsim.log`;
  - deterministic victim reclaim of the freed 1208-byte softc chunk
    (`kmalloc(size, M_BUS)` — the per-CPU free list is LIFO, so
    `victim == old_sc` on every run) with field-level diff reporting
    against a mirror of `struct acpi_hp_softc` (offsets printed at
    boot: wmi_dev=+8, verbose=+28, was_wlan_on_air=+56, ...).
- Teardown is the REAL newbus path (`device_delete_child` → verbatim
  `acpi_hp_detach` → `kfree(softc, M_BUS)` → device free) — the
  kldunload equivalent.

## Build

    sh build.sh          # baseline kernel
    sh build.sh fixed    # fix.diff (acpi_hp.c remove-target + acpi_wmi.c
                         # dispatch drain, mirrored by HP_SIM_FIX_DRAIN=1)

## Run

    sh run.sh            # cmd 5 control, cmd 4 uaf x3, cmd 6 delayed

Baseline success criterion: `RESULT: UAF WRITE CONFIRMED` (deterministic
write at softc+56 into the reclaimed victim) and the delayed variant's
`acpi_hp_notify+0x27` panic; fixed kernel: `uaf_writes=0` everywhere,
no panic.

## Fix

`fix.diff` (git-apply-able, A/B validated): correct KBI device in
`acpi_hp_detach` (`sc->wmi_dev`, not `dev` — the old call resolves to
`kobj_error_method` ENXIO and never unregisters) + in-flight dispatch
refcount/drain in `acpi_wmi.c` — the DF-2381 family fix shape.
