You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Signed-mode admission is malleable: rollback + mix-and-match of independently-signed artifacts #2
In ed25519 signed mode, admission pins a long-term release public key, not a specific artifact hash, so any artifact signed by that key is accepted (this is what enables "re-sign, reboot" roll-forward). An actor who controls the serving endpoint(s)/mirrors -- but does NOT hold the private key -- cannot forge a payload, but CAN mix and match knowledge of previously-signed artifacts. Filing to track; this is a design decision, not a code bug.
What an endpoint controller can do (no forgery)
Rollback / downgrade. Serve an OLD but validly-signed payload (e.g. a previous stage2 / UKI with a since-patched vulnerability). The pinned key still verifies it, and there is no version or monotonic counter, so the downgrade is invisible to admission.
Mix-and-match. The payload and its signed args (args_url / args_sig_url) are signed INDEPENDENTLY with no binding between them. Serve the payload from release A with the signed args from release B -- both signatures verify, but the combination was never intended.
Strip. Depending on config, drop optional signed inputs (the actor controls what each URL returns), reverting to inline / default behavior. (Note: outright omitting a required args_url fetch fails closed; the concern is serving a stale-but-signed value.)
Scope
Applies to both stages: stage0 _stage1 (UKI + optional args) and stage1 _stage2 (payload + optional args). Threat actor = the endpoint/mirror controller, not a payload forger.
Not mitigated by PCR 14: measurement records what actually ran, so a relying party pinning an exact hash detects a rollback -- but the "trust the key, roll forward" model deliberately does not pin hashes, which is exactly where this bites.
Directions to consider (for later)
Sign a single manifest binding {payload hash, args hash, version/counter} so the pieces cannot be recombined and the version is authenticated.
A monotonic version / min-version in the signed data plus a persisted floor for anti-rollback (needs trusted storage, e.g. a TPM NV counter -- non-trivial).
Bind args to the payload (sign args together with the payload hash).
Related: the set_load_options silent-drop of a malformed signed directive (stage0 review finding #3) is part of this same args-integrity question.
Activity
stage1 admission: discriminated union (payload | manifest) + reproduc…
stage2: discriminated union (payload | manifest) with signed-manifest…
Domain-separated signatures + standalone stage0-sign signer (#8)