# DF-5627 VERDICT — reproduced (Info, impact: none — latent uninitialized kernel-stack read)

## Root cause

`sys/bus/ppbus/ppb_base.c:100-108`:

```c
int
ppb_get_epp_protocol(device_t bus)
{
	uintptr_t protocol;                       /* uninitialized */

	BUS_READ_IVAR(device_get_parent(bus), bus, PPC_IVAR_EPP_PROTO,
	    &protocol);                           /* return value discarded */

	return (protocol);
}
```

`BUS_READ_IVAR` is an error-returning method call; on failure the typical
implementation writes nothing through `*result` (see `ppc_read_ivar()`'s
own `default: return (ENOENT);` at `sys/dev/misc/ppc/ppc.c:2060-2062`, or
any bus without the ivar).  Discarding the error and returning
`protocol` hands the caller stale stack contents.

## Verification (production code)

Shared `ppbbasehx` KLD, guest's **unmodified** `/usr/src/sys/bus/ppbus/
ppb_base.c`.  The fake controller's `bus_read_ivar` returns ENOENT
without writing (generic-controller behavior).  Immediately before each
call a `__noinline` helper dirties 512 stack bytes with a uniform
pattern; `ppb_get_epp_protocol`'s small frame then lands in the dirtied
region:

```
stack dirtied 0x41 -> protocol=0x41414141
stack dirtied 0x42 -> protocol=0x42424242
stack dirtied 0x43 -> protocol=0x43434343
```

The production function returned the dirtier's bytes verbatim,
deterministically, across 4 module loads.  This is a CWE-457
use-of-uninitialized-variable in an `EXPORT_SYMS` interface.

## Why latent / impact ceiling

- The only in-tree ppbus parent is `ppc`, whose `read_ivar` always writes
  `PCP_IVAR_EPP_PROTO` (ppc.c:2053-2055) — the failure path needs a
  non-ppc/failed controller (third-party KLD controller, or future
  ivar-set changes).
- In-tree consumer: `mode2xfer()` (ppb_msq.c:85).  With garbage `epp` it
  takes the `default:` branch — `panic("unknown EPP protocol")` (the
  panic-as-error already filed as part of DF-5576) — or, if the garbage
  happens to be 0/1, silently selects the wrong EPP protocol/submicroseq.
- The value itself never reaches userland, so this is not a direct
  disclosure; it is an uninitialized-read contract bug feeding a
  panic/logic sink.  Info severity (Low under a third-party-controller
  threat model).

## Fix validation — fixed

Applied `uintptr_t protocol = 0;` (fix.diff: `= EPP_1_9`, same value 0,
plus the comment) to the guest's `/usr/src/sys/bus/ppbus/ppb_base.c`,
rebuilt the same harness, re-ran:

```
stack dirtied 0x41 -> protocol=0x00000000
stack dirtied 0x42 -> protocol=0x00000000
stack dirtied 0x43 -> protocol=0x00000000
```

Baseline misbehavior gone; control (dirty patterns) unchanged; source
restored to pristine and `cmp`-verified (`RESTORED-OK` in session log).

## Environment

DragonFly 6.5-DEVELOPMENT x86_64 (X86_64_GENERIC), cc 8.3, 6 vCPU QEMU
guest, no parallel port.

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