Refuse inexact production selector authorities

This commit is contained in:
ms2k 2026-07-16 21:06:02 +09:00
commit 4cf7a5e595

View file

@ -87,6 +87,7 @@ impl PreparedLowerStore {
Err(error) => return Err(error.into()),
}
let root = open_directory_at(&storage_root, Path::new("prepared-lower"))?;
require_owned_directory(&root)?;
Self::initialize_retained(root, catalog)
}
@ -101,7 +102,8 @@ impl PreparedLowerStore {
Ok(()) | Err(rustix::io::Errno::EXIST) => {}
Err(error) => return Err(error.into()),
}
open_directory_at(&store.root, Path::new(name))?;
let directory = open_directory_at(&store.root, Path::new(name))?;
require_owned_directory(&directory)?;
}
open_lock_at(&store.root)?;
Ok(store)
@ -472,6 +474,14 @@ impl PreparedLowerStore {
}
}
fn require_owned_directory(directory: &File) -> Result<()> {
let stat = rustix::fs::fstat(directory)?;
if stat.st_uid != rustix::process::getuid().as_raw() || stat.st_mode & 0o7777 != 0o700 {
bail!("fixed prepared-lower directory must be owned by the invoking user with mode 0700");
}
Ok(())
}
struct Identities {
artifact_id: PreparedArtifactId,
source: SourceIdentity,
@ -685,3 +695,20 @@ fn hex(bytes: &[u8]) -> String {
fn secure_resolve() -> ResolveFlags {
ResolveFlags::BENEATH | ResolveFlags::NO_SYMLINKS | ResolveFlags::NO_MAGICLINKS
}
#[cfg(test)]
mod fixed_directory_tests {
use std::os::unix::fs::PermissionsExt;
use super::*;
#[test]
fn prepared_lower_root_requires_invoking_owner_and_exact_private_mode() {
let directory = tempfile::tempdir().unwrap();
std::fs::set_permissions(directory.path(), std::fs::Permissions::from_mode(0o777)).unwrap();
let root = File::open(directory.path()).unwrap();
assert!(require_owned_directory(&root).is_err());
std::fs::set_permissions(directory.path(), std::fs::Permissions::from_mode(0o700)).unwrap();
assert!(require_owned_directory(&root).is_ok());
}
}