Replace external reachability with an owned canary
This commit is contained in:
parent
0f6825c3b9
commit
31e9ab0f2d
1 changed files with 1409 additions and 1972 deletions
|
|
@ -1,12 +1,11 @@
|
|||
use super::{
|
||||
AcknowledgedChildAcquisition, CanonicalDerivedNetworkPolicy, CommittedSandboxRuntime,
|
||||
CoordinatorChannel, GitRoutingCoordinator, MountIdentity, NamespaceIdentity,
|
||||
NetworkCoordinator, NetworkProbeRequest, NetworkReadinessEvidence, PidfsProcessIdentityV1,
|
||||
PipeFlags, PreparedArtifactId, ProcessOwnershipCommitAck, ReachabilityExpectation,
|
||||
RetainedProcess, RuntimeSupervisorLaunch, SandboxCoordinator, SandboxCoordinatorError,
|
||||
SandboxHandoffAuthority, StagedProcessOwnership, StateAnchorCoordinator, SupervisorEvent,
|
||||
child_broker, cleanup_supervisor, current_process_identity, io, pipe_with,
|
||||
private_seqpacket_pair,
|
||||
CoordinatorChannel, GitRoutingCoordinator, MountIdentity, NetworkCoordinator,
|
||||
NetworkReadinessAttestation, NetworkReadinessEvidence, PidfsProcessIdentityV1, PipeFlags,
|
||||
PreparedArtifactId, ProcessOwnershipCommitAck, RetainedProcess, RuntimeSupervisorLaunch,
|
||||
SandboxCoordinator, SandboxCoordinatorError, SandboxHandoffAuthority, StagedProcessOwnership,
|
||||
StateAnchorCoordinator, SupervisorEvent, child_broker, cleanup_supervisor,
|
||||
current_process_identity, io, pipe_with, private_seqpacket_pair,
|
||||
};
|
||||
|
||||
pub struct AwaitingAttachedRunsc {
|
||||
|
|
@ -18,6 +17,7 @@ pub struct AwaitingAttachedRunsc {
|
|||
git_routing_required: bool,
|
||||
git_routing_mount: Option<MountIdentity>,
|
||||
network_evidence: Option<NetworkReadinessEvidence>,
|
||||
network_attestation: Option<NetworkReadinessAttestation>,
|
||||
runsc_command: lazaret_runtime_supervisor::sandbox::RunscCommand,
|
||||
}
|
||||
|
||||
|
|
@ -263,6 +263,7 @@ impl AwaitingAttachedRunsc {
|
|||
git_routing_required: launch.has_git_routing(),
|
||||
git_routing_mount: None,
|
||||
network_evidence: None,
|
||||
network_attestation: None,
|
||||
runsc_command: launch.runsc_command().clone(),
|
||||
})
|
||||
}
|
||||
|
|
@ -315,16 +316,11 @@ impl AwaitingAttachedRunsc {
|
|||
///
|
||||
/// # Errors
|
||||
/// Refuses event ordering, namespace mutation, or any attestation mismatch.
|
||||
pub fn receive_network_readiness<BuildProbeRequest>(
|
||||
pub fn receive_network_attestation(
|
||||
&mut self,
|
||||
network: &NetworkCoordinator<'_>,
|
||||
policy: &CanonicalDerivedNetworkPolicy,
|
||||
build_probe_request: BuildProbeRequest,
|
||||
expected_reachability: &ReachabilityExpectation,
|
||||
) -> Result<NetworkReadinessEvidence, SandboxCoordinatorError>
|
||||
where
|
||||
BuildProbeRequest: FnOnce(NamespaceIdentity) -> NetworkProbeRequest,
|
||||
{
|
||||
) -> Result<(), SandboxCoordinatorError> {
|
||||
let staged = self
|
||||
.helper_staged
|
||||
.ok_or(SandboxCoordinatorError::InvalidState(
|
||||
|
|
@ -359,32 +355,14 @@ impl AwaitingAttachedRunsc {
|
|||
attestation.runtime_supervisor,
|
||||
)?;
|
||||
network.validate_attestation(policy, &attestation)?;
|
||||
let probe_request = build_probe_request(namespace);
|
||||
if probe_request.domain_id != attestation.domain_id
|
||||
|| probe_request.generation_id != attestation.generation_id
|
||||
|| probe_request.enforcement_namespace != attestation.enforcement_namespace
|
||||
{
|
||||
if namespace != attestation.enforcement_namespace {
|
||||
return Err(SandboxCoordinatorError::InvalidState(
|
||||
"network probe request mismatches attestation",
|
||||
"network namespace changed during attestation",
|
||||
));
|
||||
}
|
||||
control.acknowledge_network_attestation(probe_request)?;
|
||||
let probe = match control.receive()? {
|
||||
SupervisorEvent::NetworkProbe(probe) => probe,
|
||||
SupervisorEvent::Refused(detail) => {
|
||||
return Err(SandboxCoordinatorError::Io(io::Error::other(detail)));
|
||||
}
|
||||
_ => {
|
||||
return Err(SandboxCoordinatorError::InvalidState(
|
||||
"Runtime Supervisor did not return the network probe",
|
||||
));
|
||||
}
|
||||
};
|
||||
let evidence =
|
||||
network.commit_readiness(policy, attestation, probe, expected_reachability)?;
|
||||
control.acknowledge_network_readiness()?;
|
||||
self.network_evidence = Some(evidence.clone());
|
||||
Ok(evidence)
|
||||
control.acknowledge_network_attestation()?;
|
||||
self.network_attestation = Some(attestation);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Receives and durably stages the exact RS child without releasing its barrier.
|
||||
|
|
@ -400,7 +378,7 @@ impl AwaitingAttachedRunsc {
|
|||
"attached runsc stage was already received",
|
||||
));
|
||||
}
|
||||
if self.helper_staged.is_some() && self.network_evidence.is_none() {
|
||||
if self.helper_staged.is_some() && self.network_attestation.is_none() {
|
||||
return Err(SandboxCoordinatorError::InvalidState(
|
||||
"attached runsc cannot start before network attestation",
|
||||
));
|
||||
|
|
@ -469,6 +447,7 @@ impl AwaitingAttachedRunsc {
|
|||
lifetime: self.lifetime.take(),
|
||||
staged,
|
||||
network_evidence: self.network_evidence.take(),
|
||||
network_attestation: self.network_attestation.take(),
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -494,6 +473,7 @@ pub struct AwaitingSandboxReadiness {
|
|||
lifetime: Option<std::os::fd::OwnedFd>,
|
||||
staged: StagedProcessOwnership,
|
||||
network_evidence: Option<NetworkReadinessEvidence>,
|
||||
network_attestation: Option<NetworkReadinessAttestation>,
|
||||
}
|
||||
|
||||
impl AwaitingSandboxReadiness {
|
||||
|
|
@ -520,13 +500,35 @@ impl AwaitingSandboxReadiness {
|
|||
pub fn commit_networked(
|
||||
mut self,
|
||||
coordinator: &SandboxCoordinator<'_>,
|
||||
network: &NetworkCoordinator<'_>,
|
||||
policy: &CanonicalDerivedNetworkPolicy,
|
||||
) -> Result<(CommittedSandboxRuntime, NetworkReadinessEvidence), SandboxCoordinatorError> {
|
||||
let evidence =
|
||||
self.network_evidence
|
||||
let attestation =
|
||||
self.network_attestation
|
||||
.take()
|
||||
.ok_or(SandboxCoordinatorError::InvalidState(
|
||||
"network readiness evidence is absent",
|
||||
"network attestation is absent",
|
||||
))?;
|
||||
let control = self
|
||||
.control
|
||||
.as_ref()
|
||||
.ok_or(SandboxCoordinatorError::InvalidState(
|
||||
"Runtime Supervisor control channel is absent",
|
||||
))?;
|
||||
let canary = match control.receive()? {
|
||||
SupervisorEvent::NetworkCanary(canary) => canary,
|
||||
SupervisorEvent::Refused(detail) => {
|
||||
return Err(SandboxCoordinatorError::Io(io::Error::other(detail)));
|
||||
}
|
||||
_ => {
|
||||
return Err(SandboxCoordinatorError::InvalidState(
|
||||
"Runtime Supervisor did not return owned-canary evidence",
|
||||
));
|
||||
}
|
||||
};
|
||||
let evidence = network.commit_readiness(policy, attestation, canary)?;
|
||||
control.acknowledge_network_readiness()?;
|
||||
self.network_evidence = Some(evidence.clone());
|
||||
let runtime = self.commit_after_probe(coordinator, Some(evidence.clone()))?;
|
||||
Ok((runtime, evidence))
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue