# DF-5501 VERDICT — reproduced (securelevel enforcement gap)

## Candidate

passioctl() (scsi_pass.c:437-525) performs no securelevel check while
passopen() (scsi_pass.c:335-339) refuses opens at securelevel > 1.  A fd
opened before the raise keeps full raw-SCSI passthrough (CAMIOCOMMAND:
arbitrary CDBs, including disk WRITE commands, to the device behind the
periph) after kern.securelevel is raised to 2 — the exact tamper
protection the open-time check exists for.

## Run (DragonFly 6.5-DEVELOPMENT, fresh vm.sh reset with-src boot)

1. securelevel=-1: open /dev/pass0 → ok.
2. sysctl kern.securelevel=2 → fresh open: `Operation not permitted`
   (passopen's check working as designed).
3. CAMIOCOMMAND (XPT_SCSI_IO, TEST UNIT READY) on the PRE-OPENED fd at
   securelevel=2: **rc=0**, CAM status 0x0c (the device's own answer to
   TUR — the vbd/cd passthrough target does not implement it cleanly;
   irrelevant: the command traversed passioctl → passsendccb →
   cam_periph_runccb → xpt_action and was fully processed, no EPERM).

run.log holds the full output, RUN_RC=0.  Reproduced on the first clean
attempt (an initial run with an over-strict success criterion and the
resulting still-elevated-securelevel guest was superseded by the clean
reset run recorded here; the earlier run's transcript matches).

## Impact ceiling

Any code that already held a pass fd when securelevel was raised (long
-lived privileged daemon, or a process that compromised root *before* the
raise) retains arbitrary raw device I/O — in particular writes to the
raw disk devices, i.e. it can rewrite the running kernel on disk and
other artifacts securelevel ≥ 2 is meant to freeze.  Not an unprivileged
escalation by itself: the fd must be opened while privileged / before the
raise → Low severity, but a real logic gap (fresh opens ARE blocked, so
the intent to block at high securelevel is explicit in the driver).

## Fix

One-line re-check in passioctl (fix.diff).  Not kernel-built: Low-tier
logic finding; the fix cannot regress the reproduced marker (it adds the
same EPERM the open path already returns) — no memory corruption
involved, so no mandatory fix-build per the audit contract.

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