Bind sandbox handoff authority and restore verifier gates
This commit is contained in:
parent
cf914bdf51
commit
49d5def1a9
2 changed files with 951 additions and 170 deletions
|
|
@ -163,6 +163,13 @@ pub struct ProcessOwnershipContext {
|
|||
pub slot: HostProcessOwnershipSlot,
|
||||
}
|
||||
|
||||
pub struct AcknowledgedChildAcquisition<'target> {
|
||||
pub expected_parent: PidfsProcessIdentityV1,
|
||||
pub ownership: ProcessOwnershipContext,
|
||||
pub target: &'target TargetCommand,
|
||||
pub standard_io: ChildStandardIo,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct RetainedProcess {
|
||||
pidfd: OwnedFd,
|
||||
|
|
@ -366,10 +373,12 @@ impl ChildBroker {
|
|||
Acknowledge: FnOnce(StagedProcessOwnership) -> io::Result<ProcessOwnershipCommitAck>,
|
||||
{
|
||||
self.acquire_with_stdio_after_ack(
|
||||
expected_parent,
|
||||
ownership,
|
||||
target,
|
||||
standard_io,
|
||||
AcknowledgedChildAcquisition {
|
||||
expected_parent,
|
||||
ownership,
|
||||
target,
|
||||
standard_io,
|
||||
},
|
||||
stage,
|
||||
acknowledge,
|
||||
|| Ok(()),
|
||||
|
|
@ -385,10 +394,7 @@ impl ChildBroker {
|
|||
#[allow(clippy::disallowed_methods, clippy::disallowed_types)]
|
||||
pub fn acquire_with_stdio_after_ack<Stage, Acknowledge, Transition>(
|
||||
&self,
|
||||
expected_parent: PidfsProcessIdentityV1,
|
||||
ownership: ProcessOwnershipContext,
|
||||
target: &TargetCommand,
|
||||
mut standard_io: ChildStandardIo,
|
||||
acquisition: AcknowledgedChildAcquisition<'_>,
|
||||
stage: Stage,
|
||||
acknowledge: Acknowledge,
|
||||
transition: Transition,
|
||||
|
|
@ -402,14 +408,18 @@ impl ChildBroker {
|
|||
.exclusion
|
||||
.lock()
|
||||
.map_err(|_| io::Error::other("child broker lock poisoned"))?;
|
||||
require_parent_edge_standard_io(target.parent_edge(), standard_io.policy())?;
|
||||
require_parent_edge_standard_io(
|
||||
acquisition.target.parent_edge(),
|
||||
acquisition.standard_io.policy(),
|
||||
)?;
|
||||
require_default_sigchld()?;
|
||||
require_reapable_sigchld()?;
|
||||
let (release, wait) = launch_barrier()?;
|
||||
let mut command = private_role_command(WRAPPER_ROLE);
|
||||
append_parent_identity(&mut command, expected_parent);
|
||||
target.append_to(&mut command);
|
||||
append_parent_identity(&mut command, acquisition.expected_parent);
|
||||
acquisition.target.append_to(&mut command);
|
||||
command.stdin(wait.into_stdio());
|
||||
let mut standard_io = acquisition.standard_io;
|
||||
if let Some(stdout) = standard_io.stdout.take() {
|
||||
command.stdout(stdout);
|
||||
}
|
||||
|
|
@ -424,10 +434,10 @@ impl ChildBroker {
|
|||
Err(error) => return fail_before_pidfd(release, &mut child, error),
|
||||
};
|
||||
let staged = StagedProcessOwnership::v1(
|
||||
ownership.domain_id,
|
||||
ownership.generation_id,
|
||||
ownership.coordinator_id,
|
||||
ownership.slot,
|
||||
acquisition.ownership.domain_id,
|
||||
acquisition.ownership.generation_id,
|
||||
acquisition.ownership.coordinator_id,
|
||||
acquisition.ownership.slot,
|
||||
process.identity,
|
||||
);
|
||||
if let Err(error) = stage(staged) {
|
||||
|
|
|
|||
|
|
@ -13,8 +13,9 @@ use lazaret_core::records::{
|
|||
HostProcessOwnershipSlot, ProcessOwnershipCommitAck, StagedProcessOwnership,
|
||||
};
|
||||
use lazaret_linux::process::{
|
||||
ChildStandardIo, ProcessOwnershipContext, TargetCommand, append_parent_identity, child_broker,
|
||||
current_process_identity, dispatch_private_process_role, verify_direct_child_pidfd,
|
||||
AcknowledgedChildAcquisition, ChildStandardIo, ProcessOwnershipContext, TargetCommand,
|
||||
append_parent_identity, child_broker, current_process_identity, dispatch_private_process_role,
|
||||
verify_direct_child_pidfd,
|
||||
};
|
||||
use rustix::pipe::{PipeFlags, pipe_with};
|
||||
use rustix::process::{PidfdFlags, pidfd_open};
|
||||
|
|
@ -45,6 +46,7 @@ fn exit(result: std::io::Result<()>) -> ExitCode {
|
|||
fn run_all() -> std::io::Result<()> {
|
||||
successful_acquisition()?;
|
||||
acknowledged_transition_precedes_exact_wrapper_release()?;
|
||||
failed_acknowledged_transition_refuses_exact_wrapper_release()?;
|
||||
lifetime_pipe_descriptor_contract()?;
|
||||
failed_stages_and_acknowledgments()?;
|
||||
production_wrapper_refuses_former_harness_path()?;
|
||||
|
|
@ -54,6 +56,29 @@ fn run_all() -> std::io::Result<()> {
|
|||
concurrent_acquisitions_serialize()
|
||||
}
|
||||
|
||||
#[allow(clippy::disallowed_methods, clippy::disallowed_types)]
|
||||
fn failed_acknowledged_transition_refuses_exact_wrapper_release() -> std::io::Result<()> {
|
||||
let target_marker = marker("failed-transition-target");
|
||||
let target = TargetCommand::new("/usr/bin/touch").argument(&target_marker);
|
||||
let result = child_broker().acquire_with_stdio_after_ack(
|
||||
AcknowledgedChildAcquisition {
|
||||
expected_parent: current_process_identity()?,
|
||||
ownership: context(),
|
||||
target: &target,
|
||||
standard_io: ChildStandardIo::inherit(),
|
||||
},
|
||||
|_| Ok(()),
|
||||
|staged| Ok(ProcessOwnershipCommitAck::v1(staged)),
|
||||
|| Err(std::io::Error::other("handoff authority changed")),
|
||||
);
|
||||
if result.is_ok() || target_marker.exists() {
|
||||
return Err(std::io::Error::other(
|
||||
"failed transition released the exact wrapper",
|
||||
));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[allow(clippy::disallowed_methods, clippy::disallowed_types)]
|
||||
fn acknowledged_transition_precedes_exact_wrapper_release() -> std::io::Result<()> {
|
||||
let target_marker = marker("transition-target");
|
||||
|
|
@ -62,10 +87,12 @@ fn acknowledged_transition_precedes_exact_wrapper_release() -> std::io::Result<(
|
|||
let acknowledged = std::cell::Cell::new(false);
|
||||
let target = TargetCommand::new("/usr/bin/touch").argument(&target_marker);
|
||||
let process = child_broker().acquire_with_stdio_after_ack(
|
||||
parent,
|
||||
context(),
|
||||
&target,
|
||||
ChildStandardIo::inherit(),
|
||||
AcknowledgedChildAcquisition {
|
||||
expected_parent: parent,
|
||||
ownership: context(),
|
||||
target: &target,
|
||||
standard_io: ChildStandardIo::inherit(),
|
||||
},
|
||||
|ownership| {
|
||||
staged.set(Some(ownership));
|
||||
Ok(())
|
||||
|
|
|
|||
Loading…
Reference in a new issue