Confine package ownership changes to private mounts

This commit is contained in:
ms2k 2026-07-27 03:31:58 +09:00
commit 8334fd379f
2 changed files with 402 additions and 25 deletions

View file

@ -395,7 +395,7 @@ pub(super) fn create_regular_file(parent: impl AsFd, name: &str) -> Result<(), S
parent.as_fd(),
name,
OFlags::WRONLY | OFlags::CREATE | OFlags::EXCL | OFlags::CLOEXEC | OFlags::NOFOLLOW,
Mode::from_raw_mode(0o600),
Mode::from_raw_mode(0o644),
confined_resolve_flags(),
) {
Ok(descriptor) => File::from(descriptor).sync_all()?,
@ -440,7 +440,7 @@ pub(super) fn atomic_replace_at(
parent.as_fd(),
Path::new(&candidate),
OFlags::WRONLY | OFlags::CREATE | OFlags::EXCL | OFlags::CLOEXEC | OFlags::NOFOLLOW,
Mode::from_raw_mode(0o600),
Mode::from_raw_mode(0o644),
confined_resolve_flags(),
) {
Ok(descriptor) => {
@ -514,6 +514,7 @@ pub(super) fn overlay_options(lower: &Path, upper: &Path, work: &Path) -> OsStri
append_fuse_option_path(&mut bytes, upper);
bytes.extend_from_slice(b",workdir=");
append_fuse_option_path(&mut bytes, work);
bytes.extend_from_slice(b",xattr_permissions=2,noacl");
OsString::from_vec(bytes)
}

View file

@ -67,6 +67,7 @@ fn run() -> io::Result<()> {
}
Err(error) => return Err(error),
}
enter_runtime_user_namespace()?;
let tree = TestTree::new().map_err(|error| io::Error::other(format!("test tree: {error}")))?;
let configuration = configuration(&tree)
.map_err(|error| io::Error::other(format!("configuration: {error}")))?;
@ -251,6 +252,25 @@ fn run() -> io::Result<()> {
Ok(())
}
#[allow(deprecated)]
fn enter_runtime_user_namespace() -> io::Result<()> {
let uid = rustix::process::getuid().as_raw();
let gid = rustix::process::getgid().as_raw();
rustix::thread::unshare(rustix::thread::UnshareFlags::NEWUSER)
.map_err(|error| io::Error::other(format!("fixture user namespace: {error}")))?;
fs::write("/proc/self/setgroups", "deny")?;
fs::write("/proc/self/uid_map", format!("0 {uid} 1\n"))?;
fs::write("/proc/self/gid_map", format!("0 {gid} 1\n"))?;
rustix::thread::unshare(rustix::thread::UnshareFlags::NEWNS)
.map_err(|error| io::Error::other(format!("fixture mount namespace: {error}")))?;
rustix::mount::mount_change(
"/",
rustix::mount::MountPropagationFlags::PRIVATE | rustix::mount::MountPropagationFlags::REC,
)
.map_err(|error| io::Error::other(format!("fixture private propagation: {error}")))?;
Ok(())
}
#[allow(deprecated)]
fn run_private_recovery_holder(arguments: &[OsString]) -> io::Result<()> {
if arguments.len() != 2 {