ostree_ext/isolation.rs
1use std::process::Command;
2
3use once_cell::sync::Lazy;
4
5pub(crate) const DEFAULT_UNPRIVILEGED_USER: &str = "nobody";
6
7/// Checks if the current process is (apparently at least)
8/// running under systemd. We use this in various places
9/// to e.g. log to the journal instead of printing to stdout.
10pub(crate) fn running_in_systemd() -> bool {
11 static RUNNING_IN_SYSTEMD: Lazy<bool> = Lazy::new(|| {
12 // See https://www.freedesktop.org/software/systemd/man/systemd.exec.html#%24INVOCATION_ID
13 std::env::var_os("INVOCATION_ID")
14 .filter(|s| !s.is_empty())
15 .is_some()
16 });
17
18 *RUNNING_IN_SYSTEMD
19}
20
21/// Return a prepared subprocess configuration that will run as an unprivileged user if possible.
22///
23/// This currently only drops privileges when run under systemd with DynamicUser.
24pub(crate) fn unprivileged_subprocess(binary: &str, user: &str) -> Command {
25 // TODO: if we detect we're running in a container as uid 0, perhaps at least switch to the
26 // "bin" user if we can?
27 if !running_in_systemd() {
28 return Command::new(binary);
29 }
30 let mut cmd = Command::new("setpriv");
31 // Clear some strategic environment variables that may cause the containers/image stack
32 // to look in the wrong places for things.
33 cmd.env_remove("HOME");
34 cmd.env_remove("XDG_DATA_DIR");
35 cmd.env_remove("USER");
36 cmd.args([
37 "--no-new-privs",
38 "--init-groups",
39 "--reuid",
40 user,
41 "--bounding-set",
42 "-all",
43 "--pdeathsig",
44 "TERM",
45 "--",
46 binary,
47 ]);
48 cmd
49}