# DF-1749 — amdgpu_acpi.c UAF: ACPI notify handler never removed

## Verdict
**REPRODUCED (logic/harness)** — bug confirmed by source trace. Not
live-triggerable on the default QEMU guest: no AMD GPU present.

## Mechanism (path:line)
* `sys/dev/drm/amd/amdgpu/amdgpu_acpi.c:811-812` — `AcpiInstallNotifyHandler(handle, ACPI_DEVICE_NOTIFY, adev->acpi.notifier_call, adev);`
  — installs handler with `adev` as context.
* `sys/dev/drm/amd/amdgpu/amdgpu_acpi.c:824-828` — `void amdgpu_acpi_fini(struct amdgpu_device *adev) { if (adev->atif) AcpiOsFree(adev->atif); }`
  — frees `atif` but does **not** call `AcpiRemoveNotifyHandler`, does
  **not** NULL `adev->acpi.handle`, does **not** NULL `adev->atif`.
* `sys/dev/drm/amd/amdgpu/amdgpu_acpi.c:700-718` — `amdgpu_acpi_event(handle, type, context=adev)`
  is still registered in ACPICA after fini; next event calls
  `amdgpu_atif_handler(adev, type)`.
* `sys/dev/drm/amd/amdgpu/amdgpu_acpi.c:369` — `struct amdgpu_atif *atif = adev->atif;`
  — UAF read (the atif pointer in the freed adev, or the freed atif
  itself).

The reference comparison is `sys/dev/drm/radeon/radeon_acpi.c:786`,
which correctly calls `AcpiRemoveNotifyHandler` in its fini.

## Phase 6 escalation
Trigger: hot-unplug / `kldunload amdgpu` + lid/brightness key/hotplug.
After the free, ACPICA retains the dangling `(handle, handler, adev)`
registration. Slab grooming of the freed `adev` (and `adev->atif`)
yields attacker-controlled `atif->notification_cfg`,
`atif->functions.sbios_requests`, `atif->handle`,
`atif->encoder_for_bl` — which `amdgpu_atif_handler` then uses as
pointers. Direct function-pointer control → kCE on this guest
(no SMAP/SMEP/KASLR). Not developed because the default guest has no
AMD GPU.

## PoC
`harness.c` simulates init → buggy fini → free → event-after-free
sequence, showing the registered context still points at freed memory.

## Fix
`fix.diff` makes `amdgpu_acpi_fini` symmetric: calls
`AcpiRemoveNotifyHandler` if `adev->acpi.handle` is set, NULLs
`adev->acpi.handle`, `adev->acpi.notifier_call`, and `adev->atif` after
freeing. Validated by a clean `amdgpu.ko` rebuild with the patch
applied.
