diff options
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.patch | 83 |
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!( |
