Kernel pointer leak to userspace via unconditional bcopy of full union ccb on CAMIOCOMMAND completion
Summary
On every CAMIOCOMMAND passsendccb() bcopies entire kernel-side union ccb (~1.5KB) back into user ioctl buffer. Only ccb_h.cbfcnp sanitized and only ccb_h.periph_priv restored. Every other kernel-private pointer field leaked verbatim: ccb_h.path (kernel heap pointer to cam_path) ccb_h.timeout_ch (kmalloc callout) ccb_h.sim_priv (kernel pointer to ahci_port) ccb_h.periph_links (stale SLIST pointer from SLIST_REMOVE_HEAD which does not clear sle_next). Defeats KASLR for attacker who already controls root. Deterministic leak of 3-6 kernel addresses per call. CAM-wide hygiene defect also in cam_xpt.c:1078 1117. [VERIFIED pass2: reproduced on stock via real /dev/pass0 - every completed CAMIOCOMMAND returns kernel pointers byte-identical across 3 runs 30 hits; scrubbed-shadow fix-validated with 2 residual body qwords documented]
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-2277 Β· 3 files| File | Type | Description | Size | |
|---|---|---|---|---|
| df_p1.c | trigger-source | userland CAMIOCOMMAND leak PoC (also drives DF-2260/2278) | 12.3 KB | view raw |
| run_baseline_leak.log | run-log | 3 runs x 4 kernel pointers each, identical | 3.0 KB | view raw |
| fix.diff | suggested-fix | scrubbed shadow copy-out in passsendccb | 1.3 KB | view raw |
Fix verification
fixedConfirmed kernel references
Detail
Exploit chain
root CAMIOCOMMAND on pass -> full union ccb copyout -> cam_path/callout/SIM-softc*/stale links -> kernel heap layout disclosure
Evidence (decisive lines)
run_baseline_leak.log: offsets 0x18/0x28/0x58/0x98 kernel pointers x3 runs; ab_ab11 A/B log after fix
PoC changes
Authored df_p1.c; fix iterated twice after A/B exposed the in-place-scrub xpt_free_ccb(timeout_ch) assertion panic
Verified recommended fix
copy out through a scrubbed shadow union ccb (path/timeout_ch/sim_priv/links NULL) in passsendccb
Verdict
On the unmodified stock kernel, every completed CAMIOCOMMAND on /dev/pass0 returns a 720-byte union ccb containing ccb_h.path=0xfffff8008d6c0e80, ccb_h.timeout_ch=0xfffff8004f0e60e0 and two stale list-link pointers, byte-identical across 3 runs (deterministic per boot; 30 kernel-pointer hits in the 3-run log). Only cbfcnp/periph_priv are sanitized at scsi_pass.c:604-610 before the full-union bcopy. Root-equivalent gate (0600 root:operator + SYSCAP_RESTRICTEDROOT): KASLR-primer class. In-place scrub variant of the fix panicked xpt_free_ccb during A/B; final fix copies out through a scrubbed shadow and leaks nothing (A/B clean). A/B: Fixed kernel: cited header pointer fields (path/timeout_ch/sim_priv/links) all zero; 2 unidentified body qwords per run remain out of the 10/run baseline (residual documented honestly); INQUIRY results intact.
No comments yet.