# DF-3793 VERDICT

## Status: reproduced (primitive proven at runtime; impact ceiling bounded)

**Guest:** DragonFly dfbsd 6.5-DEVELOPMENT #0: Thu Jul 2 06:02:54 UTC 2026
(X86_64_GENERIC), x86_64. ACPI live, `debug.acpi.interpreter_slack=0`
(supported boot tunable) for the decisive run.

## What was run

`df3793.kmo` (kmod, source in this pack) evaluates no-`Return()` methods of
the live QEMU DSDT twice:

* **Part A (decisive)** — direct `AcpiEvaluateObject()` with a caller buffer
  pre-poisoned with `Type=ACPI_TYPE_INTEGER, Value=0xDEADBEEFCAFEBABE`:
  ```
  DF3793: path=\_SB_.PCI0.PRES._INI status=AE_OK buf.Length_after=0
  DF3793:   param.Type=1 param.Value=0xdeadbeefcafebabe  <== BUFFER UNTOUCHED, AE_OK
  DF3793: path=\_SB_.CPUS.CTFY status=AE_OK buf.Length_after=0
  DF3793:   param.Type=1 param.Value=0xdeadbeefcafebabe  <== BUFFER UNTOUCHED, AE_OK
  ```
  `AE_OK` + `Length=0` + poison intact proves ACPICA did not write the
  caller's buffer — inside `acpi_GetInteger()` (acpi.c:2175-2182) the
  identical call leaves `param` uninitialized and `ACPI_SUCCESS(status)`
  gates the read of `param.Type` / `param.Integer.Value`.

* **Part B (demonstrates stack-history dependence)** — `acpi_GetInteger()`
  on the same paths: with default slack the helper returned `AE_OK` with
  `number=0` (implicit-return object); with slack off it returned `AE_TYPE`
  (garbage Type ≠ 1). Same input, different outcome driven by stale stack
  contents. (The deliberate spray pattern did not land in the helper's
  frame, so `*number` receiving the sprayed value was not observed directly;
  Part A + source lines 2177-2182 make the read unavoidable.)

## Why only "Low" severity

The trigger is firmware AML (method that returns no object). On stock
config (slack on) most such methods gain an implicit return; slack off — a
documented supported configuration — makes every no-`Return` method a
trigger during ordinary probing. No unprivileged runtime path to feed
`acpi_GetInteger` attacker-chosen paths exists (DO_MCALL does not use it).
Worst realistic impact: stale kernel stack data deciding device presence /
lid state / thermal limits, and numbers derived from stack garbage being
exposed through sysctls (limited disclosure). No corruption, no control
flow influence found.

## Exploit chain

None (class does not permit one here): uninit *read* of a stack ACPI_OBJECT
influences boolean/integer outputs only.

## Fix validation

`fix.diff` (zero-init `param` + map the "AE_OK, no object" case to
`AE_AML_NO_RETURN_VALUE`) was applied to the guest's `/usr/src` copy,
kernel rebuilt (`make nativekernel`) and booted; the kmod re-run then
showed `acpi_GetInteger -> AE_AML_NO_RETURN_VALUE` (defined status, no
stack-data dependence). See `run_patched.log` and `fix.diff`.

## 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.
