From 00d17b9d1a6aa7ff13075a529a42363cbf014839 Mon Sep 17 00:00:00 2001 From: Mariano Abad Date: Tue, 21 Jul 2026 18:02:50 -0300 Subject: [PATCH] drm: source libdrmtap from rustdesk-org, pinned by sha (review 3.4) The dlopened .so is loaded into the CAP_SYS_ADMIN root service, so it should come from the maintainer-owned repo, not a personal fork. rustdesk-org/libdrmtap main is already synced to the exact commit we pin (c9cf0938 = v0.4.13) but carries no release tag, so point both build.py and the CI job at rustdesk-org and track main with the immutable commit pinned via DRMTAP_SHA. The post-clone sha check makes this fail-closed: main moving off the pinned commit fails the build instead of silently swapping the .so. The CI ref guard now accepts a vX.Y.Z tag or main (a loose branch is still rejected). Switch DRMTAP_REF to a tag if rustdesk-org later publishes one. --- .github/workflows/flutter-build.yml | 37 ++++++++++++++--------------- build.py | 24 ++++++++++--------- 2 files changed, 31 insertions(+), 30 deletions(-) diff --git a/.github/workflows/flutter-build.yml b/.github/workflows/flutter-build.yml index d5895ab10..8f1853f67 100644 --- a/.github/workflows/flutter-build.yml +++ b/.github/workflows/flutter-build.yml @@ -1712,35 +1712,34 @@ jobs: apt-get install -y ninja-build libdrm-dev libegl1-mesa-dev libgles2-mesa-dev python3-pip python3 -m pip install --upgrade pip python3 -m pip install 'meson>=0.57,<0.62' - # libdrmtap is sourced by cloning the rustdesk-org fork at a pinned + # libdrmtap is sourced by cloning the maintainer-owned rustdesk-org repo at a pinned # ref (it is no longer a git submodule). DRMTAP_REPO / DRMTAP_REF are # exported so build.py reuses the exact same source. We clone + build # the .so here and hand it to build.py via DRMTAP_PREBUILT_DIR, because # a later build step in this container disturbs the working tree. - # DRMTAP_REF is an EXACT release tag (vX.Y.Z), NOT a branch, and it is verified - # against the pinned immutable commit DRMTAP_SHA after clone (below). The drm backend - # has NO libdrmtap-sys Cargo dependency: rustdesk dlopens this .so at runtime - # (drmtap_dl.rs checks ABI-major). Keep DRMTAP_SHA in sync with the tag on every bump. - # Source-of-truth fork that publishes the pinned tag (rustdesk-org syncs from it; switch - # this once rustdesk-org carries v0.4.13). - export DRMTAP_REPO="https://github.com/fxd0h/libdrmtap" - export DRMTAP_REF="v0.4.13" - # Literal (not overridable by an inherited env var) so the tag/commit pair is immutable in CI. + # rustdesk-org has no release tag yet, so DRMTAP_REF tracks `main` and the exact commit + # is pinned by DRMTAP_SHA, verified after clone (below): a moving `main` fails the build + # instead of silently swapping the root-loaded .so. The drm backend has NO libdrmtap-sys + # Cargo dependency: rustdesk dlopens this .so at runtime (drmtap_dl.rs checks ABI-major). + # Keep DRMTAP_SHA in sync on every bump; switch DRMTAP_REF to an immutable vX.Y.Z tag if + # rustdesk-org later publishes one. + export DRMTAP_REPO="https://github.com/rustdesk-org/libdrmtap" + export DRMTAP_REF="main" + # Literal (not overridable by an inherited env var) so the ref/commit pair is immutable in CI. export DRMTAP_SHA="c9cf0938f3b10a3d4a9eeb9c6f97aaa1606c6b4a" - # Guard: refuse a loose/branch ref so a moving `main` can never silently - # 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 + # Guard: accept only an exact vX.Y.Z tag OR the literal `main`, so a random/loose branch + # is still rejected; the DRMTAP_SHA check below is the real anchor (it fails the build if + # `main` -- or a tag -- resolves to anything other than the pinned immutable commit). + if ! printf '%s' "$DRMTAP_REF" | grep -qE '^(v[0-9]+\.[0-9]+\.[0-9]+|main)$'; then + echo "FATAL: DRMTAP_REF must be a pinned vX.Y.Z tag or main, 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 test -f third_party/libdrmtap/meson.build || { echo "FATAL: libdrmtap source missing"; exit 1; } - # Pin the immutable commit, not only the tag name: `git clone --branch` follows a - # mutable tag, so a moved or compromised v0.4.13 could swap the root-loaded .so while - # the regex above still passes. Verify the cloned HEAD is exactly the pinned SHA. + # Pin the immutable commit, not only the ref name: `git clone --branch` follows a mutable + # ref (a branch like `main` even more than a tag), so a moved or compromised ref could + # swap the root-loaded .so while the regex above still passes. Verify HEAD is the pinned SHA. got_sha="$(git -C third_party/libdrmtap rev-parse HEAD)" if [ "$got_sha" != "$DRMTAP_SHA" ]; then echo "FATAL: libdrmtap $DRMTAP_REF resolved to $got_sha, expected $DRMTAP_SHA (moved/compromised tag?)"; exit 1 diff --git a/build.py b/build.py index 4d10b9771..6740d8920 100755 --- a/build.py +++ b/build.py @@ -335,19 +335,21 @@ def ffi_bindgen_function_refactor(): # libdrmtap is fetched at build time by cloning the rustdesk-org fork at a pinned # ref — the same way rustdesk sources its other native build deps (vcpkg, -# flutter_rust_bridge, ...), rather than carrying a git submodule. The ref is an -# EXACT release tag (vX.Y.Z), NOT a moving branch, and it is the ONLY pin for the -# drm backend: rustdesk dlopens this .so at runtime and does not depend on the -# libdrmtap-sys crate (whose build.rs would statically link the C tree, a helper and +# flutter_rust_bridge, ...), rather than carrying a git submodule. It is the ONLY +# pin for the drm backend: rustdesk dlopens this .so at runtime and does not depend on +# the libdrmtap-sys crate (whose build.rs would statically link the C tree, a helper and # libdrm/seccomp/cap). Override the repo/ref via env (DRMTAP_REPO / DRMTAP_REF) for # local testing or another fork. -# Source-of-truth fork that publishes the pinned release tag (rustdesk-org syncs from it; point -# DRMTAP_REPO there once it carries the tag). -LIBDRMTAP_REPO = os.environ.get('DRMTAP_REPO', 'https://github.com/fxd0h/libdrmtap') -LIBDRMTAP_REF = os.environ.get('DRMTAP_REF', 'v0.4.13') -# The immutable commit the release tag must resolve to. `git clone --branch` follows a mutable tag, -# so verifying this after clone catches a moved/compromised tag swapping the .so. Keep in sync with -# LIBDRMTAP_REF on every bump (override via DRMTAP_SHA together with DRMTAP_REF for a local fork). +# Point at the maintainer-owned rustdesk-org repo. It has no release tag yet, so track its `main` +# branch and pin the exact commit via LIBDRMTAP_SHA below: the post-clone sha check makes this +# fail-closed, so `main` moving off the pinned commit fails the build instead of silently shipping a +# different .so. If rustdesk-org later publishes an immutable vX.Y.Z tag, set DRMTAP_REF to it. +LIBDRMTAP_REPO = os.environ.get('DRMTAP_REPO', 'https://github.com/rustdesk-org/libdrmtap') +LIBDRMTAP_REF = os.environ.get('DRMTAP_REF', 'main') +# The immutable commit the ref must resolve to. `git clone --branch` follows a mutable ref (a branch +# even more than a tag), so verifying this after clone catches a moved/compromised ref swapping the +# .so. Keep in sync with LIBDRMTAP_REF on every bump (override via DRMTAP_SHA together with DRMTAP_REF +# for a local fork). This commit is libdrmtap v0.4.13. LIBDRMTAP_SHA = os.environ.get('DRMTAP_SHA', 'c9cf0938f3b10a3d4a9eeb9c6f97aaa1606c6b4a')