Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 20 additions & 5 deletions src/uu/runcon/src/runcon.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
//
// For the full copyright and license information, please view the LICENSE
// file that was distributed with this source code.
// spell-checker:ignore (vars) RFILE
// spell-checker:ignore (vars) RFILE execv execvp
#![cfg(target_os = "linux")]

use clap::builder::ValueParser;
Expand Down Expand Up @@ -48,7 +48,8 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
.map_err(RunconError::new)?;
// On successful execution, the following call never returns,
// and this process image is replaced.
execute_command(command, &options.arguments)
// PlainContext mode uses PATH search (like execvp).
execute_command(command, &options.arguments, false)
}
CommandLineMode::CustomContext {
compute_transition_context,
Expand All @@ -72,7 +73,8 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
.map_err(RunconError::new)?;
// On successful execution, the following call never returns,
// and this process image is replaced.
execute_command(command, &options.arguments)
// With -c flag, skip PATH search (like execv vs execvp).
execute_command(command, &options.arguments, *compute_transition_context)
}
None => print_current_context().map_err(|e| RunconError::new(e).into()),
}
Expand Down Expand Up @@ -367,8 +369,21 @@ fn get_custom_context(
/// However, until the *never* type is stabilized, one way to indicate to the
/// compiler the only valid return type is to say "if this returns, it will
/// always return an error".
fn execute_command(command: &OsStr, arguments: &[OsString]) -> UResult<()> {
let err = process::Command::new(command).args(arguments).exec();
///
/// When `skip_path_search` is true (used with `-c` flag), the command is executed
/// without PATH lookup, matching GNU's use of execv() vs execvp().
fn execute_command(command: &OsStr, arguments: &[OsString], skip_path_search: bool) -> UResult<()> {
// When skip_path_search is true and command has no path separator,
// prepend "./" to prevent PATH lookup (like execv vs execvp).
let command_path = if skip_path_search && !command.as_bytes().contains(&b'/') {
let mut path = OsString::from("./");
path.push(command);
path
} else {
command.to_os_string()
};

let err = process::Command::new(&command_path).args(arguments).exec();

let exit_status = if err.kind() == io::ErrorKind::NotFound {
error_exit_status::NOT_FOUND
Expand Down
2 changes: 1 addition & 1 deletion util/build-gnu.sh
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ export CARGOFLAGS # tell to make
ln -vf "${UU_BUILD_DIR}/install" "${UU_BUILD_DIR}/ginstall" # The GNU tests use renamed install to ginstall
if [ "${SELINUX_ENABLED}" = 1 ];then
# Build few utils for SELinux for faster build. MULTICALL=y fails...
"${MAKE}" UTILS="cat chcon cp cut echo env groups id ln ls mkdir mkfifo mknod mktemp mv printf rm rmdir runcon stat test touch tr true uname wc whoami"
"${MAKE}" UTILS="cat chcon chmod cp cut echo env groups id ln ls mkdir mkfifo mknod mktemp mv printf rm rmdir runcon stat test touch tr true uname wc whoami"
else
# Use MULTICALL=y for faster build
"${MAKE}" MULTICALL=y SKIP_UTILS="install more seq"
Expand Down
Loading