Page MenuHomeFreeBSD

pass(4): Allowlist CCB func_codes to harden passthrough ioctls
ClosedPublic

Authored by imp on Apr 17 2026, 10:35 PM.
Tags
None
Referenced Files
Unknown Object (File)
Fri, May 22, 3:13 PM
Unknown Object (File)
Wed, May 13, 6:32 PM
Unknown Object (File)
Wed, May 13, 5:46 PM
Unknown Object (File)
Wed, May 13, 5:32 PM
Unknown Object (File)
Wed, May 13, 4:17 PM
Unknown Object (File)
Mon, May 11, 7:13 AM
Unknown Object (File)
Sun, May 3, 10:03 PM
Unknown Object (File)
Sun, May 3, 9:14 AM
Subscribers
None

Details

Summary

The pass(4) driver's CAMIOCOMMAND and CAMIOQUEUE ioctls accept
arbitrary CCBs from userland. Previously, the only func_code filter
was a blocklist check against the XPT_FC_XPT_ONLY flag. This missed
several dangerous func_codes that lack that flag:

  • XPT_ABORT: the abort_ccb field is a raw kernel pointer from the user CCB payload. xpt_action_default() dereferences it without validation, leading to kernel crashes or worse.
  • XPT_SASYNC_CB: the callback and callback_arg fields come directly from the user CCB payload and get registered as a kernel async callback, allowing arbitrary kernel code execution.
  • Target mode CCBs (XPT_EN_LUN, XPT_TARGET_IO, etc.) fall through directly to the SIM with user-controlled payloads.

Replace the XPT_FC_XPT_ONLY blocklist with an explicit allowlist of CCB
function codes that are known to be safe for userland to submit: I/O
operations (SCSI, ATA, NVMe, SMP, MMC), device queries, transport
settings, and a handful of safe control operations (NOOP, REL_SIMQ,
RESET_DEV, DEBUG). Normally, the /dev/pass* permissions only allow root
to access them, so this is only a safety issue by default.

Also reject CAM_DATA_PADDR and CAM_DATA_SG_PADDR, since these pass
user-supplied physical addresses directly to DMA with no validation,
which on systems without an IOMMU allows arbitrary host memory access.
Add options PASS_UNSAFE_PADDR to allow the old behavior.

Verified that camdd, camcontrol, smartmontools, and cdrtools use only
func_codes on the allowlist (XPT_SCSI_IO, XPT_ATA_IO, XPT_NVME_IO,
XPT_NVME_ADMIN, XPT_PATH_INQ, XPT_GDEV_TYPE, XPT_GET_TRAN_SETTINGS,
XPT_SET_TRAN_SETTINGS, XPT_RESET_DEV, XPT_DEBUG) and none use
CAM_DATA_PADDR.

PR: 293888, 293890
Assisted-By: Claude Opus 4.6 (1M context)
Sponsored by: Netflix

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Not Applicable
Unit
Tests Not Applicable