summaryrefslogtreecommitdiff
path: root/pkgs/by-name/sh/shh/pr13-profile-path-fix-strace.patch
diff options
context:
space:
mode:
Diffstat (limited to 'pkgs/by-name/sh/shh/pr13-profile-path-fix-strace.patch')
-rw-r--r--pkgs/by-name/sh/shh/pr13-profile-path-fix-strace.patch83
1 files changed, 83 insertions, 0 deletions
diff --git a/pkgs/by-name/sh/shh/pr13-profile-path-fix-strace.patch b/pkgs/by-name/sh/shh/pr13-profile-path-fix-strace.patch
new file mode 100644
index 000000000000..2db49fe17177
--- /dev/null
+++ b/pkgs/by-name/sh/shh/pr13-profile-path-fix-strace.patch
@@ -0,0 +1,83 @@
+commit 4d2c1556d769695770c95a982e0dcda4d70eee57
+Author: kuflierl <41301536+kuflierl@users.noreply.github.com>
+Date: Sun Apr 13 19:57:50 2025 +0200
+
+ service.rs: profile path fix for strace
+ Enable path env fixing when path env doesn't have strace to unbreak tool on unique systems and units.
+ This fixes handling on non FHS operating systems and systemd units that define their own PATH that doesn't include strace.
+
+diff --git a/src/systemd/service.rs b/src/systemd/service.rs
+index 908fdf0..e9294cf 100644
+--- a/src/systemd/service.rs
++++ b/src/systemd/service.rs
+@@ -7,6 +7,7 @@ use std::{
+ ops::RangeInclusive,
+ path::{Path, PathBuf},
+ process::{Command, Stdio},
++ ffi::OsString,
+ };
+
+ use anyhow::Context as _;
+@@ -99,6 +100,41 @@ impl Service {
+ )
+ }
+
++ // A function for locating the parent directory i.e. PATH of an executable
++ fn resolve_exec_path<P>(exe_name: &P, path_env: OsString) -> Option<PathBuf>
++ where P: AsRef<Path> + ?Sized,
++ {
++ env::split_paths(&path_env).filter_map(|dir| {
++ let full_path = dir.join(&exe_name);
++ if full_path.is_file() {
++ Some(dir)
++ } else {
++ None
++ }
++ }).next()
++ }
++
++ // determine PATH env used for unit
++ pub(crate) fn get_exec_path(config_paths: &Vec<&Path>) -> anyhow::Result<String> {
++ let old_path_env_option = Self::config_vals("Environment", &config_paths)?
++ .into_iter().filter(|x| x.starts_with("\"PATH=")).last().map(|x| x.trim_matches('\"').get(5..).unwrap().to_owned());
++ Ok(match old_path_env_option {
++ Some(path_env) => {
++ log::info!("Found hard coded PATH environment in unit: {path_env}");
++ path_env
++ },
++ None => {
++ let output = Command::new("systemd-path").arg("search-binaries-default").output()?;
++ if !output.status.success() {
++ anyhow::bail!("systemd-path invocation failed with code {:?}", output.status);
++ }
++ let default_systemd_path = output.stdout.lines().next().ok_or_else(|| anyhow::anyhow!("Unable to get global systemd default PATH"))??;
++ log::info!("Could not find hard coded PATH environment in unit, using systemd default: {default_systemd_path}");
++ default_systemd_path
++ }
++ })
++ }
++
+ /// Get systemd "exposure level" for the service (0-100).
+ /// 100 means extremely exposed (no hardening), 0 means so sandboxed it can't do much.
+ /// Although this is a very crude heuristic, below 40-50 is generally good.
+@@ -170,6 +206,20 @@ impl Service {
+ writeln!(fragment_file, "KillMode=control-group")?;
+ writeln!(fragment_file, "StandardOutput=journal")?;
+
++ // Modifying Env Path for strace availability if needed
++ let old_path_env = Self::get_exec_path(&config_paths)?;
++ match Self::resolve_exec_path("strace", (&old_path_env).into()) {
++ Some(_) => log::info!("Found strace in previous path, no correction needed"),
++ None => {
++ let path_with_strace = Self::resolve_exec_path("strace", env::var_os("PATH").unwrap()).unwrap();
++ log::info!("Found strace from local PATH in {}, inserting it into unit config!", path_with_strace.display());
++ let mut paths = env::split_paths(&old_path_env).collect::<Vec<_>>();
++ paths.push(path_with_strace);
++ let new_path = env::join_paths(paths)?;
++ writeln!(fragment_file, "Environment=\"PATH={}\"", new_path.to_str().unwrap())?;
++ },
++ }
++
+ // Profile data dir
+ let mut rng = rand::rng();
+ let profile_data_dir = PathBuf::from(format!(