# DF-4461 — amdtemp read-time KASSERT on mutable hardware state (CCD validity)

## Verdict: `not_reproduced` on this guest — hardware-gated; code-path analysis holds.
Claimed impact: **local DoS (kernel panic)** on AMD family 17h/19h CPUs running a
stock INVARIANTS kernel. Not demonstrable on the audit guest (QEMU, no AMD PCI
devices), which is an environment limitation, not a refutation.

## Root cause (line-accurate)

`sys/dev/powermng/amdtemp/amdtemp.c`:

- Probe time — the driver itself treats the CCD valid bit as **mutable and
  possibly clear**, skipping such sensors gracefully:
  - `amdtemp_probe_ccd_sensors17h()` amdtemp.c:1012 — `if ((val & AMDTEMP_17H_CCD_TMP_VALID) == 0) continue;`
  - `amdtemp_probe_ccd_sensors19h()` amdtemp.c:1070 — same check.
- Read time — the same bit is enforced with a **KASSERT** instead of a runtime
  check:
  - `amdtemp_gettemp17to19h()` amdtemp.c:966-967:
    `KASSERT((val & AMDTEMP_17H_CCD_TMP_VALID) != 0, ("sensor %d: not valid", (int)sensor));`
- KASSERT panics whenever the kernel is built with `options INVARIANTS`
  (sys/sys/systm.h:94-96). The default DragonFly kernel config enables it:
  `sys/config/X86_64_GENERIC:56` (`options INVARIANTS`), and the guest kernel
  confirms it runs X86_64_GENERIC with that config (run.log).

## Reachability / threat

Two independent entry points, both unprivileged-reachable:

1. **Direct sysctl read** — every probed CCD gets a world-readable
   `CTLTYPE_INT|CTLFLAG_RD` sysctl (amdtemp.c:1019-1022, :1077-1080). Any
   local user can poll `dev.amdtemp.N.ccdX` in a loop
   (`amdtemp_sysctl` amdtemp.c:810 → default branch → `amdtemp_gettemp17to19h`).
2. **Periodic sensor task** — `sensor_task_register2(..., amdtemp_sensor_task,
   2, ...)` (amdtemp.c:759-763) refreshes all CCD sensors every 2 s with no
   user involvement.

If any probed CCD's Tccd register ever reports VALID=0 after boot (CCD power
management / SMU state the kernel does not control), the kernel panics. There
is no plausible reading under which the bit is guaranteed immutable: the
probe-time filter exists precisely because it reads clear on some CCD slots,
and nothing pins it after boot.

Secondary dead assertions in the same helpers (context, not the finding):
`KASSERT(error == 0, ("amdsmn_read"))` at amdtemp.c:941/956/965 can never fire —
`amdsmn_read()` (sys/dev/powermng/amdsmn/amdsmn.c:280-293) always returns 0.

## Verification performed (this run)

1. Guest state (run.log, env.txt):
   - `DragonFly dfbsd 6.5-DEVELOPMENT #0 ... X86_64_GENERIC`
   - `hw.model: QEMU Virtual CPU version 2.5+`, `hw.ncpu: 6`
   - `pciconf -l | grep -c 1022` → `0` — **no AMD PCI devices**, so neither
     `amdsmn` nor `amdtemp` can attach (`amdtemp_match` amdtemp.c:288-306
     requires an AMD vendor/device id on the hostb parent; SMN models also
     need an `amdsmn` child, amdtemp.c:536-543).
   - `dev.amdtemp` sysctl tree: 0 OIDs; dmesg: 0 amdtemp mentions.
2. Trigger executed as `nobody`: `sysctl dev.amdtemp.0.ccd0` →
   `unknown oid`, rc=1 (run.log). Guest stayed up (`uptime`).
3. Conclusion per the audit status table: guest reachable, target
   device/feature absent → **not_reproduced / impact none on this guest**.
   The panic claim stands on the source analysis above; it requires AMD Zen
   hardware to manifest.

## Fix

`fix.diff` — replace the read-time KASSERT with a graceful invalid reading
(return 0 ⇒ 0.0 K, an obviously-invalid value; alternatively the caller
`amdtemp_sensor_task` could mark the ksensor `SENSOR_FINVALID`). The probe-time
skip (amdtemp.c:1012/1070) already defines the intended semantics: a clear
VALID bit is a normal condition, not an invariant violation.

Fix validation: not possible on this guest (requires AMD SMN hardware);
`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.
