# DF-4411 — acpi_asus probe/attach mutate the driver-wide static model tables (cross-device state contamination)

- File: `sys/dev/acpica/acpi_asus/acpi_asus.c` (pass 2)
- Class: CWE-1284 / CWE-1285 family (improper handling of inconsistent data /
  mutation of what should be immutable configuration) — hygiene/correctness,
  no memory corruption
- Severity: Info — feature corruption on multi-device/reprobe scenarios only;
  requires matching ASUS/Samsung/EeePC firmware.

## Defect (path:line)

`acpi_asus_models[]` and friends are `static struct acpi_asus_model` — one
shared copy for the whole driver — yet `acpi_asus_probe` writes into the
matched entry while quirking look-alike models:

- `acpi_asus.c:682` — `model->lcd_get = NULL;` (L2B borrows L3C's entry —
  **permanently disables** L3C's lcd_get for every later probe)
- `acpi_asus.c:689` — `model->lcd_get = "\_SB.PCI0.SBSM.SEO4"` style override
  for A3G borrowing M6R
- `acpi_asus.c:697` — `model->wled_set = "WLED";` (M2N/W1N borrow xxN)
- `acpi_asus.c:705` — `model->mled_set = NULL;` (M5N/S5N borrow xxN)

and `acpi_asus_attach` does the same:

- `acpi_asus.c:807-808` — `if (sc->model->n_func == NULL) sc->model->n_func
  = acpi_asus_notify;` — writes the static entry.

Consequences:
- probe is not idempotent: a DSDT exposing two ATK0100 devices (or a
  bus re-scan after resume/driver reload) probes entries in mutated state —
  e.g. first device "L2B" kills L3C's `lcd_get`, so a genuine L3C second
  device silently loses its LCD sysctl (`acpi_asus_sysctl_init` returns
  FALSE when `lcd_get == NULL`, `acpi_asus.c:1134-1166`); conversely an
  A3G device leaves M6R's entry pointing at A3G's method;
- two concurrent probes (newbus children probing on different CPUs) race on
  unsynchronized pointer stores into shared statics;
- makes handler-removal correctness depend on hidden table state (see
  DF-4409, whose workaround exists only because of this mutation).

## Build / run

Not runnable on the audit guest (no ATK0100/ASUS010 nodes — `env.txt`).
Code-reading exercise; no runtime PoC exists that an unprivileged user (or
any user short of root + matching firmware + multiple devices) could drive.

## Recommended fix

Copy the matched entry into a per-instance `struct acpi_asus_model` in the
softc and apply the quirks to the copy (see `fix.diff` sketch).
