drm: address the phase-2 split review

1- do not depend on the libdrmtap-sys crate for the pin: its build.rs statically
compiles the whole libdrmtap C tree and a CAP_SYS_ADMIN helper and links
-ldrm/-lseccomp/-lcap, which defeats the runtime-dlopen model. keep drm a pure
dlopen backend and pin the .so by the build.py DRMTAP_REF release tag, guarded by
a strict vX.Y.Z regex. drops the now-moot Cargo.lock freshness CI checks.
2- render-node-less consumers no longer lose the stream: the --server signals
need_cpu on DrmStart when it cannot open a convert context, and the --service
streams the CPU-converted frame path for that connection instead of a dma-buf fd
the consumer cannot detile (which used to fall through to a PipeWire path nobody
can approve on an unattended seat).
3- mark PipeWire initialized only after every per-display capturer is created, so
a partial failure retries instead of the flag falsely reporting a complete init.
4- reject a degenerate (zero width/height) or short CPU frame before it reaches
PixelBuffer::new (which derives stride as data.len()/height, dividing by zero).
5- keep the export-ledger epoch at DRM_DISPLAY_GENERATION so a hotplug invalidates
cached buffers (elision stays off until the recycled-fb_id inode case is handled).
6- validate the udev uevent source (kernel nl_pid, multicast) with recvmsg so a
local process cannot unicast a spoofed drm-change event to the root listener.
This commit is contained in:
Mariano Abad
2026-07-21 00:25:19 -03:00
parent 3b6914b1b2
commit 6cc426e9f5
7 changed files with 131 additions and 88 deletions

View File

@@ -1708,11 +1708,12 @@ jobs:
export DRMTAP_REPO="https://github.com/rustdesk-org/libdrmtap"
export DRMTAP_REF="v0.4.13"
# Guard: refuse a loose/branch ref so a moving `main` can never silently
# regress the pin. Only a vX.Y.Z tag is accepted.
case "$DRMTAP_REF" in
v[0-9]*.[0-9]*.[0-9]*) ;;
*) echo "FATAL: DRMTAP_REF must be a pinned vX.Y.Z tag, got '$DRMTAP_REF'"; exit 1;;
esac
# regress the pin. Only an EXACT vX.Y.Z tag is accepted (a strict anchored
# match, so values like v0.4.13-ci or a branch that resolves under
# `git clone --branch` are rejected).
if ! printf '%s' "$DRMTAP_REF" | grep -qE '^v[0-9]+\.[0-9]+\.[0-9]+$'; then
echo "FATAL: DRMTAP_REF must be a pinned vX.Y.Z tag, got '$DRMTAP_REF'"; exit 1
fi
git config --global --add safe.directory '*' || true
rm -rf third_party/libdrmtap
git clone --depth 1 --branch "$DRMTAP_REF" "$DRMTAP_REPO" third_party/libdrmtap
@@ -1731,16 +1732,9 @@ jobs:
[ -n "$(find "$DRMTAP_PREBUILT_DIR" -name 'libdrmtap.so.0.*' -type f)" ] \
|| { echo "FATAL: prebuilt libdrmtap.so missing"; exit 1; }
ls -l "$DRMTAP_PREBUILT_DIR"
# Lock-freshness guard, BEFORE the `--locked` build (which itself fails on a
# checksum mismatch): prove Cargo.lock is in sync with Cargo.toml and actually
# contains the pinned libdrmtap-sys (the integrator must have run
# `cargo update -p libdrmtap-sys --precise 0.4.13`). This turns a stale/loose lock
# into an explicit, readable failure instead of a confusing error deep in the build.
# The `=0.4.13` requirement in libs/scrap/Cargo.toml + `--locked` already force the
# exact resolved version + its checksum; this only confirms the lock was regenerated.
cargo update --locked --dry-run
cargo tree --locked --features drm -p libdrmtap-sys -i >/dev/null \
|| { echo "FATAL: Cargo.lock does not contain the pinned libdrmtap-sys (run: cargo update -p libdrmtap-sys --precise 0.4.13)"; exit 1; }
# The drm backend is pure runtime-dlopen (no libdrmtap-sys crate dependency),
# so the pin is the DRMTAP_REF tag verified above plus the prebuilt .so; there
# is nothing to assert in Cargo.lock for it.
cargo build --locked --lib $JOBS --features hwcodec,flutter,unix-file-copy-paste,drm --release
python3 ./build.py --flutter --drm --skip-cargo
for name in rustdesk-unattended-wayland*??.deb; do