[PATCH AUTOSEL 6.18-5.10] ACPICA: Add validation for node in acpi_ns_build_normalized_path()

Sasha Levin <[email protected]>
Newsgroups org.kernel.vger.linux-acpi,dev.linux.lists.acpica-devel,dev.linux.lists.patches,org.kernel.vger.linux-kernel,org.kernel.vger.stable
Message-ID <[email protected]>
From: ikaros <[email protected]>

[ Upstream commit 96b2b616870e46e2bc04efec03879683a0036e66 ]

Add validation for node in acpi_ns_build_normalized_path()
to prevent use-after-free vulnerabilities.

Link: https://github.com/acpica/acpica/commit/b35adf49e89a
Signed-off-by: ikaros <[email protected]>
Signed-off-by: Rafael J. Wysocki <[email protected]>
Link: https://patch.msgid.link/[email protected]
Signed-off-by: Sasha Levin <[email protected]>
---

LLM Generated explanations, may be completely bogus:

## Phase 1: Commit Message Forensics

**Step 1.1 — Subject line**
Record: `[ACPICA] [Add] validation for node in
acpi_ns_build_normalized_path() to prevent use-after-free`

**Step 1.2 — Tags**
Record:
- Link: https://github.com/acpica/acpica/commit/b35adf49e89a
- Link: https://patch.msgid.link/[email protected]
- Signed-off-by: ikaros \<[email protected]\>
- Signed-off-by: Rafael J. Wysocki \<[email protected]\>
- No Fixes:, Reported-by:, Tested-by:, Reviewed-by:, or Cc: stable tags
- Notable: ACPICA maintainer (Rafael J. Wysocki) signed off; upstream
  ACPICA commit link present

**Step 1.3 — Body analysis**
Record:
- Bug: `acpi_ns_build_normalized_path()` can dereference an
  invalid/freed namespace node pointer
