Page MenuHomeFreeBSD

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

Authored by imp on Fri, Apr 17, 10:35 PM.
Tags
None
Referenced Files
F153469458: D56486.diff
Tue, Apr 21, 8:33 AM
F153451355: D56486.diff
Tue, Apr 21, 6:14 AM
F153364674: D56486.diff
Mon, Apr 20, 5:50 PM
Unknown Object (File)
Sat, Apr 18, 5:11 AM
Unknown Object (File)
Sat, Apr 18, 5:10 AM
Unknown Object (File)
Sat, Apr 18, 4:37 AM
Subscribers
None

Details

Reviewers
jhb
mav
ken
chs
Group Reviewers
cam
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 Skipped
Unit
Tests Skipped
Build Status
Buildable 72307
Build 69190: arc lint + arc unit