Decompose oversized Rust files by responsibility

This commit is contained in:
ms2k 2026-07-19 03:02:44 +09:00
commit ee9201b057

View file

@ -417,675 +417,6 @@ fn require_inputs(inputs: &ColdStartInputs<'_>) -> Result<(), ColdStartError> {
Ok(())
}
struct GitRoutingLayout {
_runtime_directory: RuntimeGitRoutingDirectory,
workspace: File,
workspace_label: PathBuf,
isolated: File,
isolated_label: PathBuf,
mountpoint: File,
mountpoint_label: PathBuf,
git_common: File,
git_common_label: PathBuf,
transient_hooks: File,
transient_hooks_label: PathBuf,
transient_config: File,
transient_config_label: PathBuf,
global_excludes: Option<PathBuf>,
isolate_ignored: bool,
}
impl GitRoutingLayout {
fn create(
configuration: &ResolvedDomainConfiguration,
container_id: ContainerId,
invoking_uid: u32,
) -> Result<Option<Self>, ColdStartError> {
let workspace_label = host_path(configuration.workspace().canonical_label().as_bytes());
let workspace = File::from(
configuration
.workspace()
.open_authority()
.map_err(failure)?,
);
match statat(&workspace, ".git", AtFlags::SYMLINK_NOFOLLOW) {
Ok(_) => {}
Err(rustix::io::Errno::NOENT) => return Ok(None),
Err(error) => return Err(failure(error)),
}
let persistent_root = configuration
.persistent_domain_root()
.open_authority()
.map_err(failure)?;
let isolated = open_or_create_private_directory(
&persistent_root,
"ignored-workspace",
invoking_uid,
false,
)?;
let runtime_root = configuration
.runtime_domain_root()
.open_authority()
.map_err(failure)?;
let runtime_parent =
open_or_create_private_directory(&runtime_root, "git-routing", invoking_uid, false)?;
let runtime_name = OsString::from(hex(container_id.as_bytes()));
let directory =
open_or_create_private_directory(&runtime_parent, &runtime_name, invoking_uid, true)?;
let identity = FileIdentity::capture(&directory)?;
let runtime_directory = RuntimeGitRoutingDirectory {
parent: runtime_parent,
directory,
name: runtime_name.clone(),
identity,
};
let mountpoint = open_or_create_private_directory(
&runtime_directory.directory,
"workspace",
invoking_uid,
true,
)?;
let transient_hooks = open_or_create_private_directory(
&runtime_directory.directory,
"hooks",
invoking_uid,
true,
)?;
let transient_config = openat2(
&runtime_directory.directory,
"config",
OFlags::RDWR | OFlags::CREATE | OFlags::EXCL | OFlags::CLOEXEC | OFlags::NOFOLLOW,
Mode::RUSR | Mode::WUSR,
confined_resolve_flags(),
)
.map_err(failure)?;
fchmod(&transient_config, Mode::RUSR | Mode::WUSR).map_err(failure)?;
require_private_file(&transient_config, invoking_uid, 0o600)?;
let isolated_label = host_path(
configuration
.persistent_domain_root()
.canonical_label()
.as_bytes(),
)
.join("ignored-workspace");
let runtime_label = host_path(
configuration
.runtime_domain_root()
.canonical_label()
.as_bytes(),
)
.join("git-routing")
.join(&runtime_name);
let mountpoint_label = runtime_label.join("workspace");
let transient_hooks_label = runtime_label.join("hooks");
let transient_config_label = runtime_label.join("config");
let git_common_path = git_common_directory(&workspace_label).map_err(failure)?;
let git_common = open_absolute_directory(&git_common_path)?;
let global_excludes = global_excludes_path(&workspace_label)?;
Ok(Some(Self {
_runtime_directory: runtime_directory,
workspace,
workspace_label,
isolated: File::from(isolated),
isolated_label,
mountpoint: File::from(mountpoint),
mountpoint_label,
git_common,
git_common_label: git_common_path,
transient_hooks: File::from(transient_hooks),
transient_hooks_label,
transient_config: File::from(transient_config),
transient_config_label,
global_excludes,
isolate_ignored: configuration.fingerprint_record().isolate_gitignored,
}))
}
fn launch_authority(
&self,
configuration: &ResolvedDomainConfiguration,
) -> Result<RuntimeGitRoutingLaunch, ColdStartError> {
configuration
.workspace()
.open_authority()
.map_err(failure)?;
RuntimeGitRoutingLaunch::new(RuntimeGitRoutingAuthority {
workspace: self.workspace.try_clone().map_err(failure)?,
workspace_label: self.workspace_label.clone(),
isolated: self.isolated.try_clone().map_err(failure)?,
mountpoint: self.mountpoint.try_clone().map_err(failure)?,
mountpoint_label: self.mountpoint_label.clone(),
git_common: self.git_common.try_clone().map_err(failure)?,
git_common_label: self.git_common_label.clone(),
transient_hooks: self.transient_hooks.try_clone().map_err(failure)?,
transient_hooks_label: self.transient_hooks_label.clone(),
transient_config: self.transient_config.try_clone().map_err(failure)?,
transient_config_label: self.transient_config_label.clone(),
global_excludes: self.global_excludes.clone(),
isolate_ignored: self.isolate_ignored,
})
.map_err(failure)
}
fn mountpoint(&self) -> HostPath {
HostPath::new(
self.mountpoint_label
.as_os_str()
.as_encoded_bytes()
.to_vec(),
)
}
fn host_root(&self) -> HostPath {
HostPath::new(self.workspace_label.as_os_str().as_encoded_bytes().to_vec())
}
fn isolated_root(&self) -> HostPath {
HostPath::new(self.isolated_label.as_os_str().as_encoded_bytes().to_vec())
}
}
struct RuntimeGitRoutingDirectory {
parent: OwnedFd,
directory: OwnedFd,
name: OsString,
identity: FileIdentity,
}
impl Drop for RuntimeGitRoutingDirectory {
fn drop(&mut self) {
remove_staging_directory(&self.parent, &self.name, &self.directory, self.identity);
}
}
fn open_absolute_directory(path: &Path) -> Result<File, ColdStartError> {
let descriptor = openat2(
rustix::fs::CWD,
path,
OFlags::RDONLY | OFlags::DIRECTORY | OFlags::CLOEXEC | OFlags::NOFOLLOW,
Mode::empty(),
ResolveFlags::NO_MAGICLINKS | ResolveFlags::NO_SYMLINKS,
)
.map_err(failure)?;
Ok(File::from(descriptor))
}
fn global_excludes_path(workspace: &Path) -> Result<Option<PathBuf>, ColdStartError> {
let (reader, writer) = pipe_with(PipeFlags::CLOEXEC).map_err(failure)?;
let target = TargetCommand::new("git")
.argument("-C")
.argument(workspace)
.argument("config")
.argument("--path")
.argument("--get")
.argument("--default")
.argument("")
.argument("core.excludesFile");
child_broker()
.run_transient_with_private_stdout(&target, writer)
.map_err(|error| failure(format!("Git global-excludes discovery: {error}")))?;
let mut output = Vec::new();
File::from(reader)
.read_to_end(&mut output)
.map_err(failure)?;
parse_global_excludes_path(workspace, &output)
}
fn parse_global_excludes_path(
workspace: &Path,
output: &[u8],
) -> Result<Option<PathBuf>, ColdStartError> {
let value = output.strip_suffix(b"\n").unwrap_or(output);
if value.contains(&0) {
return Err(ColdStartError("Git global-excludes path is invalid".into()));
}
if value.is_empty() {
return Ok(default_global_excludes_path());
}
let path = PathBuf::from(OsString::from_vec(value.to_vec()));
Ok(Some(if path.is_absolute() {
path
} else {
workspace.join(path)
}))
}
fn default_global_excludes_path() -> Option<PathBuf> {
std::env::var_os("XDG_CONFIG_HOME")
.filter(|path| !path.is_empty())
.map(PathBuf::from)
.or_else(|| {
std::env::var_os("HOME")
.filter(|path| !path.is_empty())
.map(|home| PathBuf::from(home).join(".config"))
})
.map(|home| home.join("git/ignore"))
}
pub(crate) struct RuntimeStaging {
runsc_root: OwnedFd,
bundles: OwnedFd,
bundle: OwnedFd,
controls: OwnedFd,
control: OwnedFd,
overlays: OwnedFd,
overlay: OwnedFd,
name: OsString,
bundle_identity: FileIdentity,
control_identity: FileIdentity,
overlay_identity: FileIdentity,
}
impl RuntimeStaging {
pub(crate) fn runsc_root_identity(&self) -> Result<MountIdentity, ColdStartError> {
mount_identity(&self.runsc_root).map_err(failure)
}
pub(crate) fn cleanup_overlay(&self) -> Result<(), ColdStartError> {
let retained = fstat(&self.overlay).map_err(failure)?;
if !self.overlay_identity.matches(&retained) {
return Err(ColdStartError(
"runsc overlay retained authority changed".into(),
));
}
remove_children(&self.overlay).map_err(failure)?;
let current =
statat(&self.overlays, &self.name, AtFlags::SYMLINK_NOFOLLOW).map_err(failure)?;
if !self.overlay_identity.matches(&current)
|| !FileType::from_raw_mode(current.st_mode).is_dir()
{
return Err(ColdStartError(
"runsc overlay path changed before cleanup".into(),
));
}
unlinkat(&self.overlays, &self.name, AtFlags::REMOVEDIR).map_err(failure)?;
Ok(())
}
pub(crate) fn escalation_mailboxes(
&self,
invoking_uid: u32,
) -> Result<(RegularFileMailbox, RegularFileMailbox, RegularFileMailbox), ColdStartError> {
let credentials = RegularFileMailbox::openat_private(
&self.control,
OsStr::new("credentials"),
invoking_uid,
)
.map_err(failure)?;
let mailbox =
RegularFileMailbox::openat_private(&self.control, OsStr::new("mailbox"), invoking_uid)
.map_err(failure)?;
let requests =
RegularFileMailbox::openat_private(&mailbox, OsStr::new("requests"), invoking_uid)
.map_err(failure)?;
let results =
RegularFileMailbox::openat_private(&mailbox, OsStr::new("results"), invoking_uid)
.map_err(failure)?;
Ok((credentials, requests, results))
}
fn create(
runtime_domain: &ConfinedPathPlan,
container_id: ContainerId,
escalation_client: &File,
sandbox_init: &File,
invoking_uid: u32,
) -> Result<Self, ColdStartError> {
let root = runtime_domain.open_authority().map_err(failure)?;
let bundles = open_or_create_private_directory(&root, "bundles", invoking_uid, false)?;
let controls =
open_or_create_private_directory(&root, "sandbox-control", invoking_uid, false)?;
let overlays =
open_or_create_private_directory(&root, "runsc-overlay", invoking_uid, false)?;
let runsc_root = open_or_create_private_directory(&root, "runsc", invoking_uid, false)?;
let name = OsString::from(hex(container_id.as_bytes()));
let bundle = open_or_create_private_directory(&bundles, &name, invoking_uid, true)?;
let bundle_identity = FileIdentity::capture(&bundle)?;
let control = match open_or_create_private_directory(&controls, &name, invoking_uid, true) {
Ok(control) => control,
Err(error) => {
remove_staging_directory(&bundles, &name, &bundle, bundle_identity);
return Err(error);
}
};
let control_identity = FileIdentity::capture(&control)?;
let overlay = match open_or_create_private_directory(&overlays, &name, invoking_uid, true) {
Ok(overlay) => overlay,
Err(error) => {
remove_staging_directory(&controls, &name, &control, control_identity);
remove_staging_directory(&bundles, &name, &bundle, bundle_identity);
return Err(error);
}
};
let overlay_identity = FileIdentity::capture(&overlay)?;
let staging = Self {
runsc_root,
bundles,
bundle,
controls,
control,
overlays,
overlay,
name,
bundle_identity,
control_identity,
overlay_identity,
};
staging.populate_control(escalation_client, sandbox_init)?;
Ok(staging)
}
fn populate_control(
&self,
escalation_client: &File,
sandbox_init: &File,
) -> Result<(), ColdStartError> {
let invoking_uid = fstat(&self.control).map_err(failure)?.st_uid;
drop(open_or_create_private_directory(
&self.control,
"credentials",
invoking_uid,
true,
)?);
let mailbox =
open_or_create_private_directory(&self.control, "mailbox", invoking_uid, true)?;
drop(open_or_create_private_directory(
&mailbox,
"requests",
invoking_uid,
true,
)?);
drop(open_or_create_private_directory(
&mailbox,
"results",
invoking_uid,
true,
)?);
let bin = open_or_create_private_directory(&self.control, "bin", invoking_uid, true)?;
require_executable_regular_file(escalation_client, "escalation client")?;
copy_descriptor(escalation_client, &bin, "lazaret-escalate", invoking_uid)?;
require_executable_regular_file(sandbox_init, "sandbox init")?;
copy_descriptor(sandbox_init, &bin, "lazaret-sandbox-init", invoking_uid)?;
Ok(())
}
fn write_bundle(&self, bytes: &[u8]) -> Result<(), ColdStartError> {
let descriptor = openat2(
&self.bundle,
"config.json",
OFlags::WRONLY | OFlags::CREATE | OFlags::EXCL | OFlags::CLOEXEC | OFlags::NOFOLLOW,
Mode::RUSR | Mode::WUSR,
confined_resolve_flags(),
)
.map_err(failure)?;
let mut file = File::from(descriptor);
file.write_all(bytes).map_err(failure)?;
fchmod(file.as_fd(), Mode::RUSR | Mode::WUSR).map_err(failure)?;
file.sync_all().map_err(failure)?;
require_private_file(&file, fstat(&self.bundle).map_err(failure)?.st_uid, 0o600)?;
Ok(())
}
}
fn copy_descriptor(
source: &File,
parent: &OwnedFd,
name: &str,
invoking_uid: u32,
) -> Result<(), ColdStartError> {
let descriptor = openat2(
parent,
name,
OFlags::WRONLY | OFlags::CREATE | OFlags::EXCL | OFlags::CLOEXEC | OFlags::NOFOLLOW,
Mode::RWXU,
confined_resolve_flags(),
)
.map_err(failure)?;
let mut destination = File::from(descriptor);
fchmod(destination.as_fd(), Mode::RWXU).map_err(failure)?;
let mut offset = 0_u64;
let mut buffer = [0_u8; 16 * 1024];
loop {
let read = source.read_at(&mut buffer, offset).map_err(failure)?;
if read == 0 {
break;
}
destination.write_all(&buffer[..read]).map_err(failure)?;
offset = offset
.checked_add(read as u64)
.ok_or_else(|| ColdStartError("escalation client is too large".into()))?;
}
destination.sync_all().map_err(failure)?;
require_private_file(&destination, invoking_uid, 0o700)
}
fn require_executable_regular_file(source: &File, label: &str) -> Result<(), ColdStartError> {
let metadata = source
.metadata()
.map_err(|error| failure(format!("inspecting {label}: {error}")))?;
if !metadata.file_type().is_file() || metadata.permissions().mode() & 0o111 == 0 {
return Err(ColdStartError(format!(
"{label} is not an executable regular file"
)));
}
Ok(())
}
#[derive(Clone, Copy)]
struct FileIdentity {
device: u64,
inode: u64,
}
impl FileIdentity {
fn capture(descriptor: impl AsFd) -> Result<Self, ColdStartError> {
let metadata = fstat(descriptor).map_err(failure)?;
Ok(Self {
device: metadata.st_dev,
inode: metadata.st_ino,
})
}
fn matches(self, metadata: &rustix::fs::Stat) -> bool {
metadata.st_dev == self.device && metadata.st_ino == self.inode
}
}
impl Drop for RuntimeStaging {
fn drop(&mut self) {
remove_staging_directory(
&self.overlays,
&self.name,
&self.overlay,
self.overlay_identity,
);
remove_staging_directory(
&self.controls,
&self.name,
&self.control,
self.control_identity,
);
remove_staging_directory(
&self.bundles,
&self.name,
&self.bundle,
self.bundle_identity,
);
}
}
fn open_or_create_private_directory(
parent: impl AsFd,
name: impl AsRef<std::ffi::OsStr>,
invoking_uid: u32,
require_new: bool,
) -> Result<OwnedFd, ColdStartError> {
let name = name.as_ref();
let created = match mkdirat(parent.as_fd(), name, Mode::RWXU) {
Ok(()) => true,
Err(rustix::io::Errno::EXIST) if !require_new => false,
Err(error) => return Err(failure(error)),
};
let directory = openat2(
parent.as_fd(),
name,
OFlags::RDONLY | OFlags::DIRECTORY | OFlags::CLOEXEC | OFlags::NOFOLLOW,
Mode::empty(),
confined_resolve_flags(),
)
.map_err(failure)?;
if created {
fchmod(&directory, Mode::RWXU).map_err(failure)?;
}
require_private_directory(&directory, invoking_uid)?;
Ok(directory)
}
fn require_private_directory(
descriptor: impl AsFd,
invoking_uid: u32,
) -> Result<(), ColdStartError> {
let metadata = fstat(descriptor).map_err(failure)?;
if !FileType::from_raw_mode(metadata.st_mode).is_dir()
|| metadata.st_uid != invoking_uid
|| metadata.st_mode & 0o7777 != 0o700
{
return Err(ColdStartError(
"runtime staging directory is not invoking-user-owned mode 0700".into(),
));
}
Ok(())
}
fn require_private_file(
descriptor: impl AsFd,
invoking_uid: u32,
mode: u32,
) -> Result<(), ColdStartError> {
let metadata = fstat(descriptor).map_err(failure)?;
if !FileType::from_raw_mode(metadata.st_mode).is_file()
|| metadata.st_uid != invoking_uid
|| metadata.st_mode & 0o7777 != mode
|| metadata.st_nlink != 1
{
return Err(ColdStartError(
"runtime staging file has unsafe type, ownership, mode, or link count".into(),
));
}
Ok(())
}
fn remove_staging_directory(
parent: impl AsFd,
name: &std::ffi::OsStr,
directory: impl AsFd,
expected: FileIdentity,
) {
let retained = fstat(directory.as_fd());
if !retained
.as_ref()
.is_ok_and(|metadata| expected.matches(metadata))
{
return;
}
if remove_children(directory.as_fd()).is_err() {
return;
}
let Ok(current) = statat(parent.as_fd(), name, AtFlags::SYMLINK_NOFOLLOW) else {
return;
};
if expected.matches(&current) && FileType::from_raw_mode(current.st_mode).is_dir() {
let _ = unlinkat(parent.as_fd(), name, AtFlags::REMOVEDIR);
}
}
fn remove_children(directory: impl AsFd) -> std::io::Result<()> {
let duplicate = rustix::io::dup(directory.as_fd())?;
let mut buffer = [std::mem::MaybeUninit::uninit(); 8192];
let names = {
let mut names = Vec::new();
let mut entries = RawDir::new(duplicate, &mut buffer);
while let Some(entry) = entries.next() {
let entry = entry?;
let bytes = entry.file_name().to_bytes();
if bytes != b"." && bytes != b".." {
names.push(OsString::from_vec(bytes.to_vec()));
}
}
names
};
for name in names {
let metadata = statat(directory.as_fd(), &name, AtFlags::SYMLINK_NOFOLLOW)?;
if FileType::from_raw_mode(metadata.st_mode).is_dir() {
let child = openat2(
directory.as_fd(),
&name,
OFlags::RDONLY | OFlags::DIRECTORY | OFlags::CLOEXEC | OFlags::NOFOLLOW,
Mode::empty(),
confined_resolve_flags(),
)?;
remove_children(&child)?;
unlinkat(directory.as_fd(), &name, AtFlags::REMOVEDIR)?;
} else {
unlinkat(directory.as_fd(), &name, AtFlags::empty())?;
}
}
Ok(())
}
fn confined_resolve_flags() -> ResolveFlags {
ResolveFlags::BENEATH
| ResolveFlags::NO_MAGICLINKS
| ResolveFlags::NO_SYMLINKS
| ResolveFlags::NO_XDEV
}
fn host_path(bytes: &[u8]) -> PathBuf {
PathBuf::from(OsString::from_vec(bytes.to_vec()))
}
fn hex(bytes: &[u8]) -> String {
use std::fmt::Write as _;
bytes.iter().fold(String::new(), |mut output, byte| {
write!(output, "{byte:02x}").expect("writing to a String cannot fail");
output
})
}
#[cfg(test)]
mod tests {
use std::fs::File;
use std::os::fd::OwnedFd;
use rustix::pipe::{PipeFlags, pipe_with};
use super::BootstrapOwnerGuard;
#[test]
fn bootstrap_owner_guard_tracks_the_exact_inherited_pipe() {
let (reader, writer) = pipe_with(PipeFlags::CLOEXEC).unwrap();
let guard = BootstrapOwnerGuard::from_inherited(reader).unwrap();
assert!(guard.is_live().unwrap());
drop(writer);
assert!(!guard.is_live().unwrap());
}
#[test]
fn bootstrap_owner_guard_refuses_non_pipe_authority() {
let descriptor: OwnedFd = File::open("/dev/null").unwrap().into();
assert!(BootstrapOwnerGuard::from_inherited(descriptor).is_err());
}
#[test]
fn repository_relative_global_excludes_are_workspace_relative() {
let root = tempfile::tempdir().unwrap();
let workspace = root.path().join("workspace");
assert_eq!(
super::parse_global_excludes_path(&workspace, b"policy/ignore\n").unwrap(),
Some(workspace.join("policy/ignore"))
);
assert!(super::parse_global_excludes_path(&workspace, b"bad\0path\n").is_err());
}
}
include!("cold_start/git_routing.rs");
include!("cold_start/runtime_staging.rs");
include!("cold_start/tests.rs");