feat(host/windows): seal the host↔driver channels (frame + gamepad, proto v2)
Frame ring (pf-vdisplay) and both gamepad SHM channels move off named Global\ objects (openable by any sibling LocalService) to UNNAMED sections/events whose handles the host DuplicateHandles into the driver's verified WUDFHost with least access — frame delivery over the SYSTEM+admins-only IOCTL_SET_FRAME_CHANNEL, pads over a 32-byte named bootstrap mailbox (pid + handle value only, DoS-bounded; HID minidrivers have no control device). Driver-validated pad_index kills cross-pad redirects; v1↔v2 mixes fail closed with diagnosis logs on both sides. Sibling-LocalService denial proven empirically (design/idd-push-security.md, design/gamepad-channel-sealing.md). Driver-side raw ops now live behind pf-umdf-util (checked shm accessors, the forbid(unsafe_code) ChannelClient state machine, WDF request tokens) — the pad drivers' logic is 100% safe Rust; whole drivers workspace clippy-gated in CI. driver install --gamepad now sweeps SWD\punktfunk phantom devnodes: a re-created SwDevice REVIVES the old devnode with its previously-bound driver (never re-ranks), so an upgrade otherwise leaves the old driver serving — or, across the v1→v2 fence, a dead pad (found live on the RTX box). On-glass validated on the RTX 4090 box: frame path 7007 frames p50 2.06 ms cross-machine; DualSense + XUSB "sealed pad channel mapped"/proto=2 attach via both the test harness and a real streaming session; phantom-sweep repro. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -93,6 +93,8 @@ pub unsafe fn dispatch(request: WDFREQUEST, ioctl_code: u32) {
|
||||
}
|
||||
// SAFETY: `request` is the framework WDFREQUEST.
|
||||
control::IOCTL_SET_RENDER_ADAPTER => unsafe { set_render_adapter(request) },
|
||||
// SAFETY: `request` is the framework WDFREQUEST.
|
||||
control::IOCTL_SET_FRAME_CHANNEL => unsafe { set_frame_channel(request) },
|
||||
_ => complete(request, STATUS_NOT_FOUND),
|
||||
}
|
||||
}
|
||||
@@ -148,11 +150,49 @@ unsafe fn add(request: WDFREQUEST) {
|
||||
adapter_luid_high: luid_high,
|
||||
target_id,
|
||||
resolved_monitor_id: monitor_id,
|
||||
// This WUDFHost's pid — where the host duplicates the sealed frame channel's handles INTO
|
||||
// (`ProcessSharingDisabled`: this process is exclusively ours and dies with the device).
|
||||
wudf_pid: std::process::id(),
|
||||
};
|
||||
// SAFETY: `request` is the framework WDFREQUEST.
|
||||
unsafe { write_output_complete(request, &reply) };
|
||||
}
|
||||
|
||||
/// `IOCTL_SET_FRAME_CHANNEL`: adopt the handle values the host duplicated into this process and stash
|
||||
/// them on the target monitor for the swap-chain worker to attach with. The ownership contract with
|
||||
/// the host is **adopt-on-success only**: this driver owns (and eventually closes) the handles iff the
|
||||
/// IOCTL completes successfully; on ANY error completion it leaves them untouched, because the host
|
||||
/// reaps its remote duplicates whenever the IOCTL fails — a close on both sides would double-close
|
||||
/// values the OS may already have reused for unrelated handles.
|
||||
///
|
||||
/// # Safety
|
||||
/// `request` is the framework `WDFREQUEST`.
|
||||
unsafe fn set_frame_channel(request: WDFREQUEST) {
|
||||
// SAFETY: `request` is the framework WDFREQUEST.
|
||||
let Some(req) = (unsafe { read_input::<control::SetFrameChannelRequest>(request) }) else {
|
||||
complete(request, STATUS_INVALID_PARAMETER);
|
||||
return;
|
||||
};
|
||||
// A malformed request adopts nothing (no FrameChannel is built, so no Drop can close anything).
|
||||
let Some(ch) = crate::frame_transport::FrameChannel::from_request(&req) else {
|
||||
complete(request, STATUS_INVALID_PARAMETER);
|
||||
return;
|
||||
};
|
||||
match crate::monitor::set_frame_channel(req.target_id, ch) {
|
||||
Ok(()) => complete(request, STATUS_SUCCESS),
|
||||
Err(ch) => {
|
||||
dbglog!(
|
||||
"[pf-vd] SET_FRAME_CHANNEL: no monitor with target_id {} — rejecting (host reaps the handles)",
|
||||
req.target_id
|
||||
);
|
||||
// NOT adopted: disarm the channel so its Drop does NOT close the handles (see the contract
|
||||
// above — the host's error path reaps them remotely).
|
||||
ch.into_unowned();
|
||||
complete(request, STATUS_NOT_FOUND);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// `IOCTL_REMOVE`: depart + drop the monitor for the given session id.
|
||||
///
|
||||
/// # Safety
|
||||
|
||||
Reference in New Issue
Block a user