Own the patched runsc artifact and bind recovery identity
This commit is contained in:
parent
c474fa4a23
commit
2c420012bd
6 changed files with 1967 additions and 130 deletions
|
|
@ -40,6 +40,13 @@ use validation::{
|
|||
};
|
||||
|
||||
pub const NETWORK_NAMESPACE_PATH: &str = "/proc/self/ns/net";
|
||||
pub const RUNSC_BUILD_ID: &str = "904ab3c9bd4c99a27181076f2c9ea2fecc041db5a728c999540d6664174d2cd4";
|
||||
pub const RUNSC_BUILD_ID_BYTES: [u8; 32] = [
|
||||
144, 74, 179, 201, 189, 76, 153, 162, 113, 129, 7, 111, 44, 158, 162, 254, 204, 4, 29, 181,
|
||||
167, 40, 201, 153, 84, 13, 102, 100, 23, 77, 44, 212,
|
||||
];
|
||||
pub const RUNSC_EXECUTABLE_NAME: &str =
|
||||
"lazaret-runsc-904ab3c9bd4c99a27181076f2c9ea2fecc041db5a728c999540d6664174d2cd4";
|
||||
pub const DOMAIN_OPEN_FILE_LIMIT: u64 = 524_288;
|
||||
|
||||
const OCI_VERSION: &str = "1.2.1";
|
||||
|
|
@ -445,6 +452,7 @@ pub fn stage_host_terminal(
|
|||
|
||||
pub struct SandboxBuildRequest<'a> {
|
||||
pub configuration: &'a ResolvedDomainConfiguration,
|
||||
pub runsc_program: &'a Path,
|
||||
pub container_id: ContainerId,
|
||||
pub expected_network_namespace: NamespaceIdentity,
|
||||
pub root_process: RootProcess,
|
||||
|
|
@ -647,6 +655,7 @@ fn build_sandbox_bundle_from_source(
|
|||
request: SandboxBuildRequest<'_>,
|
||||
workspace_source: PathBuf,
|
||||
) -> Result<SandboxBundle, SandboxBuildError> {
|
||||
validate_absolute_normalized(request.runsc_program)?;
|
||||
require_network_namespace(request.expected_network_namespace)?;
|
||||
request
|
||||
.configuration
|
||||
|
|
@ -694,6 +703,7 @@ fn build_sandbox_bundle_from_source(
|
|||
let specification_json = canonical_specification_json(&specification)?;
|
||||
let bundle_authorization = Sha256::digest(&specification_json).into();
|
||||
let command = build_runsc_command(
|
||||
request.runsc_program,
|
||||
&paths,
|
||||
request.configuration.runsc_dcache(),
|
||||
bundle_authorization,
|
||||
|
|
|
|||
|
|
@ -277,12 +277,13 @@ pub(super) fn build_linux() -> Result<oci_spec::runtime::Linux, SandboxBuildErro
|
|||
}
|
||||
|
||||
pub(super) fn build_runsc_command(
|
||||
program: &Path,
|
||||
paths: &RuntimePaths,
|
||||
dcache: u32,
|
||||
bundle_authorization: [u8; 32],
|
||||
) -> RunscCommand {
|
||||
RunscCommand::new(
|
||||
"runsc",
|
||||
program,
|
||||
[
|
||||
OsString::from(format!(
|
||||
"-root={}",
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ use std::io::{self, Read};
|
|||
use std::os::fd::{AsFd, AsRawFd, OwnedFd};
|
||||
use std::os::unix::ffi::{OsStrExt, OsStringExt};
|
||||
use std::os::unix::fs::FileExt;
|
||||
use std::path::PathBuf;
|
||||
use std::path::{Component, Path, PathBuf};
|
||||
use std::time::{Duration, Instant};
|
||||
|
||||
use lazaret_core::codec::{decode, encode};
|
||||
|
|
@ -419,7 +419,7 @@ impl RuntimeSupervisorLaunch {
|
|||
command: &RunscCommand,
|
||||
) -> io::Result<Self> {
|
||||
if ownership.slot != HostProcessOwnershipSlot::SandboxRuntimeSupervisor
|
||||
|| command.program() != OsStr::new("runsc")
|
||||
|| !is_absolute_normalized(command.program())
|
||||
|| !command
|
||||
.arguments()
|
||||
.iter()
|
||||
|
|
@ -558,6 +558,14 @@ impl RuntimeSupervisorLaunch {
|
|||
}
|
||||
}
|
||||
|
||||
fn is_absolute_normalized(value: &OsStr) -> bool {
|
||||
let path = Path::new(value);
|
||||
path.is_absolute()
|
||||
&& path
|
||||
.components()
|
||||
.all(|component| matches!(component, Component::RootDir | Component::Normal(_)))
|
||||
}
|
||||
|
||||
/// Runs the Runtime Supervisor's private early role before ordinary binary dispatch.
|
||||
///
|
||||
/// # Errors
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
use super::{
|
||||
AsRawFd, ConfigurationFingerprint, CoordinatorId, DerivedPolicyDigest, Deserialize, DomainId,
|
||||
File, FileType, GenerationId, HostProcessOwnershipSlot, MAX_RUNTIME_HANDOFF_BYTES,
|
||||
NetworkSidecarId, OsStr, OsStrExt, OsString, OsStringExt, PathBuf, ProcessOwnershipContext,
|
||||
Read, RuntimeArguments, RuntimeGitRoutingArguments, RuntimeGitRoutingLaunch,
|
||||
RuntimeNetworkArguments, RuntimeStateAnchorArguments, RuntimeSupervisorLaunch, Serialize,
|
||||
StateAnchorLaunchAuthority, decode, encode, fstat, io, require_write_sealed,
|
||||
NetworkSidecarId, OsStr, OsStrExt, OsString, OsStringExt, Path, PathBuf,
|
||||
ProcessOwnershipContext, Read, RuntimeArguments, RuntimeGitRoutingArguments,
|
||||
RuntimeGitRoutingLaunch, RuntimeNetworkArguments, RuntimeStateAnchorArguments,
|
||||
RuntimeSupervisorLaunch, Serialize, StateAnchorLaunchAuthority, decode, encode, fstat, io,
|
||||
require_write_sealed,
|
||||
};
|
||||
|
||||
#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
|
||||
|
|
@ -280,7 +281,9 @@ pub(super) fn parse_runtime_handoff(arguments: &[OsString]) -> io::Result<Runtim
|
|||
let RuntimeSupervisorHandoff::V1(handoff) =
|
||||
decode::<RuntimeSupervisorHandoff>(&encoded).map_err(io::Error::other)?;
|
||||
validate_runtime_handoff(handoff_descriptor, &handoff)?;
|
||||
if handoff.runsc_program.as_slice() != b"runsc" {
|
||||
if !super::is_absolute_normalized(
|
||||
Path::new(OsStr::from_bytes(&handoff.runsc_program)).as_os_str(),
|
||||
) {
|
||||
return Err(io::Error::other("Runtime Supervisor target is not runsc"));
|
||||
}
|
||||
if !handoff
|
||||
|
|
@ -450,7 +453,7 @@ mod handoff_tests {
|
|||
state_anchor: None,
|
||||
git_routing: None,
|
||||
network: None,
|
||||
runsc_program: b"runsc".to_vec(),
|
||||
runsc_program: b"/usr/bin/runsc".to_vec(),
|
||||
runsc_arguments: arguments,
|
||||
})
|
||||
}
|
||||
|
|
@ -520,7 +523,7 @@ mod handoff_tests {
|
|||
configuration_fingerprint: ConfigurationFingerprint::new([5; 32]),
|
||||
network_sidecar_id: NetworkSidecarId::new([6; 32]),
|
||||
}),
|
||||
runsc_program: b"runsc".to_vec(),
|
||||
runsc_program: b"/usr/bin/runsc".to_vec(),
|
||||
runsc_arguments: vec![
|
||||
b"-root=/runtime".to_vec(),
|
||||
b"run".to_vec(),
|
||||
|
|
@ -531,8 +534,8 @@ mod handoff_tests {
|
|||
assert_eq!(
|
||||
Sha256::digest(&encoded).as_slice(),
|
||||
[
|
||||
123, 0, 18, 227, 164, 11, 96, 15, 4, 201, 99, 25, 198, 122, 175, 149, 170, 165, 12,
|
||||
40, 209, 64, 119, 67, 10, 109, 128, 44, 201, 103, 14, 182,
|
||||
160, 106, 3, 13, 33, 111, 190, 97, 46, 192, 143, 140, 37, 66, 201, 110, 197, 41,
|
||||
25, 200, 73, 147, 49, 163, 36, 226, 10, 166, 255, 62, 61, 135,
|
||||
]
|
||||
);
|
||||
assert_eq!(
|
||||
|
|
@ -620,7 +623,7 @@ mod handoff_tests {
|
|||
configuration_fingerprint: None,
|
||||
network_sidecar_id: None,
|
||||
runsc_command: RunscCommand::new(
|
||||
"runsc",
|
||||
"/usr/bin/runsc",
|
||||
[OsString::from("run"), OsString::from("container")],
|
||||
[8; 32],
|
||||
),
|
||||
|
|
|
|||
|
|
@ -422,7 +422,7 @@ fn runtime_supervisor_and_runsc_keep_distinct_edge_and_stdio_policies() {
|
|||
policy_digest: None,
|
||||
configuration_fingerprint: None,
|
||||
runsc_command: RunscCommand::new(
|
||||
"runsc",
|
||||
"/usr/bin/runsc",
|
||||
[OsString::from("run"), OsString::from("container")],
|
||||
[0; 32],
|
||||
),
|
||||
|
|
@ -450,7 +450,7 @@ fn runtime_supervisor_and_runsc_keep_distinct_edge_and_stdio_policies() {
|
|||
state_anchor: None,
|
||||
git_routing: None,
|
||||
network: None,
|
||||
runsc_program: "runsc".into(),
|
||||
runsc_program: "/usr/bin/runsc".into(),
|
||||
runsc_arguments: ["-root=/runtime", "run", "container"]
|
||||
.map(OsString::from)
|
||||
.into(),
|
||||
|
|
@ -462,7 +462,7 @@ fn runtime_supervisor_and_runsc_keep_distinct_edge_and_stdio_policies() {
|
|||
ChildStandardIoPolicy::Silenced
|
||||
);
|
||||
let delete = runsc_delete_target(&runsc_arguments).unwrap();
|
||||
assert_eq!(delete.program(), "runsc");
|
||||
assert_eq!(delete.program(), "/usr/bin/runsc");
|
||||
assert_eq!(
|
||||
delete.arguments(),
|
||||
["-root=/runtime", "delete", "--force", "container"]
|
||||
|
|
@ -482,7 +482,7 @@ fn runtime_handoff_preserves_exact_ownership_and_runsc_arguments() {
|
|||
let launch = RuntimeSupervisorLaunch::from_runsc_command(
|
||||
ownership,
|
||||
&RunscCommand::new(
|
||||
"runsc",
|
||||
"/usr/bin/runsc",
|
||||
[
|
||||
OsString::from("-root=/runtime"),
|
||||
OsString::from("run"),
|
||||
|
|
|
|||
|
|
@ -143,6 +143,7 @@ env = {{ UNSELECTED_SECRET = "env:UNSELECTED_HOST_SECRET" }}
|
|||
fn request(&self, root_process: RootProcess) -> SandboxBuildRequest<'_> {
|
||||
SandboxBuildRequest {
|
||||
configuration: &self.configuration,
|
||||
runsc_program: Path::new("/usr/bin/runsc"),
|
||||
container_id: ContainerId::new([0x11; 32]),
|
||||
expected_network_namespace: current_network_namespace(),
|
||||
root_process,
|
||||
|
|
@ -352,7 +353,7 @@ fn routed_workspace_source_replaces_only_the_workspace_bind_source() {
|
|||
}
|
||||
|
||||
fn assert_runtime_command(bundle: &SandboxBundle, fixture: &Fixture) {
|
||||
assert_eq!(bundle.command().program(), OsStr::new("runsc"));
|
||||
assert_eq!(bundle.command().program(), OsStr::new("/usr/bin/runsc"));
|
||||
let runtime_domain = String::from_utf8(
|
||||
fixture
|
||||
.configuration
|
||||
|
|
@ -421,6 +422,7 @@ fn configured_dcache_is_fingerprinted_and_passed_to_runsc() {
|
|||
);
|
||||
let bundle = build_sandbox_bundle(SandboxBuildRequest {
|
||||
configuration: &configuration,
|
||||
runsc_program: Path::new("/usr/bin/runsc"),
|
||||
container_id: ContainerId::new([0x11; 32]),
|
||||
expected_network_namespace: current_network_namespace(),
|
||||
root_process: root_process([]),
|
||||
|
|
@ -650,6 +652,7 @@ fn hostile_terminal_names_sources_and_changed_entries_fail_closed() {
|
|||
.unwrap();
|
||||
let error = build_sandbox_bundle(SandboxBuildRequest {
|
||||
configuration: &fixture.configuration,
|
||||
runsc_program: Path::new("/usr/bin/runsc"),
|
||||
container_id: ContainerId::new([0x11; 32]),
|
||||
expected_network_namespace: current_network_namespace(),
|
||||
root_process: root_process([]),
|
||||
|
|
@ -684,6 +687,7 @@ fn invalid_processes_and_wrong_network_identity_fail_closed() {
|
|||
}
|
||||
let error = build_sandbox_bundle(SandboxBuildRequest {
|
||||
configuration: &fixture.configuration,
|
||||
runsc_program: Path::new("/usr/bin/runsc"),
|
||||
container_id: ContainerId::new([0x11; 32]),
|
||||
expected_network_namespace: NamespaceIdentity {
|
||||
device: DeviceId::new(u64::MAX),
|
||||
|
|
|
|||
Loading…
Reference in a new issue