Skip to content

Commit 01b6655

Browse files
committed
coreutils: Protect against env -a for security
1 parent 3af5b71 commit 01b6655

3 files changed

Lines changed: 29 additions & 5 deletions

File tree

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -539,6 +539,7 @@ wc = { optional = true, version = "0.6.0", package = "uu_wc", path = "src/uu/wc"
539539
who = { optional = true, version = "0.6.0", package = "uu_who", path = "src/uu/who" }
540540
whoami = { optional = true, version = "0.6.0", package = "uu_whoami", path = "src/uu/whoami" }
541541
yes = { optional = true, version = "0.6.0", package = "uu_yes", path = "src/uu/yes" }
542+
libc.workspace = true
542543

543544
# this breaks clippy linting with: "tests/by-util/test_factor_benches.rs: No such file or directory (os error 2)"
544545
# factor_benches = { optional = true, version = "0.0.0", package = "uu_factor_benches", path = "tests/benches/factor" }

src/bin/coreutils.rs

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
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 getauxval
7+
68
use clap::Command;
79
use coreutils::validation;
810
use itertools::Itertools as _;
@@ -45,8 +47,19 @@ fn main() {
4547
let utils = util_map();
4648
let mut args = uucore::args_os();
4749

50+
#[cfg(target_os = "linux")]
51+
// protect against env -a
52+
let binary = {
53+
use std::ffi::{CStr, OsString};
54+
use std::os::unix::ffi::OsStringExt;
55+
let _ = args.next();
56+
let n = unsafe { CStr::from_ptr(libc::getauxval(libc::AT_EXECFN) as _) };
57+
OsString::from_vec(n.to_bytes().to_vec())
58+
};
59+
#[cfg(not(target_os = "linux"))]
4860
let binary = validation::binary_path(&mut args);
49-
let binary_as_util = validation::name(&binary).unwrap_or_else(|| {
61+
62+
let binary_as_util = validation::name(binary.as_ref()).unwrap_or_else(|| {
5063
usage(&utils, "<unknown binary name>");
5164
process::exit(0);
5265
});
@@ -55,8 +68,12 @@ fn main() {
5568
let is_coreutils = binary_as_util.ends_with("utils");
5669
let matched_util = utils
5770
.keys()
71+
//*utils is not ls
5872
.filter(|&&u| binary_as_util.ends_with(u) && !is_coreutils)
59-
.max_by_key(|u| u.len()); //Prefer stty more than tty. *utils is not ls
73+
//Prefer stty more than tty
74+
.max_by_key(|u| u.len())
75+
// todo: with coreutils -> ls -> blah symlink chain, blah calls ls
76+
;
6077

6178
let util_name = if let Some(&util) = matched_util {
6279
Some(OsString::from(util))

tests/by-util/test_env.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -722,7 +722,11 @@ fn test_env_with_empty_executable_double_quotes() {
722722
}
723723

724724
#[test]
725-
#[cfg(all(unix, feature = "dirname", feature = "echo"))]
725+
#[cfg(all(
726+
all(unix, feature = "dirname", feature = "echo"),
727+
not(target_os = "linux")
728+
))]
729+
// protected against hijack at Linux
726730
fn test_env_overwrite_arg0() {
727731
let ts = TestScenario::new(util_name!());
728732

@@ -746,7 +750,8 @@ fn test_env_overwrite_arg0() {
746750
}
747751

748752
#[test]
749-
#[cfg(all(unix, feature = "echo"))]
753+
#[cfg(all(all(unix, feature = "echo"), not(target_os = "linux")))]
754+
// protected against hijack at Linux
750755
fn test_env_arg_argv0_overwrite() {
751756
let ts = TestScenario::new(util_name!());
752757

@@ -794,7 +799,8 @@ fn test_env_arg_argv0_overwrite() {
794799
}
795800

796801
#[test]
797-
#[cfg(all(unix, feature = "echo"))]
802+
#[cfg(all(all(unix, feature = "echo"), not(target_os = "linux")))]
803+
// protected against hijack at Linux
798804
fn test_env_arg_argv0_overwrite_mixed_with_string_args() {
799805
let ts = TestScenario::new(util_name!());
800806

0 commit comments

Comments
 (0)