Skip to content

Commit 413055b

Browse files
authored
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
1 parent ea6d114 commit 413055b

File tree

2 files changed

+16
-1
lines changed

2 files changed

+16
-1
lines changed

src/uu/chmod/src/chmod.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -407,7 +407,7 @@ impl Chmoder {
407407
// should not change the permissions in this case
408408
continue;
409409
}
410-
if self.recursive && self.preserve_root && file == Path::new("/") {
410+
if self.recursive && self.preserve_root && Self::is_root(file) {
411411
return Err(ChmodError::PreserveRoot("/".into()).into());
412412
}
413413
if self.recursive {
@@ -419,6 +419,10 @@ impl Chmoder {
419419
r
420420
}
421421

422+
fn is_root(file: impl AsRef<Path>) -> bool {
423+
matches!(fs::canonicalize(&file), Ok(p) if p == Path::new("/"))
424+
}
425+
422426
#[cfg(not(target_os = "linux"))]
423427
fn walk_dir_with_context(&self, file_path: &Path, is_command_line_arg: bool) -> UResult<()> {
424428
let mut r = self.chmod_file(file_path);

tests/by-util/test_chmod.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -508,6 +508,17 @@ fn test_chmod_preserve_root() {
508508
.stderr_contains("chmod: it is dangerous to operate recursively on '/'");
509509
}
510510

511+
#[test]
512+
fn test_chmod_preserve_root_with_paths_that_resolve_to_root() {
513+
new_ucmd!()
514+
.arg("-R")
515+
.arg("--preserve-root")
516+
.arg("755")
517+
.arg("/../")
518+
.fails_with_code(1)
519+
.stderr_contains("chmod: it is dangerous to operate recursively on '/'");
520+
}
521+
511522
#[test]
512523
fn test_chmod_symlink_non_existing_file() {
513524
let scene = TestScenario::new(util_name!());

0 commit comments

Comments
 (0)