Skip to content

refactor(native): hyperrs-elfsum crate + single native/ Cargo workspace - #106

Merged
markovejnovic merged 10 commits into
mainfrom
refactor/elfsum
Nov 1, 2026
Merged

markovejnovic merged 10 commits into
mainfrom
refactor/elfsum

Conversation

@markovejnovic

@markovejnovic markovejnovic commented Oct 31, 2026 •

Copy link
Copy Markdown
Contributor

What

Folds the meta constants crate, src/checksum.rs, and xtask's zero/hash/write logic into one crate, hyperrs-elfsum (native/hyperrs-elfsum/).

  • Default build (what the helper links, no deps): Digest, Slot::{get, hex}, and a checksum!() expression macro that declares the #[link_section = ".note.sum"] #[used] static in the calling crate and returns &'static Slot (invoke once per binary: two expansions make a 64-byte section, which stamping rejects with WrongSize).
  • stamp feature (blake3 + object + thiserror, used by xtask): Elf::read validates once that .note.sum exists, is exactly 32 bytes, and lies inside the file; the resulting Elf then offers an infallible stamp() (only for mutable buffers). Section bounds are checked by object (section.data()), the size by TryFrom<&[u8]> for &[u8; 32]; errors are a typed Error.

xtask's stamp.rs is now just build → static-link check → Elf::read(..)?.stamp() → write.

Why

  • One home for the section name/length. The link_section literal now lives only inside the crate's macro, not hand-mirrored in the helper.
  • Slot::get reads via read_volatile. Before, the slot was a plain immutable all-zero static, which the compiler may constant-fold, so version could report zeros even after stamping (unverified on a real build; see below).
  • The stamping logic becomes property-testable.

The digest algorithm is unchanged (BLAKE3 of the file with the slot zeroed), so existing stamps and Hyper.SuidHelper.Expected stay compatible.

Tests

Inline in the crate, per the new inline-tests direction:

  • after stamping, the stored slot equals the image digest; stamping is idempotent;
  • digest equals BLAKE3 of the zeroed image (oracle against the old algorithm);
  • digest ignores slot contents;
  • flipping any byte outside the slot breaks the stamp;
  • any non-32-byte slot gives WrongSize;
  • missing section / non-ELF input are refused;
  • Linux-only: the checksum!() macro lands in .note.sum with the right size.

CI runs these via the new workspace job (below).

Verification status

  • ✅ hyperrs-elfsum tests (9/9) pass on macOS; clippy -D warnings clean for elfsum, xtask, and the helper (aarch64-musl, with and without insecure_mode).
  • ✅ cargo tree: the release helper links hyperrs-elfsum without blake3/object.
  • ⚠️ Not yet run on Linux: the macro section test, the helper's suites, and a real stamp. To check the constant-folding fix: cargo xtask stamp && target/hyper-suidhelper version should print a non-zero checksum.

Follow-ups (not in this PR)

  • No doc comments in the new crate yet; Slot::get's unsafe needs a SAFETY comment.
  • Stale comments: Cargo.toml above default-members ("only touch the helper itself"), and xtask/src/stamp.rs mentions a verifier that re-hashes, which does not exist (the runtime check compares the helper's self-reported checksum).

Second commit: native/ is one Cargo workspace

  • Members: guest-agent, hyperrs-elfsum, suidhelper, suidhelper/xtask, sharing one Cargo.lock, target/, rust-toolchain.toml and .config/nextest.toml.
  • The lock is the union of the two old locks; cargo metadata --locked passes and no dependency versions changed.
  • Release profiles must live at the workspace root. The helper keeps release (opt-level = "z", strip). The guest agent's lto/panic = "abort"/codegen-units = 1 can't be set per package, so they move to a release-guest profile, which :guest_agent_build now uses. Neither binary's build settings change.
  • ⚠️ The guest agent now builds on the pinned nightly (one toolchain per workspace). It was on the runner's stable before. Clippy is clean for it on nightly.
  • CI: Rust (guest-agent) and Rust (suidhelper) are merged into one Rust (native workspace) job: fmt --all, clippy --workspace, nextest --workspace with coverage. This adds the guest agent's tests and xtask, which CI didn't run before. Required status checks in branch protection need renaming.
  • Paths that followed per-crate target/ dirs are updated: the Mix stamp compiler, mix suidhelper.install, the guest-agent compiler, xtask's target_dir(), the integration coverage export, and release.yml.
  • release.yml was still bumping the deleted meta/Cargo.toml (broken by the first commit); it now bumps native/hyperrs-elfsum/Cargo.toml.
  • The stable-toolchain rustup target add x86_64-unknown-linux-musl steps in the elixir/integration jobs are dropped; the nightly toolchain file already installs both musl targets.
  • ⚠️ Not verified locally: mix compile (stamp + guest build) and mix format (needs deps on this machine).

Fold the `meta` constants crate, `src/checksum.rs` and xtask's
zero/hash/write logic into one crate. The `slot!` macro owns the
`.note.sum` literal, `Slot::get` reads via `read_volatile` so the
stamped digest cannot be constant-folded to zeros, and the `stamp`
feature (blake3 + object) stays out of the release helper.

Stamping/verification are now pure functions over `&[u8]`, covered
by inline property tests. The digest algorithm is unchanged.
@codecov

codecov Bot commented Oct 31, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ All tests successful. No failed tests found.

📢 Thoughts on this report? Let us know!

Move hyperrs-elfsum to native/hyperrs-elfsum and put guest-agent,
hyperrs-elfsum, suidhelper and xtask in a single workspace with one
Cargo.lock, target/, rust-toolchain.toml and nextest config. The lock is
the union of the two old locks; no dependency versions changed.

Release profiles now live at the workspace root. The helper keeps its
profile as `release`; the guest agent's lto/panic=abort/codegen-units
settings move to a `release-guest` profile so neither binary changes.

CI: the guest-agent and suidhelper jobs become one workspace job that
runs fmt, clippy and nextest across every crate (guest-agent and xtask
were previously not tested in CI). Paths in the Mix compilers, install
task, integration coverage export and release workflow follow the
shared target/. release.yml now bumps hyperrs-elfsum instead of the
deleted meta crate.
@markovejnovic markovejnovic changed the title refactor(suidhelper): extract checksum stamping into hyperrs-elfsum refactor(native): hyperrs-elfsum crate + single native/ Cargo workspace Oct 31, 2026
@github-actions

github-actions Bot commented Oct 31, 2026 •

Copy link
Copy Markdown

Test Results

    4 files  ± 0  226 suites  +3   2m 27s ⏱️ -58s
  713 tests +22  713 ✅ +22    0 💤 ±0  0 ❌ ±0 
1 194 runs  +22  713 ✅ +22  481 💤 ±0  0 ❌ ±0 

Results for commit 24f3019. ± Comparison against base commit 7c4d054.

♻️ This comment has been updated with latest results.

@markovejnovic
markovejnovic marked this pull request as ready for review October 31, 2026 20:14
@markovejnovic
markovejnovic merged commit 6f159cb into main Nov 1, 2026
8 checks passed
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.

1 participant