From 2aae8955f825fc7bfc0ea59d8d0cf1f3a1aacb98 Mon Sep 17 00:00:00 2001 From: Mariano Abad Date: Sat, 25 Jul 2026 22:36:55 -0300 Subject: [PATCH] docs: list every case that selects the CPU-converted frame path The security document described the CPU fallback without saying when it is taken, and the multi-GPU safety fallback added in this branch was not mentioned at all. Enumerate the four cases, including the one where the service could not name the exporting GPU on a host with several render nodes, and note that a single-render-node host keeps the DMA-BUF path. --- DRM_CAPTURE_SECURITY.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/DRM_CAPTURE_SECURITY.md b/DRM_CAPTURE_SECURITY.md index fd8b2ded9..ee36e64d8 100644 --- a/DRM_CAPTURE_SECURITY.md +++ b/DRM_CAPTURE_SECURITY.md @@ -75,6 +75,18 @@ unprivileged one presents) but reuses RustDesk's own hardened IPC. reading but cannot write it. The **CPU fallback path** instead carries plain packed-BGRA bytes over the same authorized socket (no fd passing, no shared memory). +- **When the CPU fallback is chosen.** The split path is the default; the + consumer asks the service for the CPU-converted frame in three cases: the + `.so` predates the split (no `drmtap_open_render` / `drmtap_convert_dmabuf`), + no render node can be opened for this seat, or a previous convert on this + display already failed. A fourth case is a **multi-GPU safety fallback**: if + the service could not name the render node of the GPU that exports the scanout + (an older `libdrmtap` without `drmtap_render_node`) and the host has more than + one render node, the consumer refuses to guess one, because importing a scanout + on a device that did not export it can succeed and return corrupted pixels + rather than fail. The conversion then happens in the service, on the device it + already has open, so it is correct by construction. Hosts with a single render + node have nothing to pick wrong and keep the DMA-BUF fast path. ## Deployment