review: serialize runtime event emission; document RTMR3/TCB verification scope#706
Merged
Conversation
…tion scope emit_runtime_event appended to the event log and extended RTMR3 without synchronization. Concurrent emit_event RPCs could interleave their log writes and extend_rtmr calls, making the on-disk log order diverge from the RTMR extension order and breaking RTMR3 replay during quote verification. Guard the whole critical section with a process-global mutex so log order always matches extension order. Also document two intentional verification scoping decisions in the security model: why only RTMR3 is replayed from an event log (boot-time RTMR0-2 events have no downstream consumer and are stripped at the source), and why TCB status is surfaced rather than gated (left to downstream policy; only Revoked is rejected, by dcap-qvl).
Contributor
There was a problem hiding this comment.
Pull request overview
This PR hardens TDX attestation verification reliability by preventing concurrent runtime-event emission from producing an event log ordering that cannot reproduce the quoted rt_mr3, and it documents intentional design scope choices in quote verification (RTMR3-only replay and surfacing—rather than gating on—TCB status).
Changes:
- Serialize runtime event emission by guarding the “append event log + extend RTMR3” critical section with a process-global mutex.
- Add “Verification Design Notes” to the security model documentation explaining RTMR3-only replay and TCB-status handling.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
dstack-attest/src/lib.rs |
Adds a process-global mutex to ensure runtime event log order matches RTMR3 extension order under concurrency. |
docs/security/security-model.md |
Documents why only RTMR3 is replay-verified and why TCB status is surfaced rather than used as a hard gate. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Two independent attestation-hardening changes, kept out of the cloud-merge PR (#701):
1. Serialize runtime event emission (concurrency fix)
emit_runtime_eventappended to the event log and extended RTMR3 without synchronization. The guest-agent'semit_eventRPC is reachable concurrently by multiple clients, so two concurrent calls could interleave as:Now the on-disk log order is
[A, B]but the RTMR extension order is[B, A]. RTMR is a chainedSHA384(old ‖ digest)register, so replaying the log during verification no longer reproduces the quotedrt_mr3— the whole quote becomes unverifiable. The two separatewrite_allcalls insideemit()can also be split by another writer, corrupting a log line.Fix: guard the whole critical section (log append + register extension) with a process-global
Mutex, so log order always matches extension order. The function is fully synchronous (noawait), so astd::sync::Mutexis appropriate.2. Document two intentional verification scoping decisions
Added a "Verification Design Notes" section to
docs/security/security-model.md:imr == 3at the source (into_stripped).validate_tcbenforces only hard invariants (debug off, SEAM measurements); thestatusstring is passed through for downstream policy to judgeOutOfDateetc. OnlyRevokedis rejected outright, by dcap-qvl'sis_valid(). Notes planned grace-period refactor.Testing
cargo check -p dstack-attestcargo clippy -p dstack-attest(clean)