From 7d628c65d3380dc76ee4ea433ad3ccb1682053f9 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Sat, 28 Dec 2024 22:27:53 +0100 Subject: [PATCH] chroot: handle the error when invalid user Currently fails with: ``` 2024-12-28T14:55:18.9330231Z thread 'main' panicked at src/uu/chroot/src/chroot.rs:284:46: 2024-12-28T14:55:18.9330718Z called `Result::unwrap()` on an `Err` value: Custom { kind: NotFound, error: "Not found: nobody:+65535" } 2024-12-28T14:55:18.9331305Z note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace ``` --- src/uu/chroot/src/chroot.rs | 3 ++- src/uu/chroot/src/error.rs | 4 ++++ tests/by-util/test_chroot.rs | 22 ++++++++++++++++++++++ 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/src/uu/chroot/src/chroot.rs b/src/uu/chroot/src/chroot.rs index fb20b0ccc46..58e11e101cf 100644 --- a/src/uu/chroot/src/chroot.rs +++ b/src/uu/chroot/src/chroot.rs @@ -281,7 +281,8 @@ fn set_groups_from_str(groups: &str) -> UResult<()> { fn set_user(user: &str) -> UResult<()> { if !user.is_empty() { - let user_id = entries::usr2uid(user).unwrap(); + let user_id = + entries::usr2uid(user).map_err(|_| ChrootError::NoSuchUser(user.to_string()))?; let err = unsafe { setuid(user_id as libc::uid_t) }; if err != 0 { return Err( diff --git a/src/uu/chroot/src/error.rs b/src/uu/chroot/src/error.rs index 526f1a75a43..1b83e76256b 100644 --- a/src/uu/chroot/src/error.rs +++ b/src/uu/chroot/src/error.rs @@ -27,6 +27,9 @@ pub enum ChrootError { /// The new root directory was not given. MissingNewRoot, + /// Failed to find the specified user. + NoSuchUser(String), + /// Failed to find the specified group. NoSuchGroup(String), @@ -71,6 +74,7 @@ impl Display for ChrootError { "Missing operand: NEWROOT\nTry '{} --help' for more information.", uucore::execution_phrase(), ), + Self::NoSuchUser(s) => write!(f, "no such user: {}", s.maybe_quote(),), Self::NoSuchGroup(s) => write!(f, "no such group: {}", s.maybe_quote(),), Self::NoSuchDirectory(s) => write!( f, diff --git a/tests/by-util/test_chroot.rs b/tests/by-util/test_chroot.rs index bf6b2ce16f1..42da75f4879 100644 --- a/tests/by-util/test_chroot.rs +++ b/tests/by-util/test_chroot.rs @@ -64,6 +64,28 @@ fn test_invalid_user_spec() { assert!(result.stderr_str().starts_with("chroot: invalid userspec")); } +#[test] +fn test_invalid_user() { + let ts = TestScenario::new(util_name!()); + let at = &ts.fixtures; + + let dir = "CHROOT_DIR"; + at.mkdir(dir); + if let Ok(result) = run_ucmd_as_root(&ts, &[dir, "whoami"]) { + result.success().no_stderr().stdout_is("root"); + } else { + print!("Test skipped; requires root user"); + } + + if let Ok(result) = run_ucmd_as_root(&ts, &["--user=nobody:+65535", dir, "pwd"]) { + result + .failure() + .stderr_contains("no such user: nobody:+65535"); + } else { + print!("Test skipped; requires root user"); + } +} + #[test] #[cfg(not(target_os = "android"))] fn test_preference_of_userspec() {