From faced00a45815f21e98916b0a231dd45407f2218 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Teemu=20P=C3=A4tsi?= Date: Sun, 20 Apr 2025 17:10:22 +0300 Subject: [PATCH 1/5] id: The `--real` flag should only affect `-u`, `-g`, and `-U` --- src/uu/id/src/id.rs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/uu/id/src/id.rs b/src/uu/id/src/id.rs index 83a6d066f74..6f24b6dec54 100644 --- a/src/uu/id/src/id.rs +++ b/src/uu/id/src/id.rs @@ -230,10 +230,14 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { return Ok(()); } - let (uid, gid) = possible_pw.as_ref().map(|p| (p.uid, p.gid)).unwrap_or(( - if state.rflag { getuid() } else { geteuid() }, - if state.rflag { getgid() } else { getegid() }, - )); + let (uid, gid) = possible_pw.as_ref().map(|p| (p.uid, p.gid)).unwrap_or({ + let use_effective = !state.rflag && (state.uflag || state.gflag || state.gsflag); + if use_effective { + (geteuid(), getegid()) + } else { + (getuid(), getgid()) + } + }); state.ids = Some(Ids { uid, gid, From a498a2722d7ab56ce96e7cab4766343930ea85ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Teemu=20P=C3=A4tsi?= Date: Sun, 20 Apr 2025 22:35:34 +0300 Subject: [PATCH 2/5] id: Test output with different UID and EUID --- tests/by-util/test_id.rs | 45 +++++++++++++++++++++- tests/fixtures/id/different_uid_and_euid.c | 7 ++++ 2 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 tests/fixtures/id/different_uid_and_euid.c diff --git a/tests/by-util/test_id.rs b/tests/by-util/test_id.rs index 2b3eee6590e..b3eae97057c 100644 --- a/tests/by-util/test_id.rs +++ b/tests/by-util/test_id.rs @@ -8,7 +8,7 @@ use uutests::new_ucmd; use uutests::unwrap_or_return; use uutests::util::{TestScenario, check_coreutil_version, expected_result, is_ci, whoami}; -use uutests::util_name; +use uutests::{at_and_ucmd, util_name}; const VERSION_MIN_MULTIPLE_USERS: &str = "8.31"; // this feature was introduced in GNU's coreutils 8.31 @@ -478,3 +478,46 @@ fn test_id_pretty_print_password_record() { .fails() .stderr_contains("the argument '-p' cannot be used with '-P'"); } + +enum CompilationResult { + CompilerNotInstalled, + Error, + Success, +} + +fn compile_preload_file_with_gcc(c_file: &str, so_file: &str) -> CompilationResult { + let result = std::process::Command::new("gcc") + .args(["-fPIC", "-shared", "-o", &so_file, &c_file]) + .status(); + + match result { + Err(err) if err.kind() == std::io::ErrorKind::NotFound => { + CompilationResult::CompilerNotInstalled + } + Ok(status) if status.success() => CompilationResult::Success, + _ => CompilationResult::Error, + } +} + +#[test] +#[cfg(all(unix, not(target_os = "android")))] +fn test_id_different_uid_and_euid() { + let (at, mut ucmd) = at_and_ucmd!(); + + // Compile the preload file required for mocking different UID and EUID. + // The UID should be 1000, whereas the EUID should be 0. + let c_file = at.as_string() + "/different_uid_and_euid.c"; + let so_file = at.as_string() + "/different_uid_and_euid.so"; + let compilation_result = compile_preload_file_with_gcc(&c_file, &so_file); + match compilation_result { + CompilationResult::CompilerNotInstalled => { + println!("test skipped: `gcc` compiler is not installed"); + return; + } + CompilationResult::Error => panic!("Preload file compilation failed"), + CompilationResult::Success => {} + } + + let result = ucmd.env("LD_PRELOAD", so_file).run(); + result.stdout_contains("uid=1000").stdout_contains("euid=0"); +} diff --git a/tests/fixtures/id/different_uid_and_euid.c b/tests/fixtures/id/different_uid_and_euid.c new file mode 100644 index 00000000000..7154e86afb4 --- /dev/null +++ b/tests/fixtures/id/different_uid_and_euid.c @@ -0,0 +1,7 @@ +#include + +const uid_t USER_UID = 1000; +const uid_t ROOT_UID = 0; + +uid_t getuid(void) { return USER_UID; } +uid_t geteuid(void) { return ROOT_UID; } From 208fa8e7f88f29214ef99984bf47c6a9ebc2ed0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Teemu=20P=C3=A4tsi?= Date: Sun, 20 Apr 2025 23:03:10 +0300 Subject: [PATCH 3/5] id: Simplify testing different UID and EUID --- tests/by-util/test_id.rs | 35 ++++++++++------------------------- 1 file changed, 10 insertions(+), 25 deletions(-) diff --git a/tests/by-util/test_id.rs b/tests/by-util/test_id.rs index b3eae97057c..9dac99bced2 100644 --- a/tests/by-util/test_id.rs +++ b/tests/by-util/test_id.rs @@ -479,24 +479,14 @@ fn test_id_pretty_print_password_record() { .stderr_contains("the argument '-p' cannot be used with '-P'"); } -enum CompilationResult { - CompilerNotInstalled, - Error, - Success, -} - -fn compile_preload_file_with_gcc(c_file: &str, so_file: &str) -> CompilationResult { - let result = std::process::Command::new("gcc") +fn compile_preload_file_with_gcc( + c_file: &str, + so_file: &str, +) -> Result { + Ok(std::process::Command::new("gcc") .args(["-fPIC", "-shared", "-o", &so_file, &c_file]) - .status(); - - match result { - Err(err) if err.kind() == std::io::ErrorKind::NotFound => { - CompilationResult::CompilerNotInstalled - } - Ok(status) if status.success() => CompilationResult::Success, - _ => CompilationResult::Error, - } + .status() + .map_err(|_| "`gcc` is not installed")?) } #[test] @@ -508,14 +498,9 @@ fn test_id_different_uid_and_euid() { // The UID should be 1000, whereas the EUID should be 0. let c_file = at.as_string() + "/different_uid_and_euid.c"; let so_file = at.as_string() + "/different_uid_and_euid.so"; - let compilation_result = compile_preload_file_with_gcc(&c_file, &so_file); - match compilation_result { - CompilationResult::CompilerNotInstalled => { - println!("test skipped: `gcc` compiler is not installed"); - return; - } - CompilationResult::Error => panic!("Preload file compilation failed"), - CompilationResult::Success => {} + let status = unwrap_or_return!(compile_preload_file_with_gcc(&c_file, &so_file)); + if !status.success() { + panic!("Preload file compilation failed") } let result = ucmd.env("LD_PRELOAD", so_file).run(); From 8efcbf9adae59b7074d29b2ac8ff8a4083df7d95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Teemu=20P=C3=A4tsi?= Date: Sun, 20 Apr 2025 23:21:09 +0300 Subject: [PATCH 4/5] id: Compile preload file for test using cc instead of gcc --- tests/by-util/test_id.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/by-util/test_id.rs b/tests/by-util/test_id.rs index 9dac99bced2..eaffbd8d4f7 100644 --- a/tests/by-util/test_id.rs +++ b/tests/by-util/test_id.rs @@ -483,10 +483,10 @@ fn compile_preload_file_with_gcc( c_file: &str, so_file: &str, ) -> Result { - Ok(std::process::Command::new("gcc") + Ok(std::process::Command::new("cc") .args(["-fPIC", "-shared", "-o", &so_file, &c_file]) .status() - .map_err(|_| "`gcc` is not installed")?) + .map_err(|_| "`cc` command is not available")?) } #[test] From 7d2f68c916c0f0d2518f5dcef1d6e7467b463427 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Teemu=20P=C3=A4tsi?= Date: Mon, 21 Apr 2025 10:36:08 +0300 Subject: [PATCH 5/5] id: Remove test for different UID and EUID The test is incompatible with some CI/CD targets. This reverts the following commits: - 8efcbf9adae59b7074d29b2ac8ff8a4083df7d95 - 208fa8e7f88f29214ef99984bf47c6a9ebc2ed0d - a498a2722d7ab56ce96e7cab4766343930ea85ac --- tests/by-util/test_id.rs | 30 +--------------------- tests/fixtures/id/different_uid_and_euid.c | 7 ----- 2 files changed, 1 insertion(+), 36 deletions(-) delete mode 100644 tests/fixtures/id/different_uid_and_euid.c diff --git a/tests/by-util/test_id.rs b/tests/by-util/test_id.rs index eaffbd8d4f7..2b3eee6590e 100644 --- a/tests/by-util/test_id.rs +++ b/tests/by-util/test_id.rs @@ -8,7 +8,7 @@ use uutests::new_ucmd; use uutests::unwrap_or_return; use uutests::util::{TestScenario, check_coreutil_version, expected_result, is_ci, whoami}; -use uutests::{at_and_ucmd, util_name}; +use uutests::util_name; const VERSION_MIN_MULTIPLE_USERS: &str = "8.31"; // this feature was introduced in GNU's coreutils 8.31 @@ -478,31 +478,3 @@ fn test_id_pretty_print_password_record() { .fails() .stderr_contains("the argument '-p' cannot be used with '-P'"); } - -fn compile_preload_file_with_gcc( - c_file: &str, - so_file: &str, -) -> Result { - Ok(std::process::Command::new("cc") - .args(["-fPIC", "-shared", "-o", &so_file, &c_file]) - .status() - .map_err(|_| "`cc` command is not available")?) -} - -#[test] -#[cfg(all(unix, not(target_os = "android")))] -fn test_id_different_uid_and_euid() { - let (at, mut ucmd) = at_and_ucmd!(); - - // Compile the preload file required for mocking different UID and EUID. - // The UID should be 1000, whereas the EUID should be 0. - let c_file = at.as_string() + "/different_uid_and_euid.c"; - let so_file = at.as_string() + "/different_uid_and_euid.so"; - let status = unwrap_or_return!(compile_preload_file_with_gcc(&c_file, &so_file)); - if !status.success() { - panic!("Preload file compilation failed") - } - - let result = ucmd.env("LD_PRELOAD", so_file).run(); - result.stdout_contains("uid=1000").stdout_contains("euid=0"); -} diff --git a/tests/fixtures/id/different_uid_and_euid.c b/tests/fixtures/id/different_uid_and_euid.c deleted file mode 100644 index 7154e86afb4..00000000000 --- a/tests/fixtures/id/different_uid_and_euid.c +++ /dev/null @@ -1,7 +0,0 @@ -#include - -const uid_t USER_UID = 1000; -const uid_t ROOT_UID = 0; - -uid_t getuid(void) { return USER_UID; } -uid_t geteuid(void) { return ROOT_UID; }