Skip to content

Commit

Permalink
Spawn processes as an unprivileged user by default, including connect…
Browse files Browse the repository at this point in the history
…ion-checker
  • Loading branch information
dlon committed Aug 21, 2024
1 parent 0cc9684 commit f603283
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 5 deletions.
18 changes: 18 additions & 0 deletions test/scripts/ssh-setup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ for file in test-runner connection-checker $APP_PACKAGE $PREVIOUS_APP $UI_RUNNER
cp -f "$SCRIPT_DIR/$file" "$RUNNER_DIR"
done

# Unprivileged users need execute rights for connection checker
chmod 551 "${RUNNER_DIR}/connection-checker"

chown -R root "$RUNNER_DIR/"

# Create service
Expand Down Expand Up @@ -69,11 +72,18 @@ function setup_macos {
</plist>
EOF

create_test_user_macos

echo "Starting test runner service"

launchctl load -w $RUNNER_PLIST_PATH
}

function create_test_user_macos {
echo "Adding test user account"
sysadminctl -addUser mole -fullName "Mole Molesson" -password mole
}

function setup_systemd {
RUNNER_SERVICE_PATH="/etc/systemd/system/testrunner.service"

Expand All @@ -94,10 +104,18 @@ EOF

semanage fcontext -a -t bin_t "$RUNNER_DIR/.*" &> /dev/null || true

create_test_user_linux

systemctl enable testrunner.service
systemctl start testrunner.service
}

function create_test_user_linux {
echo "Adding test user account"
useradd -m mole
echo "mole" | passwd mole --stdin
}

if [[ "$(uname -s)" == "Darwin" ]]; then
setup_macos
exit 0
Expand Down
2 changes: 1 addition & 1 deletion test/test-runner/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ features = ["codec"]
default-features = false

[target.'cfg(unix)'.dependencies]
nix = { workspace = true }
nix = { workspace = true, features = ["user"] }

[target.'cfg(target_os = "linux")'.dependencies]
rs-release = "0.1.7"
Expand Down
15 changes: 11 additions & 4 deletions test/test-runner/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -386,11 +386,18 @@ impl Service for TestServer {
}

cmd.stderr(Stdio::piped());
cmd.kill_on_drop(true);

let mut child = cmd.kill_on_drop(true).spawn().map_err(|error| {
log::error!("Failed to spawn {}: {error}", opts.path);
test_rpc::Error::Syscall
})?;
// TODO: do not hardcode
let mut child = util::as_unprivileged("mole", || cmd.spawn())
.map_err(|error| {
log::error!("Failed to drop privileges: {error}");
test_rpc::Error::Syscall
})?
.map_err(|error| {
log::error!("Failed to spawn {}: {error}", opts.path);
test_rpc::Error::Syscall
})?;

let pid = child
.id()
Expand Down
49 changes: 49 additions & 0 deletions test/test-runner/src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,52 @@ impl<F: FnOnce() + Send> OnDrop<F> {
}
}
}

#[cfg(target_os = "windows")]
pub fn as_unprivileged<T>(
unpriv_user: &str,
func: impl FnOnce() -> T,
) -> Result<T, nix::Error> {
// NOTE: no-op
let _ = unpriv_user;
Ok(func())
}

#[derive(thiserror::Error, Debug)]
pub enum Error {
#[error("Failed to get the specified user")]
GetUser(#[source] nix::Error),
#[error("The specified user was not found")]
MissingUser,
}

#[cfg(unix)]
pub fn as_unprivileged<T>(
unpriv_user: &str,
func: impl FnOnce() -> T,
) -> Result<T, Error> {
let original_uid = nix::unistd::getuid();
let original_gid = nix::unistd::getgid();

let user = nix::unistd::User::from_name(unpriv_user).map_err(Error::GetUser)?.ok_or(Error::MissingUser)?;
let uid = user.uid;
let gid = user.gid;

if let Err(error) = nix::unistd::setegid(gid) {
log::error!("Failed to set gid: {error}");
}
if let Err(error) = nix::unistd::seteuid(uid) {
log::error!("Failed to set uid: {error}");
}

let func_result = func();

if let Err(error) = nix::unistd::seteuid(original_uid) {
log::error!("Failed to restore uid: {error}");
}
if let Err(error) = nix::unistd::setegid(original_gid) {
log::error!("Failed to restore gid: {error}");
}

Ok(func_result)
}

0 comments on commit f603283

Please sign in to comment.