- Symptom: heap use-after-free when reading `next_node->name`
- Root cause (from upstream issue #1138): during ACPI AML
  parsing/cleanup, walk state is freed while a stale `method_node` is
  still passed into pathname building via `acpi_ex_stop_trace_method()`
  → `acpi_ns_get_normalized_pathname()` →
  `acpi_ns_build_normalized_path()`
- No kernel version range stated in commit message

**Step 1.4 — Hidden bug fix?**
Record: No — explicitly described as UAF prevention, not disguised
cleanup.

---

## Phase 2: Diff Analysis

**Step 2.1 — Inventory**
Record:
- `drivers/acpi/acpica/nsnames.c`: +6 lines, 0 removed
- Function modified: `acpi_ns_build_normalized_path()`
- Scope: single-file, surgical fix

**Step 2.2 — Code flow change**
Record:
- Before: after NULL check on `node`, function immediately walks
  `next_node->parent` chain and reads `next_node->name` via
  `ACPI_MOVE_32_TO_32`
- After: if `ACPI_GET_DESCRIPTOR_TYPE(node) != ACPI_DESC_TYPE_NAMED`,
  jump to `build_trailing_null` (return empty path with trailing NUL)
  instead of dereferencing
- Affected path: any caller passing a stale/invalid node into
  `acpi_ns_build_normalized_path()`

**Step 2.3 — Bug mechanism**
Record:
- Category: **memory safety / use-after-free**
- Mechanism: freed walk-state memory is still referenced as a namespace
  node; reading `next_node->name` at the line equivalent to current line
  232 triggers ASAN heap-use-after-free (confirmed upstream in ACPICA
  issue #1138)

**Step 2.4 — Fix quality**
Record:
- Obviously correct: matches existing ACPICA validation pattern used in
  `acpi_ns_get_pathname_length()` (lines 56–63 of the same file),
  `acpi_ns_validate_handle()`, and `acpi_ut_get_node_name()`
- Minimal, no unrelated changes
- Regression risk: very low — invalid nodes get empty path instead of
  crash; valid nodes unchanged

---

## Phase 3: Git History Investigation

**Step 3.1 — Blame**
Record: vulnerable loop introduced in `d1e7ffe50ba58` (2015, "ACPICA:
Namespace: Add function to directly return normalized full path"). Bug
has been present since that function was added.

**Step 3.2 — Fixes: tag**
Record: N/A — no Fixes: tag in commit message.

**Step 3.3 — File history**
Record: `nsnames.c` is long-stable ACPI code; recent changes are
formatting/copyright, not structural refactors. Fix is standalone (not
dependent on other patches in the 27-patch ACPICA series).

**Step 3.4 — Author**
Record: ikaros (void0red) reported the UAF to upstream ACPICA; Rafael J.
Wysocki (ACPI maintainer) committed to Linux.

**Step 3.5 — Dependencies**
Record: no prerequisites. Patch 12/27 in the same series fixes a related
UAF in `acpi_ds_terminate_control_method()`, but this validation patch
is independent and self-contained. `git apply --check` confirms clean
apply to this tree.

---

## Phase 4: Mailing List and External Research

**Step 4.1 — Original discussion**
Record:
- b4 dig found: [PATCH v1 19/27] at
  https://patch.msgid.link/[email protected]
- Part of "ACPI: ACPICA 20260408" series (27 patches)
- v1 only revision found
- No NAKs or stable nominations found in thread mbox

**Step 4.2 — Reviewers**
Record: CC'd to Rafael J. Wysocki, linux-acpi, LKML, Saket Dumbre, Pawel
Chmielewski (Intel ACPICA developers).

**Step 4.3 — Bug report**
Record: ACPICA GitHub issue #1138 documents:
- ASAN heap-use-after-free at `AcpiNsBuildNormalizedPath` reading 4
  bytes (`next_node->name`)
- Reproducer: `./generate/unix/bin/acpiexec -m issue33.aml`
- Call chain: `acpi_ns_build_normalized_path` ←
  `acpi_ns_get_normalized_pathname` ← `acpi_ex_stop_trace_method` ←
  `acpi_ds_terminate_control_method` ← AML parse/table load path
- Severity: confirmed memory safety bug with concrete reproducer

**Step 4.4 — Related patches**
Record: patch 12/27 addresses a different UAF root cause in
`acpi_ds_terminate_control_method()`. Patch 19/27 (this commit) is a
defensive guard at the common pathname builder. Both are security-
relevant; this one stands alone.

**Step 4.5 — Stable list**
Record: no Cc: stable discussion found in downloaded thread.

---

## Phase 5: Code Semantic Analysis

**Step 5.1 — Key functions**
Record: `acpi_ns_build_normalized_path()` (modified); callers include
`acpi_ns_get_pathname_length()`, `acpi_ns_handle_to_pathname()`,
`acpi_ns_get_normalized_pathname()`

**Step 5.2 — Callers**
Record: `acpi_ns_get_normalized_pathname()` is called from many ACPI
paths including:
- `acpi_ex_stop_trace_method()` in `extrace.c` (UAF trigger path)
- `acpi_ns_get_external_pathname()`, `nsparse.c`, `nsinit.c`,
  `dsmethod.c`, `nseval.c`, `nssearch.c`
- Debugger-only paths (`db*.c`) — less relevant for production

**Step 5.3 — Callees**
Record: reads node descriptor type, walks parent chain, copies 4-byte
ACPI names; no allocation in the vulnerable section.

**Step 5.4 — Reachability**
Record:
- Call chain reaches ACPI table loading and method termination during
  normal kernel ACPI operation (boot + runtime method execution)
- Trigger requires crafted/malformed ACPI AML that causes walk-state
  teardown with stale node reference — demonstrated with `issue33.aml`
  in acpiexec; same ACPICA code runs in the kernel

**Step 5.5 — Similar patterns**
Record: `acpi_ns_get_pathname_length()` already validates descriptor
type before calling `acpi_ns_build_normalized_path()`, but
`acpi_ns_get_normalized_pathname()` does not — creating the gap this
patch closes at the lowest common level.

---

## Phase 6: Cross-Reference Against Local Tree

**Step 6.1 — Buggy code in tree?**
Record: **YES**. Local tree is **Linux 6.18.44** (`git describe HEAD` →
`v6.18.44`). Vulnerable code is present at lines 221–244 of
`drivers/acpi/acpica/nsnames.c` without the descriptor-type check. Fix
commit `96b2b616870e4` is **not** an ancestor of HEAD.

**Step 6.2 — Backport complications**
Record: clean apply confirmed (`git apply --check` → CLEAN APPLY). No
rework needed.

**Step 6.3 — Related fixes already present?**
Record: no — `git log -S "Validate the Node to avoid use-after-free"`
finds nothing in this tree; related patch 12/27
(`acpi_ds_terminate_control_method` UAF fix) also absent.

---

## Phase 7: Subsystem and Maintainer Context

**Step 7.1 — Subsystem criticality**
Record: **ACPI/ACPICA** — IMPORTANT to CORE. ACPI is on every x86/ARM
server, laptop, and most embedded systems with firmware tables.

**Step 7.2 — Activity**
Record: ACPI subsystem actively maintained in this tree (recent NULL-
deref and execution-abort fixes in `drivers/acpi/acpica/`).

---

## Phase 8: Impact and Risk Assessment

**Step 8.1 — Who is affected**
Record: all systems using in-kernel ACPICA for ACPI table parsing and
AML method execution.

**Step 8.2 — Trigger conditions**
Record: malformed/crafted ACPI AML during table load or method
termination with tracing enabled path; demonstrated with acpiexec +
crafted AML. Requires specific ACPI content, but ACPI tables are
firmware-supplied and occasionally attacker-influenced (e.g., custom
DSDT injection in some environments).

**Step 8.3 — Failure mode severity**
Record: **heap use-after-free** → kernel oops/panic or potential
information disclosure/exploitation primitive. Severity: **HIGH**.

**Step 8.4 — Risk-benefit**
Record:
- Benefit: **HIGH** — prevents real UAF on ACPI parsing path
- Risk: **VERY LOW** — 6-line defensive check, established ACPICA
  pattern
- Ratio: strongly favors backport

---

## Phase 9: Final Synthesis

**Step 9.1 — Evidence summary**

FOR backport:
- Confirmed heap UAF with ASAN report and reproducer (ACPICA #1138)
- Affects ACPI table/method execution — common kernel path
- Small, surgical, obviously correct fix
- Matches existing validation patterns in same subsystem
- Applies cleanly to Linux 6.18.44
- Signed off by ACPI maintainer
- Bug present since 2015 — long exposure window

AGAINST backport:
- Part of larger ACPICA import series (but this patch is standalone)
- No explicit stable nomination in mailing list
- Related root-cause fix exists separately in patch 12/27 (but this
  defensive fix has independent value)

UNRESOLVED: none material to the decision.

**Step 9.2 — Stable rules checklist**
1. Obviously correct and tested? **PASS** — ASAN-verified bug, standard
   ACPICA validation pattern
2. Fixes a real bug? **PASS** — confirmed heap UAF
3. Important issue? **PASS** — memory safety during ACPI parsing
   (crash/security)
4. Small and contained? **PASS** — 6 lines, one function
5. No new features/APIs? **PASS** — defensive validation only
6. Can apply to local tree? **PASS** — clean apply verified

**Step 9.3 — Exception category**
Record: N/A (security/memory-safety bug fix, not a quirk/ID/DT
exception).

**Step 9.4 — Decision rationale**

For **Linux 6.18.44**, this commit should be backported. The vulnerable
`acpi_ns_build_normalized_path()` code exists in this tree, the fix is
absent, and upstream has demonstrated a reproducible heap use-after-free
on the ACPI AML parsing/teardown path that the kernel shares. The fix is
minimal, follows established ACPICA conventions already used in sibling
functions in the same file, and prevents dereferencing freed namespace
nodes by validating the descriptor type before walking the parent chain.

---

## Verification

- [Phase 1] Parsed commit message and tags from `git show 96b2b616870e4`
- [Phase 1] Fetched ACPICA upstream issue #1138 — ASAN UAF confirmed
  with stack trace and reproducer
- [Phase 2] Diff analysis: +6 lines adding `ACPI_GET_DESCRIPTOR_TYPE`
  check before node walk
- [Phase 2] Read current `nsnames.c` lines 193–270 in tree — vulnerable
  code confirmed present
- [Phase 3] `git blame -L 221,245`: buggy loop from `d1e7ffe50ba58`
  (2015)
- [Phase 3] `git merge-base --is-ancestor 96b2b616870e4 HEAD` → FIX NOT
  IN TREE
- [Phase 3] `git apply --check` on patch → CLEAN APPLY
- [Phase 4] `b4 dig -c 96b2b616870e4` → lore URL found; patch 19/27 of
  ACPICA series
- [Phase 4] `b4 dig -w` → Rafael Wysocki, linux-acpi, LKML CC'd
- [Phase 4] Downloaded mbox; grep found no Cc: stable; found related
  patch 12/27
- [Phase 5] `grep acpi_ns_get_normalized_pathname` — multiple kernel
  callers including `extrace.c:284`
- [Phase 5] Read `extrace.c` `acpi_ex_stop_trace_method()` and
  `dsmethod.c:850` call site
- [Phase 5] Confirmed `acpi_ns_get_pathname_length()` already validates
  at line 58; `acpi_ns_get_normalized_pathname()` does not
- [Phase 6] `git describe HEAD` → v6.18.44
- [Phase 6] Confirmed validation check absent in current `nsnames.c`
- [Phase 7] `git log --oneline -20 -- drivers/acpi/acpica/` — active
  subsystem
- [Phase 8] UAF severity assessed from ASAN report in issue #1138

**YES**The analysis is complete for **ACPICA: Add validation for node in
acpi_ns_build_normalized_path()** on **Linux 6.18.44**.

**Summary:** This is a small (6-line) fix for a confirmed heap use-
after-free in ACPI pathname building. The vulnerable code is present in
this tree; the fix is not. It applies cleanly and follows existing
ACPICA validation patterns. Upstream demonstrated the bug with ASAN on
the ACPI AML parse/teardown path (`acpi_ex_stop_trace_method` →
`acpi_ns_get_normalized_pathname` → `acpi_ns_build_normalized_path`).

**Verdict for this tree: YES** — worth backporting as a memory-safety
fix on a common ACPI path.

 drivers/acpi/acpica/nsnames.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/acpi/acpica/nsnames.c b/drivers/acpi/acpica/nsnames.c
index 22aeeeb56cffd..19802da865c54 100644
--- a/drivers/acpi/acpica/nsnames.c
+++ b/drivers/acpi/acpica/nsnames.c
@@ -222,6 +222,12 @@ acpi_ns_build_normalized_path(struct acpi_namespace_node *node,
 		goto build_trailing_null;
 	}
 
+	/* Validate the Node to avoid use-after-free vulnerabilities */
+
+	if (ACPI_GET_DESCRIPTOR_TYPE(node) != ACPI_DESC_TYPE_NAMED) {
+		goto build_trailing_null;
+	}
+
 	next_node = node;
 	while (next_node && next_node != acpi_gbl_root_node) {
 		if (next_node != node) {
-- 
2.53.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.