# DF-4408 — acpi_asus_probe dereferences an unchecked ACPI evaluation result (NULL / non-String INIT object)

- File: `sys/dev/acpica/acpi_asus/acpi_asus.c` (pass 2, GLM 5.3; no known findings on this file)
- Class: CWE-476 (NULL pointer dereference) + CWE-690 (unchecked return value)
- Severity: Low — firmware-gated (needs an ACPI node with HID `ATK0100`/`ASUS010`
  whose `INIT` method is missing, fails, or returns a non-String). Trigger is
  probe time (boot), or a root-forced re-probe/re-scan. Kernel panic (DoS),
  no info leak, no corruption primitive.

## Defect (path:line)

`acpi_asus_probe`, `acpi_asus.c:579-586`:

```c
AcpiEvaluateObject(sc->handle, "INIT", &Args, &Buf);   /* status ignored */
Obj = Buf.Pointer;                                     /* NULL on failure */

if (Obj->String.Pointer == NULL) {                     /* NULL deref if Obj==NULL */
```

and the fall-through of that same branch, `acpi_asus.c:613-621`:

```c
}              /* Obj->String.Pointer == NULL but neither Samsung (ODEM) nor
                * EeePC (ASUS010) matched: falls out of the if-block */
...
for (model = acpi_asus_models; model->name != NULL; model++) {
    if (strncmp(Obj->String.Pointer, model->name, 3) == 0) {   /* strncmp(NULL,...) */
```

Three concrete panic paths, all deterministic:
1. `INIT` missing / evaluation fails (`AE_NOT_FOUND` etc.): `Buf.Pointer` stays
   NULL (buffer was `Buf.Pointer = NULL; Buf.Length = ACPI_ALLOCATE_BUFFER`,
   `acpi_asus.c:576-577`) → `Obj->String.Pointer` faults at once.
2. `INIT` returns an Integer/Package/Buffer: `Obj->Type != ACPI_TYPE_STRING`
   is never checked; `String.Pointer` (offset 16 in `union acpi_object`) reads
   bytes outside the returned member → wild pointer into `strncmp`.
3. `INIT` returns a String whose `Pointer` is NULL and the DSDT is neither
   `ODEM` (Samsung) nor `ASUS010` (EeePC): the intended branch handles Samsung
   and EeePC but then falls *through* into the model-name loop and does
   `strncmp(NULL, model->name, 3)`.

Same family: `acpi_asus.c:621-624, 710` pass `Obj->String.Pointer` to
`strncmp`/`sbuf_printf("%s")` unvalidated.

## Build / run

Not runnable on the audit guest: `acpidump` shows zero `ATK0100`/`ASUS010`
nodes (see `env.txt`), so `acpi_asus` never probes here. On a machine with a
broken INIT method this panics during boot; a root user can also force it via
devctl-driven reprobe. No unprivileged trigger exists.

## Recommended fix

Check the evaluation status, `Obj != NULL`, and `Obj->Type ==
ACPI_TYPE_STRING` before any use, and make the NULL-String-Pointer branch
return instead of falling through — see `fix.diff`. (FreeBSD's copy has the
same gap; fix should go upstream.)
