1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-07-28 03:27:44 +00:00

chgrp,chown: fix bug in option --preserve-root

This commit is contained in:
knight42 2016-08-27 23:56:05 +08:00
parent d79e3d00eb
commit 136ca4e197
4 changed files with 51 additions and 18 deletions

View file

@ -13,7 +13,7 @@ walkdir = "*"
[dependencies.uucore] [dependencies.uucore]
path = "../uucore" path = "../uucore"
default-features = false default-features = false
features = ["entries"] features = ["entries", "fs"]
[[bin]] [[bin]]
name = "chgrp" name = "chgrp"

View file

@ -12,6 +12,7 @@
extern crate uucore; extern crate uucore;
use uucore::libc::{self, gid_t, lchown}; use uucore::libc::{self, gid_t, lchown};
pub use uucore::entries; pub use uucore::entries;
use uucore::fs::resolve_relative_path;
extern crate walkdir; extern crate walkdir;
use walkdir::WalkDir; use walkdir::WalkDir;
@ -194,12 +195,6 @@ impl Chgrper {
fn exec(&self) -> i32 { fn exec(&self) -> i32 {
let mut ret = 0; let mut ret = 0;
for f in &self.files { for f in &self.files {
if f == "/" && self.preserve_root && self.recursive {
show_info!("it is dangerous to operate recursively on '/'");
show_info!("use --no-preserve-root to override this failsafe");
ret = 1;
continue;
}
ret |= self.traverse(f); ret |= self.traverse(f);
} }
ret ret
@ -230,6 +225,28 @@ impl Chgrper {
_ => return 1, _ => return 1,
}; };
// Prohibit only if:
// (--preserve-root and -R present) &&
// (
// (argument is not symlink && resolved to be '/') ||
// (argument is symlink && should follow argument && resolved to be '/')
// )
if self.recursive && self.preserve_root {
let may_exist = if follow_arg {
path.canonicalize().ok()
} else {
Some(resolve_relative_path(path).into_owned())
};
if let Some(p) = may_exist {
if p.parent().is_none() {
show_info!("it is dangerous to operate recursively on '/'");
show_info!("use --no-preserve-root to override this failsafe");
return 1;
}
}
}
let ret = self.wrap_chgrp(path, &meta, follow_arg); let ret = self.wrap_chgrp(path, &meta, follow_arg);
if !self.recursive { if !self.recursive {

View file

@ -14,7 +14,7 @@ walkdir = "0.1"
[dependencies.uucore] [dependencies.uucore]
path = "../uucore" path = "../uucore"
default-features = false default-features = false
features = ["entries"] features = ["entries", "fs"]
[dependencies.clippy] [dependencies.clippy]
version = "*" version = "*"

View file

@ -15,6 +15,7 @@
extern crate uucore; extern crate uucore;
use uucore::libc::{self, uid_t, gid_t, lchown}; use uucore::libc::{self, uid_t, gid_t, lchown};
pub use uucore::entries::{self, Locate, Passwd, Group}; pub use uucore::entries::{self, Locate, Passwd, Group};
use uucore::fs::resolve_relative_path;
extern crate walkdir; extern crate walkdir;
use walkdir::WalkDir; use walkdir::WalkDir;
@ -257,12 +258,6 @@ impl Chowner {
fn exec(&self) -> i32 { fn exec(&self) -> i32 {
let mut ret = 0; let mut ret = 0;
for f in &self.files { for f in &self.files {
if f == "/" && self.preserve_root && self.recursive {
show_info!("it is dangerous to operate recursively on '/'");
show_info!("use --no-preserve-root to override this failsafe");
ret = 1;
continue;
}
ret |= self.traverse(f); ret |= self.traverse(f);
} }
ret ret
@ -293,6 +288,28 @@ impl Chowner {
_ => return 1, _ => return 1,
}; };
// Prohibit only if:
// (--preserve-root and -R present) &&
// (
// (argument is not symlink && resolved to be '/') ||
// (argument is symlink && should follow argument && resolved to be '/')
// )
if self.recursive && self.preserve_root {
let may_exist = if follow_arg {
path.canonicalize().ok()
} else {
Some(resolve_relative_path(path).into_owned())
};
if let Some(p) = may_exist {
if p.parent().is_none() {
show_info!("it is dangerous to operate recursively on '/'");
show_info!("use --no-preserve-root to override this failsafe");
return 1;
}
}
}
let ret = if self.matched(meta.uid(), meta.gid()) { let ret = if self.matched(meta.uid(), meta.gid()) {
self.wrap_chown(path, &meta, follow_arg) self.wrap_chown(path, &meta, follow_arg)
} else { } else {
@ -300,10 +317,10 @@ impl Chowner {
}; };
if !self.recursive { if !self.recursive {
return ret; ret
} else {
ret | self.dive_into(&root)
} }
self.dive_into(&root)
} }
fn dive_into<P: AsRef<Path>>(&self, root: P) -> i32 { fn dive_into<P: AsRef<Path>>(&self, root: P) -> i32 {
@ -413,4 +430,3 @@ impl Chowner {
} }
} }
} }