Skip to content

fix: verify macOS FFmpeg download with a pinned SHA256 (#172) - #192

Merged
thcp merged 1 commit into
mainfrom
fix/macos-ffmpeg-checksum-172
Jun 5, 2026
Merged

thcp merged 1 commit into
mainfrom
fix/macos-ffmpeg-checksum-172

Conversation

@thcp

@thcp thcp commented Jun 5, 2026

Copy link
Copy Markdown
Collaborator

Fixes #172.

Problem

macOS setup downloaded ffmpeg/ffprobe from evermeet.cx's rolling getrelease/latest URLs, extracted them, marked them executable, and ran them - with no integrity check. The Windows path already verifies a SHA256 companion before extracting, so a corrupt or tampered macOS download could be executed as the user during setup.

Why not mirror the Windows trick

Windows fetches gyan.dev's .sha256 companion at runtime and compares. evermeet publishes no SHA companion - only a GPG signature and a size. So there is no same-flow hash to fetch.

Approach (chosen: pin a known hash)

Pin a specific evermeet versioned build and its SHA256, captured at build time, and verify the archive before it is extracted or chmod'd.

  • Switched the macOS URLs from getrelease/latest to the pinned versioned zips (ffmpeg-8.1.1.zip, ffprobe-8.1.1.zip) so the pinned hash stays valid.
  • The pinned hashes were captured from evermeet's TLS endpoint and the download sizes matched evermeet's signed release-info JSON (26007615 / 25910701 bytes).
  • verify_pinned_sha256() rejects a mismatch and deletes the file so a bad binary is never run.
  • expected_ffmpeg_sha256() enforces the pinned hash for the default URLs and honours an explicit STEMDECK_FFMPEG_SHA256 / STEMDECK_FFPROBE_SHA256 for custom override URLs, otherwise skips - matching the Windows override behaviour.
  • Reuses the existing sha256_file() helper and sha2 crate; no new dependencies.

Trade-off: the version + both hashes must be bumped together when updating FFmpeg, and evermeet eventually removes old versioned builds (the existing STEMDECK_FFMPEG_URL override remains an escape hatch). Re-hosting the binaries on our own GitHub releases for retention is a sensible future step.

Verification

  • 4 new Rust unit tests (match accepted + file kept; mismatch rejected + file removed; None skips; default URL pins / unknown override skips). cargo test: 9 passed. cargo fmt --check and cargo check clean.
  • Real-world: re-downloaded both versioned zips and confirmed the SHA256 values and that they match evermeet's published sizes.

Note: CI does not run cargo clippy; pre-existing clippy warnings in unrelated CUDA/torch code (surfaced only by newer local toolchains) are out of scope here.

File: desktop/src-tauri/src/main.rs.

The macOS setup downloaded ffmpeg and ffprobe from evermeet.cx's rolling
getrelease/latest URLs, extracted them, marked them executable, and ran
them - with no integrity check. The Windows path already verifies a SHA256
companion before extracting; macOS had no equivalent, so a corrupt or
tampered download could be executed as the user during setup.

evermeet publishes no .sha256 companion (only a GPG signature and a size),
so the runtime fetch-and-compare trick used for gyan.dev on Windows does not
apply. Instead, pin a specific evermeet versioned build (ffmpeg/ffprobe
8.1.1) and its SHA256, captured at build time, and verify the archive before
it is extracted or chmod'd. The download sizes matched evermeet's signed
release-info JSON when the hashes were captured.

- Switch the macOS URLs from getrelease/latest to the pinned versioned zips
  so the pinned hash stays valid.
- verify_pinned_sha256() rejects a mismatch and deletes the file so a bad
  binary is never run; expected_ffmpeg_sha256() enforces the pinned hash for
  the default URLs and honours an explicit STEMDECK_FFMPEG_SHA256 /
  STEMDECK_FFPROBE_SHA256 for custom override URLs (else skips, matching the
  Windows override behaviour).
- Reuses the existing sha256_file() helper and sha2 crate.

Adds 4 Rust unit tests (match accepted, mismatch removes the file, None
skips, default-URL pins / unknown override skips). cargo test and cargo fmt
pass; cargo check is clean.

Bump the version and BOTH pinned hashes together when updating FFmpeg.
@thcp
thcp marked this pull request as ready for review June 5, 2026 12:26
@thcp
thcp merged commit 471cafd into main Jun 5, 2026
@thcp
thcp deleted the fix/macos-ffmpeg-checksum-172 branch June 5, 2026 12:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

macOS FFmpeg download runs without checksum verification

1 participant