Fix missing rustup and pin toolchain version
What changed, and why it matters
This commit fixes the mobile wallet's automated build process so it always uses the same Rust compiler version when building a privacy-sensitive networking component (the Tor plugin). Without the fix, the build could silently use whatever the latest 'stable' Rust release is at the time, making releases non-reproducible and potentially introducing unexpected behavior or compiler-related issues. It also copies a pre-installed Rust toolchain into the build container so the build does not fail from a missing rustup. This is a build-hardening and reliability change, not a direct fix for an active security vulnerability in the wallet itself.
Treat as a build-hardening improvement. Verify the pinned Rust version (1.96.1) is supported by the tor plugin and receives security updates; review the builder image to confirm /opt/cargo contains the expected toolchain; and consider adding a CI check that verifies the pinned toolchain string is actually patched before the Flutter build runs.
Security signals we found
Build reproducibility hardening for a privacy-critical dependency (Tor FFI plugin)
Pins a moving toolchain channel to a specific Rust version
Fixes missing rustup in containerized release build
No direct code vulnerability or exploit mechanism visible in the diff
Evidence from the diff
The release workflow now copies /opt/cargo into /tmp/skylight-cargo before setting CARGO_HOME, ensuring rustup/cargo are available inside the container. A new script, scripts/pin-tor-rust-toolchain.sh, patches the cargokit build_tool builder.dart after flutter pub get, replacing the hardcoded ‘stable’ channel with a pinned version (default 1.96.1). This makes the tor_ffi_plugin build reproducible because cargokit otherwise invokes rustup run stable cargo ..., which follows a moving target and cannot be overridden via RUSTUP_TOOLCHAIN. The change is defensive: it reduces supply-chain/compiler-variability risk for the Tor dependency but does not patch a known exploitable flaw in shipped code.
Changed components
.github/workflows/release.ymlscripts/pin-tor-rust-toolchain.shtor_ffi_plugin build via cargokitInspect captured patch +30 / −1
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 5f1eef2..cc268da 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -150,7 +150,7 @@ jobs:
-w /tmp/skylight \
-e SOURCE_DATE_EPOCH \
ghcr.io/magicgrants/skylight-wallet-builder:latest \
- bash -c "export CARGO_HOME=/tmp/skylight-cargo && flutter pub get && flutter build apk --dart-define=DEMO_MODE=true --release --split-per-abi && flutter build appbundle --dart-define=DEMO_MODE=true --release"
+ bash -c "cp -a /opt/cargo /tmp/skylight-cargo && export CARGO_HOME=/tmp/skylight-cargo && flutter pub get && bash scripts/pin-tor-rust-toolchain.sh && flutter build apk --dart-define=DEMO_MODE=true --release --split-per-abi && flutter build appbundle --dart-define=DEMO_MODE=true --release"
mkdir -p dist
cp -v build/app/outputs/flutter-apk/app-arm64-v8a-release.apk "dist/skylight-wallet-${VERSION}-arm64-v8a.apk"
diff --git a/scripts/pin-tor-rust-toolchain.sh b/scripts/pin-tor-rust-toolchain.sh
new file mode 100755
index 0000000..be19425
--- /dev/null
+++ b/scripts/pin-tor-rust-toolchain.sh
@@ -0,0 +1,29 @@
+#!/usr/bin/env bash
+#
+# Pin cargokit's Rust toolchain for a reproducible tor_ffi_plugin build.
+#
+# cargokit (used by the tor plugin) hardcodes the toolchain to "stable" and runs
+# `rustup run stable cargo ...` — a MOVING channel, so tor would be built with
+# whatever stable is latest at build time (non-reproducible across time, and
+# RUSTUP_TOOLCHAIN can't override an explicit `rustup run`). Its config only allows
+# the channel enum (stable/beta/nightly), not an exact version — so we patch the
+# default in the fetched package instead.
+#
+# Run AFTER `flutter pub get` (so the tor package is in PUB_CACHE) and BEFORE the
+# flutter build. Idempotent; safe if the string is already pinned.
+#
+set -euo pipefail
+
+TOOLCHAIN="${1:-1.96.1}"
+CACHE="${PUB_CACHE:-$HOME/.pub-cache}"
+
+n=0
+while IFS= read -r f; do
+ if grep -q "?? 'stable'" "$f"; then
+ sed -i "s/?? 'stable'/?? '$TOOLCHAIN'/" "$f"
+ n=$((n + 1))
+ fi
+done < <(find "$CACHE" -path '*/cargokit/build_tool/lib/src/builder.dart' 2>/dev/null)
+
+echo "pin-tor-rust-toolchain: set cargokit toolchain to $TOOLCHAIN in $n file(s) (PUB_CACHE=$CACHE)"
+[ "$n" -gt 0 ] || echo " (warning: no cargokit builder.dart found/patched — verify PUB_CACHE + that the string still exists)"
Why this scored 16/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.