Skip to content

Commit e78eda1

Browse files
committed
id: Test -p with root-owned suid binary
1 parent 2109dad commit e78eda1

File tree

1 file changed

+53
-1
lines changed

1 file changed

+53
-1
lines changed

tests/by-util/test_id.rs

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,16 @@
33
// For the full copyright and license information, please view the LICENSE
44
// file that was distributed with this source code.
55

6-
// spell-checker:ignore (ToDO) coreutil
6+
// spell-checker:ignore (ToDO) coreutil euid rgid
77

88
use uutests::new_ucmd;
99
use uutests::unwrap_or_return;
1010
use uutests::util::{TestScenario, check_coreutil_version, expected_result, is_ci, whoami};
1111
use uutests::util_name;
1212

13+
#[cfg(all(feature = "chmod", feature = "chown"))]
14+
use tempfile::TempPath;
15+
1316
const VERSION_MIN_MULTIPLE_USERS: &str = "8.31"; // this feature was introduced in GNU's coreutils 8.31
1417

1518
#[test]
@@ -470,3 +473,52 @@ fn test_id_pretty_print_password_record() {
470473
.fails()
471474
.stderr_contains("the argument '-p' cannot be used with '-P'");
472475
}
476+
477+
#[test]
478+
#[cfg(all(feature = "chmod", feature = "chown"))]
479+
fn test_id_pretty_print_suid_binary() {
480+
use uucore::process::{getgid, getuid};
481+
482+
if let Some(suid_coreutils_path) = create_root_owned_suid_coreutils_binary() {
483+
let result = TestScenario::new(util_name!())
484+
.cmd(suid_coreutils_path.to_str().unwrap())
485+
.args(&[util_name!(), "-p"])
486+
.succeeds();
487+
488+
// The `euid` line should be present only if the real UID does not belong to `root`
489+
if getuid() == 0 {
490+
result.stdout_does_not_contain("euid\t");
491+
} else {
492+
result.stdout_contains_line("euid\troot");
493+
}
494+
495+
// The `rgid` line should be present only if the real GID does not belong to `root`
496+
if getgid() == 0 {
497+
result.stdout_does_not_contain("rgid\t");
498+
} else {
499+
result.stdout_contains("rgid\t");
500+
}
501+
} else {
502+
print!("Test skipped; requires root user");
503+
}
504+
}
505+
506+
/// Create SUID temp file owned by `root:root` with the contents of the `coreutils` binary
507+
#[cfg(all(feature = "chmod", feature = "chown"))]
508+
fn create_root_owned_suid_coreutils_binary() -> Option<TempPath> {
509+
use std::fs::read;
510+
use std::io::Write;
511+
use tempfile::NamedTempFile;
512+
use uutests::util::{get_tests_binary, run_ucmd_as_root};
513+
514+
let mut temp_file = NamedTempFile::new().unwrap();
515+
let coreutils_binary = read(get_tests_binary()).unwrap();
516+
temp_file.write_all(&coreutils_binary).unwrap();
517+
let temp_path = temp_file.into_temp_path();
518+
let temp_path_str = temp_path.to_str().unwrap();
519+
520+
run_ucmd_as_root(&TestScenario::new("chown"), &["root:root", temp_path_str]).ok()?;
521+
run_ucmd_as_root(&TestScenario::new("chmod"), &["+xs", temp_path_str]).ok()?;
522+
523+
Some(temp_path)
524+
}

0 commit comments

Comments
 (0)