Skip to content

Commit 38c8b7d

Browse files
committed
chroot: set exit codes to 125, 126 or 127 for errors from chroot itself
1 parent 70714bc commit 38c8b7d

File tree

3 files changed

+29
-11
lines changed

3 files changed

+29
-11
lines changed

src/uu/chroot/src/chroot.rs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use std::ffi::CString;
1515
use std::io::Error;
1616
use std::path::Path;
1717
use std::process;
18-
use uucore::error::{set_exit_code, UResult};
18+
use uucore::error::{set_exit_code, UClapError, UResult};
1919
use uucore::libc::{self, chroot, setgid, setgroups, setuid};
2020
use uucore::{entries, format_usage};
2121

@@ -35,7 +35,7 @@ mod options {
3535
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
3636
let args = args.collect_lossy();
3737

38-
let matches = uu_app().get_matches_from(args);
38+
let matches = uu_app().try_get_matches_from(args).with_exit_code(125)?;
3939

4040
let default_shell: &'static str = "/bin/sh";
4141
let default_option: &'static str = "-i";
@@ -80,7 +80,14 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
8080
.status()
8181
{
8282
Ok(status) => status,
83-
Err(e) => return Err(ChrootError::CommandFailed(command[0].to_string(), e).into()),
83+
Err(e) => {
84+
return Err(if e.kind() == std::io::ErrorKind::NotFound {
85+
ChrootError::CommandNotFound(command[0].to_string(), e)
86+
} else {
87+
ChrootError::CommandFailed(command[0].to_string(), e)
88+
}
89+
.into())
90+
}
8491
};
8592

8693
let code = if pstatus.success() {

src/uu/chroot/src/error.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ pub enum ChrootError {
1818
/// Failed to execute the specified command.
1919
CommandFailed(String, Error),
2020

21+
/// Failed to find the specified command.
22+
CommandNotFound(String, Error),
23+
2124
/// The given user and group specification was invalid.
2225
InvalidUserspec(String),
2326

@@ -43,20 +46,23 @@ pub enum ChrootError {
4346
impl std::error::Error for ChrootError {}
4447

4548
impl UError for ChrootError {
46-
// TODO: Exit status:
4749
// 125 if chroot itself fails
4850
// 126 if command is found but cannot be invoked
4951
// 127 if command cannot be found
5052
fn code(&self) -> i32 {
51-
1
53+
match self {
54+
Self::CommandFailed(_, _) => 126,
55+
Self::CommandNotFound(_, _) => 127,
56+
_ => 125,
57+
}
5258
}
5359
}
5460

5561
impl Display for ChrootError {
5662
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
5763
match self {
5864
Self::CannotEnter(s, e) => write!(f, "cannot chroot to {}: {}", s.quote(), e,),
59-
Self::CommandFailed(s, e) => {
65+
Self::CommandFailed(s, e) | Self::CommandNotFound(s, e) => {
6066
write!(f, "failed to run command {}: {}", s.to_string().quote(), e,)
6167
}
6268
Self::InvalidUserspec(s) => write!(f, "invalid userspec: {}", s.quote(),),

tests/by-util/test_chroot.rs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ use crate::common::util::*;
44

55
#[test]
66
fn test_missing_operand() {
7-
let result = new_ucmd!().run();
7+
let result = new_ucmd!().fails();
8+
9+
result.code_is(125);
810

911
assert!(result
1012
.stderr_str()
@@ -22,7 +24,7 @@ fn test_enter_chroot_fails() {
2224
at.mkdir("jail");
2325

2426
let result = ucmd.arg("jail").fails();
25-
27+
result.code_is(125);
2628
assert!(result
2729
.stderr_str()
2830
.starts_with("chroot: cannot chroot to 'jail': Operation not permitted (os error 1)"));
@@ -36,7 +38,8 @@ fn test_no_such_directory() {
3638

3739
ucmd.arg("a")
3840
.fails()
39-
.stderr_is("chroot: cannot change root directory to 'a': no such directory");
41+
.stderr_is("chroot: cannot change root directory to 'a': no such directory")
42+
.code_is(125);
4043
}
4144

4245
#[test]
@@ -46,7 +49,7 @@ fn test_invalid_user_spec() {
4649
at.mkdir("a");
4750

4851
let result = ucmd.arg("a").arg("--userspec=ARABA:").fails();
49-
52+
result.code_is(125);
5053
assert!(result.stderr_str().starts_with("chroot: invalid userspec"));
5154
}
5255

@@ -86,7 +89,9 @@ fn test_preference_of_userspec() {
8689
.arg("-G")
8790
.arg("ABC,DEF")
8891
.arg(format!("--userspec={}:{}", username, group_name))
89-
.run();
92+
.fails();
93+
94+
result.code_is(125);
9095

9196
println!("result.stdout = {}", result.stdout_str());
9297
println!("result.stderr = {}", result.stderr_str());

0 commit comments

Comments
 (0)