# DF-0853 — PoC evidence pack

## Bug
`sys/vfs/isofs/cd9660/cd9660_vfsops.c` `iso_mountfs()`: the `high_sierra`
flag is set to 1 whenever any volume descriptor matches the Sierra id
(`"CDROM"`) at `:340` but is **never reset** when a later descriptor matches
the Standard ISO9660 id (`"CD001"`). The flag is then consulted at `:342`
(to pick `vdp->type` vs `vdp->type_sierra`) and at `:396-417` (to pick `pri`
vs `pri_sierra` field offsets). Since `pri` and `pri_sierra` are both casts of
the **same buffer** (`:347-349`), reading the wrong one parses a Standard
ISO9660 PVD at Sierra offsets — classic type confusion. The kernel then logs
`cd9660: High Sierra Format` (`:503`) and sets `iso_ftype = ISO_FTYPE_HIGH_SIERRA`
for an image whose actual primary descriptor is Standard ISO9660.

## Reachability / threat model
- `mount -t cd9660` requires either VREAD on the device node or
  `SYSCAP_RESTRICTEDROOT` (`cd9660_vfsops.c:235-243`). With
  `vfs.usermount=1` and a root-created, attacker-owned image attached via
  `vnconfig`, an unprivileged user can reach this path — i.e. the realistic
  "admin handed the user a mountable ISO" precondition. The bug is independent
  of privilege: the type confusion fires whenever the crafted image is parsed.
- No memory-corruption primitive is acquired: all `bread()`s are
  device-bounded and the `bcopy(rootp, isomp->root, 34)` stays inside the
  2048-byte descriptor buffer. The damage is misinterpretation of metadata
  (wrong `logical_block_size`, `volume_space_size`, `root_extent`, `root_size`,
  and `iso_ftype`), which then drives different downstream parsing routines in
  `cd9660_vnops.c`.

## PoC
`make_crafted_iso.c` emits a 100-sector image:
- **sector 16** — Sierra decoy: `id_sierra="CDROM"` → sets `high_sierra=1`;
  `type_sierra=3` → switch default-case, not primary, not end.
- **sector 17** — Standard ISO9660 PVD: `id="CD001"` → standard match, does
  **not** touch `high_sierra`; `system_id[0]=1` so the sticky
  `vdp->type_sierra` read returns `ISO_VD_PRIMARY`. Bytes 136-137 are forced
  to `0x00 0x08` so the *Sierra-cast* `logical_block_size` decodes to 2048,
  passing the `DEV_BSIZE..MAXBSIZE` power-of-2 validation at `:401` and
  letting the mount succeed.
- **sector 18** — Standard VD_END: `system_id[0]=255` so `type_sierra` read
  returns `ISO_VD_END`, exits the loop.

### Build
```
cc -O2 -o make_crafted_iso make_crafted_iso.c
```

### Run (as root; or as maxx with `vfs.usermount=1` + chowned device)
```
./make_crafted_iso crafted.iso
vnconfig -c vn0 ./crafted.iso
mkdir -p /mnt/df0853
mount -t cd9660 -o ro /dev/vn0 /mnt/df0853     # rc=0, mount succeeds
dmesg | tail                                   # prints "cd9660: High Sierra Format"
umount /mnt/df0853
vnconfig -u vn0
```

### Expected (bug present, unpatched `#0`)
```
cd9660: High Sierra Format
```
The kernel misclassifies a Standard ISO9660 image as High Sierra — observable
proof of the type confusion. `iso_ftype = ISO_FTYPE_HIGH_SIERRA` is set
despite the actual PVD being Standard.

### Expected (FIXED, `#1`)
Mount still succeeds (the PVD is a valid Standard ISO9660 image) but **no**
`cd9660: High Sierra Format` message is printed: `high_sierra` is correctly
reset to 0 when the Standard descriptor is recognised.

## Reproduce helpers
- `build.sh` — compile the ISO generator.
- `run.sh`  — generate ISO, attach via `vnconfig`, mount, dump dmesg tail,
  unmount. Prints `HIGH_SIERRA_COUNT=N` so you can compare unpatched (`>=1`)
  vs patched (`0`).

## Impact assessment
- Class: type confusion / incorrect type conversion (CWE-704) — not memory
  corruption. No OOB, no UAF, no write primitive.
- Ceiling: kernel misinterprets attacker-chosen ISO metadata fields
  (`logical_block_size`, `volume_space_size`, `root_extent`, `root_size`) at
  the wrong struct offsets, and selects `ISO_FTYPE_HIGH_SIERRA` parsing paths
  for a Standard ISO9660 image. In our test this manifested as `ls` returning
  `ENOTDIR` because `root_extent` was misread; no panic in 3+ runs.
- Severity: Low (matches finding classification). Reachable from an
  unprivileged user only under the `vfs.usermount=1` + chowned-image
  precondition, and yields no privilege or memory-corruption primitive —
  only metadata-driven misbehaviour on the attacker's own mount.
