Skip to content

fix(attest): accept one vm_config, not competing copies - #1430

Open
kvinwang wants to merge 2 commits into
nextfrom
fix/kms-sign-cert-verified-app-info
Open

kvinwang wants to merge 2 commits into
nextfrom
fix/kms-sign-cert-verified-app-info

Conversation

@kvinwang

@kvinwang kvinwang commented Oct 3, 2026 •

Copy link
Copy Markdown
Collaborator

Problem

A reader could find the VM config in more than one place, and different readers picked different copies:

  • Request vs attestation. KMS RPCs and the verifier receive a vm_config alongside an attestation that also carries one. Readers took the request copy whenever it was non-empty and never compared it with the attested one.
  • Top level vs nested. dstack-attest and dstack-mr also accepted a sys-config-shaped config, with the real config serialized under a vm_config key. The SEV-SNP parser in dstack-mr preferred the top-level fields, while the decoder in dstack-attest let the nested string replace the whole config. No producer in this repo emits that shape: attestations and requests both carry the flat sys_config.vm_config.

On SEV-SNP the second split is exploitable. Suppose a SignCert request carries the genuine top-level os_image_hash plus a nested {"os_image_hash": <other>}. Authorization checks the genuine hash against the launch measurement, and the certificate's app-info extension then claims <other>.

Fix

  • dstack_attest::resolve_vm_config(external, embedded): with one copy, use it; with two, require them to be identical. decode_vm_config, the SEV-SNP app-info decoder, the KMS SNP boot-info path and the verifier's launch binding all go through it.
  • Drop the nested vm_config shape from dstack-attest and dstack-mr, so a config has one layout and every field has one source. Inputs in the nested shape no longer parse.

Honest requests are unaffected, because every in-tree caller fills both copies from the same sys_config.vm_config string.

Verification

  • New KMS test: build_boot_info_for_attestation rejects a request vm_config that differs from the attested one and accepts an identical copy.
  • cargo test --all-features passes for dstack-attest, dstack-mr, dstack-kms and dstack-verifier. cargo check --workspace --all-features --tests passes, and clippy (-D warnings) is clean on the touched crates.

@kvinwang kvinwang changed the title fix(kms): stamp the verified os_image_hash on SEV-SNP signed certs fix(attest): require every copy of the vm_config to agree Oct 3, 2026
@kvinwang
kvinwang force-pushed the fix/kms-sign-cert-verified-app-info branch 2 times, most recently from 891b798 to 88485ce Compare October 3, 2026 02:15
@kvinwang kvinwang changed the title fix(attest): require every copy of the vm_config to agree fix(attest): accept one vm_config, not competing copies Oct 3, 2026
@kvinwang kvinwang closed this Oct 3, 2026
@kvinwang
kvinwang force-pushed the fix/kms-sign-cert-verified-app-info branch from a24ab30 to 3c87784 Compare October 3, 2026 02:27
@kvinwang kvinwang reopened this Oct 3, 2026

This branch has not been deployed

No deployments
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