acpi_asus_probe dereferences the unchecked INIT evaluation result: NULL Obj or non-String object -> NULL/wild pointer panic at probe
Summary
The AcpiEvaluateObject status is discarded; Buf.Pointer starts NULL so on failure Obj==NULL, yet String.Pointer is dereferenced with no NULL/Type check. If INIT returns a non-String the union read at offset 16 is a garbage pointer into strncmp. Even the intended NULL-string branch FALLS THROUGH to strncmp(NULL, ...) for non-Samsung non-EeePC platforms - deterministic panic. Firmware-gated boot DoS. Validate-status/Obj/Type fix.
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-4408 Β· 5 files| File | Type | Description | Size | |
|---|---|---|---|---|
| README.md | β | 2.6 KB | β raw | |
| VERDICT.md | β | 2.7 KB | β raw | |
| env.txt | β | 1.9 KB | view raw | |
| fix.diff | β | 1.8 KB | view raw | |
| verdict.json | β | 2.5 KB | view raw |
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/ASUS010whoseINITmethod 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:
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:
} /* 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.)
DF-4408 VERDICT β untested (source-verified; firmware-gated boot-time panic)
Reproduced?
No. Status untested: triggering requires an ACPI device whose HID matches
ATK0100 or ASUS010 (acpi_asus.c:553,561) and a broken INIT
method. The audit guest's ACPI namespace contains zero such nodes (verified
live β env.txt), so the driver never even probes. Loading a crafted DSDT
requires root (and on this guest, a custom QEMU BIOS blob). This is a
firmware-compatibility crash of the class that historically hit real laptops
(e.g. Samsung P30 PRs upstream), not an unprivileged attack path.
Defect (certain from source)
acpi_asus_probe evaluates INIT and uses the result blind:
acpi_asus.c:579βAcpiEvaluateObject(sc->handle, "INIT", &Args, &Buf)return status discarded. Buffer was reset atacpi_asus.c:576-577(Buf.Pointer = NULL; Buf.Length = ACPI_ALLOCATE_BUFFER), so on failure (noINITmethod, AML error, serializer trouble)Buf.Pointerremains NULL.acpi_asus.c:586βif (Obj->String.Pointer == NULL)dereferencesObjwith noObj != NULLcheck β panic in probe.- No
Obj->Type == ACPI_TYPE_STRINGvalidation: ifINITreturns an Integer (some BIOS variants do),Obj->String.Pointeris read from union bytes that belong to a different member (ACPI_OBJECT_STRING.Pointersits at offset 16, pastACPI_OBJECT_INTEGER.Valueat offset 8) β garbage pointer βstrncmpwild read atacpi_asus.c:621. - Even the intended NULL-string branch falls through: when
Obj->String.Pointer == NULLbut the DSDT is neither SamsungODEM(acpi_asus.c:597) norASUS010EeePC (acpi_asus.c:605), control leaves theifblock and reachesstrncmp(Obj->String.Pointer, ...)atacpi_asus.c:621with a NULL first argument β guaranteed panic. This makes the defect reachable on any ATK0100 machine whose INIT misbehaves, not just exotic ones.
Impact: NULL/wild-pointer dereference in device_probe context β kernel
panic at attach (boot-time or rescan DoS). No write primitive, no disclosure.
Fix
fix.diff: validate status + Obj != NULL + Type == ACPI_TYPE_STRING,
keep the Samsung/EeePC NULL-string detection branch, and make its tail return
ENXIO instead of falling into the model loop. Not validated on hardware
(no applicable firmware on guest) β fix_status: not_testable.
Fix status (batch validation)
Applied with the 36 sibling fix.diffs of this batch in findings/poc/_batch41/all_fixes.patch; single in-guest make -j6 nativekernel KERNCONF=X86_64_GENERIC completed RC=0 with zero errors under -Werror (full log: findings/poc/_batch41/fix_build8.log). Behavior A/B intentionally skipped for this Info-tier item.
Fix verification
not_testablefix.diff authored from source analysis; cannot be built/validated on the audit guest - driver only builds/attaches with ATK0100/ASUS010 firmware (optional acpi_asus, absent namespace).
findings/poc/DF-4408/fix.diff; env.txt
Confirmed kernel references
Detail
Evidence (decisive lines)
findings/poc/DF-4408/VERDICT.md (path:line trace incl. union-offset analysis for non-String returns), README.md, env.txt (live guest ACPI probe), fix.diff
Verified recommended fix
Validate AcpiEvaluateObject status, Obj != NULL, and Obj->Type == ACPI_TYPE_STRING before use, and make the NULL-string branch return ENXIO instead of falling through to strncmp(NULL); see fix.diff.
Verdict
Source-verified NULL/wild-pointer dereference in acpi_asus_probe: the AcpiEvaluateObject(INIT) status is ignored (acpi_asus.c:579), Buf.Pointer is NULL on failure, Obj->String.Pointer is dereferenced with no Obj NULL or Type check (acpi_asus.c:586), and even the intended NULL-string branch falls through to strncmp(Obj->String.Pointer=NULL, ...) at acpi_asus.c:621 when the platform is neither Samsung ODEM nor ASUS010 EeePC. Deterministic kernel panic at probe (boot-time DoS) on any ATK0100/ASUS010 machine with a missing, failing, or non-String INIT method. Untested at runtime: the audit guest ACPI namespace has zero ATK0100/ASUS010 nodes (verified live, env.txt) so the driver never attaches; no unprivileged trigger path exists (probe runs at boot or under root-forced rescan; DSDT replacement requires root).
No comments yet.