Set permissions on unpacked Nix store paths more carefully (#451)

* Set permissions on unpacked Nix store paths more carefully

* Don't setperm on links
This commit is contained in:
Ana Hobden 2023-05-05 12:27:00 -07:00 committed by GitHub
parent 965185dcab
commit bdd087a615
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 31 additions and 2 deletions

1
Cargo.lock generated
View file

@ -1065,6 +1065,7 @@ dependencies = [
"typetag",
"url",
"uuid",
"walkdir",
"which",
"xz2",
]

View file

@ -60,6 +60,7 @@ strum = { version = "0.24.1", features = ["derive"] }
nix-config-parser = { version = "0.1.2", features = ["serde"] }
which = "4.4.0"
sysctl = "0.5.4"
walkdir = "2.3.3"
[dev-dependencies]
eyre = { version = "0.6.8", default-features = false, features = [ "track-caller" ] }

View file

@ -143,6 +143,9 @@ impl Action for FetchAndUnpackNix {
let decoder = xz2::read::XzDecoder::new(bytes.reader());
let mut archive = tar::Archive::new(decoder);
archive.set_preserve_permissions(true);
archive.set_preserve_mtime(true);
archive.set_unpack_xattrs(true);
archive
.unpack(&dest_clone)
.map_err(FetchUrlError::Unarchive)

View file

@ -1,6 +1,11 @@
use std::path::{Path, PathBuf};
use std::{
fs::Permissions,
os::unix::prelude::PermissionsExt,
path::{Path, PathBuf},
};
use tracing::{span, Span};
use walkdir::WalkDir;
use crate::action::{
Action, ActionDescription, ActionError, ActionErrorKind, ActionTag, StatefulAction,
@ -106,6 +111,25 @@ impl Action for MoveUnpackedNix {
ActionErrorKind::Rename(entry.path().clone(), entry_dest.to_owned(), e)
})
.map_err(Self::error)?;
let perms: Permissions = PermissionsExt::from_mode(0o555);
for entry_item in WalkDir::new(&entry_dest)
.into_iter()
.filter_map(Result::ok)
.filter(|e| !e.file_type().is_symlink())
{
tokio::fs::set_permissions(&entry_item.path(), perms.clone())
.await
.map_err(|e| {
ActionErrorKind::SetPermissions(
perms.mode(),
entry_item.path().to_owned(),
e,
)
})
.map_err(Self::error)?;
}
// Leave a back link where we copied from since later we may need to know which packages we actually transferred
// eg, know which `nix` version we installed when curing a user with several versions installed
tokio::fs::symlink(&entry_dest, entry.path())

View file

@ -415,7 +415,7 @@ pub enum ActionErrorKind {
std::path::PathBuf,
#[source] std::io::Error,
),
#[error("Set mode `{0}` on `{1}`")]
#[error("Set mode `{0:#o}` on `{1}`")]
SetPermissions(u32, std::path::PathBuf, #[source] std::io::Error),
#[error("Remove file `{0}`")]
Remove(std::path::PathBuf, #[source] std::io::Error),