Chmod preserve root (#10033)

* chmod: Fix --preserve-root not being bypassed by path that resolves to root

* chmod: Regression tests for --preserve-root not being bypassed by path that resolves to root
This commit is contained in:
cerdelen
2026-01-07 10:49:54 +01:00
committed by GitHub
parent ea6d114859
commit 413055b378
2 changed files with 16 additions and 1 deletions
+5 -1
View File
@@ -407,7 +407,7 @@ impl Chmoder {
// should not change the permissions in this case
continue;
}
if self.recursive && self.preserve_root && file == Path::new("/") {
if self.recursive && self.preserve_root && Self::is_root(file) {
return Err(ChmodError::PreserveRoot("/".into()).into());
}
if self.recursive {
@@ -419,6 +419,10 @@ impl Chmoder {
r
}
fn is_root(file: impl AsRef<Path>) -> bool {
matches!(fs::canonicalize(&file), Ok(p) if p == Path::new("/"))
}
#[cfg(not(target_os = "linux"))]
fn walk_dir_with_context(&self, file_path: &Path, is_command_line_arg: bool) -> UResult<()> {
let mut r = self.chmod_file(file_path);
+11
View File
@@ -508,6 +508,17 @@ fn test_chmod_preserve_root() {
.stderr_contains("chmod: it is dangerous to operate recursively on '/'");
}
#[test]
fn test_chmod_preserve_root_with_paths_that_resolve_to_root() {
new_ucmd!()
.arg("-R")
.arg("--preserve-root")
.arg("755")
.arg("/../")
.fails_with_code(1)
.stderr_contains("chmod: it is dangerous to operate recursively on '/'");
}
#[test]
fn test_chmod_symlink_non_existing_file() {
let scene = TestScenario::new(util_name!());