# DF-0853 — VERDICT

**Verdict: REPRODUCED (and FIX VALIDATED on a built & booted single-fix kernel).**

## Mechanism (trigger → primitive → effect)

`iso_mountfs()` in `sys/vfs/isofs/cd9660/cd9660_vfsops.c` walks the volume
descriptor sequence (sectors 16..100, `:326-384`). For each descriptor:

```c
/* :334-341 */
if (bcmp (vdp->id, ISO_STANDARD_ID, sizeof vdp->id) != 0) {
    if (bcmp (vdp->id_sierra, ISO_SIERRA_ID,
              sizeof vdp->id) != 0) {
        error = EINVAL;
        goto out;
    } else
        high_sierra = 1;          /* <-- set but NEVER reset */
}
switch (isonum_711 (high_sierra? vdp->type_sierra: vdp->type)){
case ISO_VD_PRIMARY:
    if (pribp == NULL) {
        pribp = bp; bp = NULL;
        pri       = (struct iso_primary_descriptor *)vdp;
        pri_sierra= (struct iso_sierra_primary_descriptor *)vdp;  /* SAME buffer */
    }
    break;
```

`high_sierra` is initialised to 0 at `:278` and only ever set to 1 at `:340`.
If a Sierra-format descriptor appears anywhere in the sequence, every
subsequent Standard ISO9660 descriptor is misread:

- The `type` selector at `:342` reads `vdp->type_sierra` (byte offset 8) of
  the Standard descriptor — which is actually `system_id[0]`, an
  attacker-controlled byte.
- Once such a misread selects `ISO_VD_PRIMARY`, `pri` and `pri_sierra` both
  point at the **same** Standard PVD buffer (`:347-349`).
- The field reads at `:396-417` use `pri_sierra->FIELD`:
  - `logical_block_size` reads standard PVD bytes 136-137 (inside the
    standard `path_table_size` field, BE half).
  - `volume_space_size` reads standard PVD bytes 88-91 (inside the standard
    `unused3` region — fully attacker-controlled).
  - `root_directory_record` reads standard PVD bytes 180-213 (overlaps the
    tail of standard `root_directory_record` + start of `volume_set_id` —
    attacker-controlled `root_extent`, `root_size`).
- `iso_ftype` is then set to `ISO_FTYPE_HIGH_SIERRA` at `:504`, and the
  kernel logs `cd9660: High Sierra Format` at `:503` — the observable marker
  that proves the misclassification.

## Reproduction (unpatched `6.5-DEVELOPMENT #0`)

`make_crafted_iso.c` emits a 100-sector image:

| Sector | Content                                                                |
|--------|------------------------------------------------------------------------|
| 16     | Sierra decoy: `id_sierra="CDROM"` → `high_sierra=1`; `type_sierra=3`   |
| 17     | Standard PVD: `id="CD001"` (skips the reset path); `system_id[0]=1` so the sticky `type_sierra` reads `ISO_VD_PRIMARY`; bytes 136-137 = `0x00 0x08` so the Sierra-cast `logical_block_size` validates to 2048. |
| 18     | Standard VD_END: `system_id[0]=255` so `type_sierra` reads `ISO_VD_END`. |

Mount result on the unpatched kernel (3 consecutive runs all identical):
```
vn0: MBR magic not found; assume a COMPATIBILITY_SLICE (s0)
cd9660: High Sierra Format            <-- TYPE CONFUSION PROOF
MOUNT_RC=0
```

The mount succeeds, but downstream metadata is misinterpreted: an `ls` of the
mount point returns `ENOTDIR` because `root_extent` was read at the wrong
offset. **No panic in 3+ runs** — the bug is type confusion, not memory
corruption. All `bread()`s stay device-bounded and the 34-byte `bcopy` of
`rootp` stays inside the 2048-byte descriptor buffer.

## Impact
- **Class:** CWE-704 Incorrect Type Conversion. Not memory corruption.
- **Reachability:** `mount -t cd9660` requires VREAD on the device OR
  `SYSCAP_RESTRICTEDROOT` (`:235-243`). With `vfs.usermount=1` and a
  root-created, attacker-owned image attached via `vnconfig`, an unprivileged
  user reaches this path — the realistic "admin handed the user a mountable
  ISO" precondition. The bug itself is privilege-independent.
- **Ceiling:** attacker-chosen ISO controls `logical_block_size`,
  `volume_space_size`, `root_extent`, `root_size`, and `iso_ftype` for the
  mounted filesystem, all read at the wrong struct offsets. No OOB read/write,
  no UAF, no privilege boundary crossed. Severity **Low** matches the finding.

## Fix
The minimal, root-cause fix is to reset `high_sierra = 0` whenever the
current descriptor matches the Standard ISO9660 id:

```diff
--- a/sys/vfs/isofs/cd9660/cd9660_vfsops.c
+++ b/sys/vfs/isofs/cd9660/cd9660_vfsops.c
@@ -338,7 +338,8 @@
 				goto out;
 			} else
 				high_sierra = 1;
-		}
+		} else
+			high_sierra = 0;
 		switch (isonum_711 (high_sierra? vdp->type_sierra: vdp->type)){
```

## Fix validation (built + booted single-fix kernel)

| Step                                                          | Result                                                |
|---------------------------------------------------------------|-------------------------------------------------------|
| Reset to `with-src` (unpatched `#0`, full src + warm obj)     | up                                                    |
| `kern.version`                                                | `6.5-DEVELOPMENT #0` (Thu Jul 2 06:02:54 UTC 2026)   |
| Baseline PoC run                                              | `cd9660: High Sierra Format` printed; MOUNT_RC=0      |
| Apply `fix.diff` (`patch -p1`)                                | `Hunk #1 succeeded at 338`                            |
| `make -j6 nativekernel KERNCONF=X86_64_GENERIC`               | `NK_DONE rc=0` (04:33:20 UTC)                         |
| Install `kernel.stripped` → `/boot/kernel/kernel` + reboot    | `kern.version = 6.5-DEVELOPMENT #1` (today)           |
| **Patched PoC run ×3**                                        | MOUNT_RC=0, **`High Sierra Format` count = 0**        |
| `sha256(/boot/kernel/kernel)`                                 | `39174db443dffdf…e3222ad`                             |

**Before/after contrast — decisive:**

Baseline `#0`:
```
vn0: MBR magic not found; assume a COMPATIBILITY_SLICE (s0)
cd9660: High Sierra Format
=== baseline-high-sierra-count: 1 ===
```

Patched `#1`:
```
run1 MOUNT_RC=0
run2 MOUNT_RC=0
=== total-high-sierra-prints: 0 ===
```

The fix closes the bug: the same crafted ISO that triggered the
misclassification on `#0` produces zero `High Sierra Format` prints on `#1`,
and the mount still succeeds because the Standard PVD is a valid ISO9660
image once parsed at the correct offsets.

## Files
- `make_crafted_iso.c` — ISO generator (the trigger).
- `build.sh`, `run.sh` — reproduce panel scripts.
- `build.log`, `run.log`, `fix_build.log` — full untrimmed logs.
- `panic.txt` — N/A (no panic observed; type confusion only).
- `env.txt` — guest environment.
- `fix.diff` — git-apply-able single-hunk fix.
- `manifest.json` — catalog.
