# VERDICT — DF-1285

## Status
**INCONCLUSIVE (source-confirmed; not runtime-triggerable on this guest).**

## Mechanism (source-confirmed)
`OsSendCommand` at `sys/dev/raid/hptmv/entry.c:2678` handles three SCSI CDB
types by writing fixed-size replies directly into `ccb->csio.data_ptr`:

| CDB                | Lines         | Bytes written | Source                         |
|--------------------|---------------|---------------|--------------------------------|
| INQUIRY (0x12)     | entry.c:2709  | 96            | `SetInquiryData` fills `INQUIRYDATA` (`osbsd.h:68-90`) |
| READ_CAPACITY (0x25)| entry.c:2715 | 8             | `rbuf[0..7]`                   |
| SERVICE_ACTION_IN (0x9e) | entry.c:2740 | 12       | `rbuf[0..11]`                  |

CAM's `cam_periph_mapmem` allocates the kernel bounce buffer at exactly
`dxfer_len` bytes (the user-specified transfer length). If the user issues
one of these CDBs with a smaller `dxfer_len` than the reply (e.g.
`dxfer_len=4` for INQUIRY), the writes overflow the allocation by 4..92
bytes.

The INQUIRY data is partially attacker-influenced on RAID arrays — array
membership strings from `pVDev->VDeviceType` flow into the
`VendorId`/`ProductId`/`ProductRevisionLevel` memcpy's at
`entry.c:2595-2620` ("RR18xx  ", "RAID 0 Array    ", "3.00", etc.). The
READ_CAPACITY / SERVICE_ACTION_IN values are derived from
`pVDev->VDeviceCapacity` (disk size). The overflow bytes therefore are
*not* fully attacker-shaped, but the size and the start pattern are
controlled.

## Note on the file vs the brief
The task brief calls this "hptrr" — that is wrong. The vulnerable file is
`sys/dev/raid/hptmv/entry.c` (the **hptmv** driver — Highpoint RocketRAID
182x, based on the Marvell 88SX508x chipset). The DB `findings.file` column
is correct.

## Fix
Validate `csio->dxfer_len` against the actual reply size before writing,
and return `CAM_REQ_INVALID` if the buffer is too small. Do this in each
of the three cases. See `fix.diff`.

## Verification on this guest
- `hptmv` is statically compiled in (`device hptmv` in
  `sys/config/X86_64_GENERIC:119`) and shows up in `kldstat -v`
  (`pci/hptmv`).
- No Marvell 88SX508x / Highpoint PCI device in `pciconf -l` (only
  i440FX/PIIX/ACPI/virtio-net/virtio-blk/std-VGA), so `hptmv_probe` never
  matches and `OsSendCommand` is never called. **Not runtime-triggerable.**
- Fix validation: combined `X86_64_GENERIC` rebuild with this fix applied
  exited `rc=0`. Full log: `combined_build.log`.

## Exploit chain
None on this guest (no HW). On a system with an hptmv-managed disk exposed
via CAM `pass(4)` or a filesystem on top of an hptmv disk, an
unprivileged user could trigger a heap OOB write of 4..92 bytes by issuing
an INQUIRY/READ_CAPACITY/SERVICE_ACTION_IN with a small `dxfer_len`. The
overwrite start pattern is partially fixed ("RR18xx  " or zeros from
`ZeroMemory`); the size is fully controlled. No escalation was attempted
because the path is unreachable on this guest.

## Realistic impact ceiling
Local-user heap OOB write of 4..92 bytes on systems presenting an hptmv
disk to unprivileged users. CVSS: `AV:L/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:N`
(local, requires the rare hptmv-deployed machine + permissive CAM access).

## PoC changes
Folder was empty; added `trigger_analysis.c`, `build.sh`, `run.sh`,
`README.md`, this `VERDICT.md`, `fix.diff`, `manifest.json`,
`combined_build.log`.

## Recommended fix
Matches the finding proposal: validate `dxfer_len` against the expected
reply size in each of the three cases. See `fix.diff`.

## Fix status
**not_testable** — bug requires absent hardware. `fix.diff` applies cleanly
and compiles into `X86_64_GENERIC` (combined build `rc=0`).
