β¬’ DragonFlyBSD Kernel Audit
← triage Β· dashboard
DF-2385

Package helpers index Elements[idx] with no bounds check; the apparent NULL guard is dead code (heap OOB read / info leak)

Summary

acpi_PkgInt acpi_PkgStr acpi_PkgGas acpi_PkgRawGas dereference res->Package.Elements[idx] without ever checking 0<=idx<res->Package.Count. Each then guards with if(obj==NULL...) but obj obtained via address-of operator &res->Package.Elements[idx] which can never be NULL (for idx>=0 it is base+idx*sizeof for idx<0 wild non-NULL pointer) so guard is dead protects nothing. Any caller omitting ACPI_PKG_VALID or passing negative/over-large idx performs unbounded heap OOB read on Elements array reading obj->Type and (depending on garbage Type) Integer.Value String.Pointer+Length Buffer.Pointer+Length yielding per-call kernel-heap info leak into caller buffers (battery strings video levels) or kernel panic. All 36 in-tree callers pre-validate via ACPI_PKG_VALID so not firmware-triggerable today without concurrent driver bug. [VERIFIED pass2: reproduced - acpi_PkgInt idx equals Count returns the planted past-Count element 0xCAFEF00DBAADC0DE, no bounds check dead NULL guard; EINVAL fix-validated A/B]

Discussion (0)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-2385 Β· 8 files
FileTypeDescriptionSize
README.md β€” 890 B ↓ raw
VERDICT.md β€” 1.4 KB ↓ raw
env.txt β€” 145 B view raw
fix.diff β€” 972 B view raw
fixed.log β€” 390 B view raw
run.log β€” 627 B view raw
run.sh β€” 121 B view raw
verdict.json β€” 1.8 KB view raw

DF-2385 - package helpers index Elements[idx] unchecked

Rig (ACHARNESS, op=pkg_oob_canary)

Package with Count=2 whose backing store holds a third, hostile element (Type=INTEGER, Value=0xCAFEF00DBAADC0DE) past Count - what an adjacent heap chunk looks like when its first bytes happen to be 01 00 00 00. acpi_PkgInt(&pkg, 2, &dst) must NEVER be able to return it.

Baseline (run.log)

acpi_PkgInt(idx=0 < Count) -> error=0 value=0x1111111111111111  (control)
acpi_PkgInt(idx=2 == Count) -> error=0 value=0xcafef00dbaadc0de  <-- OOB READ
VERDICT: BUG REPRODUCED

Fixed kernel (fix.diff: idx bounds check in all four helpers)

acpi_PkgInt(idx=2 == Count) -> error=22 value=0xdeadbeefdeadbeef  (EINVAL)

A page-edge variant (element on an unmapped page) was prepared but the DFly kernel_map is densely mapped - no unmapped neighbor could be found (noted in run.log).

VERDICT.md
↓ download raw

DF-2385 VERDICT

Status: reproduced (reproduced) Impact: leak Confidence: certain Attempts: 2

acpi_PkgInt(res, idx=Count) returned the planted past-the-end element (0xCAFEF00DBAADC0DE) to the caller - the Elements[idx] dereference has no bounds check and the obj==NULL guard is dead code (address-of never NULL). Control idx=0 returned the in-bounds value 0x1111111111111111. All 36 in-tree callers currently pre-validate with ACPI_PKG_VALID, so firmware-triggerability requires a companion driver bug (as filed). Fixed kernel returns EINVAL for idx==Count with dst untouched (0xdeadbeef...).

Kernel references

Guest

DragonFly dfbsd 6.5-DEVELOPMENT DragonFly 6.5-DEVELOPMENT #7: Sat Oct 24 00:08:04 UTC 2026 root@dfbsd:/usr/obj/usr/src/sys/ACHARNESS x86_64

Fix validation

See fix.diff and README.md for the baseline/fixed A/B outputs (run.log / fixed.log).

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_testable
↓ fix.diffper-fix-DF-2385

Confirmed kernel references

Detail

Exploit chain

any caller that passes an unchecked idx obtains kernel heap contents adjacent to the Elements array as a returned integer - per-call kernel heap disclosure into driver state

Evidence (decisive lines)

run.log (control idx=0 -> 0x1111111111111111; idx=2==Count -> 0xcafef00dbaadc0de VERDICT BUG REPRODUCED); fixed.log (idx=2 -> error=22 val=0xdeadbeefdeadbeef)

PoC changes

rig ops pkg_oob_canary / pkg_oob_heap written for this batch; page-edge variant unavailable (kernel_map densely mapped)

Verified recommended fix

see fix.diff

Verdict

acpi_PkgInt(res, idx=Count) returned the planted past-the-end element (0xCAFEF00DBAADC0DE) to the caller - the Elements[idx] dereference has no bounds check and the obj==NULL guard is dead code (address-of never NULL). Control idx=0 returned the in-bounds value 0x1111111111111111. All 36 in-tree callers currently pre-validate with ACPI_PKG_VALID, so firmware-triggerability requires a companion driver bug (as filed). Fixed kernel returns EINVAL for idx==Count with dst untouched (0xdeadbeef...).