Skip to main content

soma_codemode/
runner_exe.rs

1use std::ffi::OsStr;
2use std::path::{Path, PathBuf};
3
4use crate::ToolError;
5
6const RUNNER_EXE_ENV: &str = "SOMA_CODE_MODE_RUNNER_EXE";
7
8pub fn resolve_runner_exe() -> Result<PathBuf, ToolError> {
9    let current = std::env::current_exe().map_err(|err| {
10        ToolError::internal_message(format!(
11            "failed to locate current executable for Code Mode runner: {err}"
12        ))
13    })?;
14    let override_exe = std::env::var_os(RUNNER_EXE_ENV).map(PathBuf::from);
15    resolve_runner_exe_from(current, override_exe)
16}
17
18pub fn resolve_runner_exe_from(
19    current_exe: PathBuf,
20    override_exe: Option<PathBuf>,
21) -> Result<PathBuf, ToolError> {
22    if let Some(path) = override_exe {
23        let path = validate_operator_override(path)?;
24        tracing::warn!(
25            runner_exe = %path.display(),
26            "using SOMA_CODE_MODE_RUNNER_EXE override for Code Mode runner"
27        );
28        return Ok(path);
29    }
30
31    if is_runner_binary_path(&current_exe) && is_usable_exe(&current_exe) {
32        return Ok(current_exe);
33    }
34    for candidate in sibling_runner_candidates(&current_exe) {
35        if is_usable_exe(&candidate) {
36            return Ok(candidate);
37        }
38    }
39
40    Err(ToolError::internal_message(format!(
41        "Code Mode runner executable is stale or unavailable near `{}`; restart the soma service or set SOMA_CODE_MODE_RUNNER_EXE to a validated soma-codemode-runner binary",
42        current_exe.display()
43    )))
44}
45
46fn validate_operator_override(path: PathBuf) -> Result<PathBuf, ToolError> {
47    if !path.is_absolute() {
48        return Err(ToolError::Sdk {
49            sdk_kind: "invalid_param".to_string(),
50            message: "SOMA_CODE_MODE_RUNNER_EXE must be an absolute path".to_string(),
51        });
52    }
53    let canonical = std::fs::canonicalize(&path).map_err(|err| {
54        ToolError::internal_message(format!(
55            "SOMA_CODE_MODE_RUNNER_EXE points at `{}`, but it cannot be resolved: {err}",
56            path.display()
57        ))
58    })?;
59    if !is_usable_exe(&canonical) {
60        return Err(ToolError::internal_message(format!(
61            "SOMA_CODE_MODE_RUNNER_EXE points at `{}`, but that file is not executable",
62            canonical.display()
63        )));
64    }
65    reject_untrusted_permissions(&canonical)?;
66    Ok(canonical)
67}
68
69fn is_usable_exe(path: &Path) -> bool {
70    if path.to_string_lossy().ends_with(" (deleted)") {
71        return false;
72    }
73    let Ok(meta) = std::fs::metadata(path) else {
74        return false;
75    };
76    if !meta.is_file() {
77        return false;
78    }
79    #[cfg(unix)]
80    {
81        use std::os::unix::fs::PermissionsExt;
82        meta.permissions().mode() & 0o111 != 0
83    }
84    #[cfg(not(unix))]
85    {
86        true
87    }
88}
89
90fn sibling_runner_candidates(current_exe: &Path) -> Vec<PathBuf> {
91    let mut candidates = Vec::new();
92    if let Some(dir) = current_exe.parent() {
93        candidates.push(dir.join(runner_binary_name()));
94        if dir.file_name() == Some(OsStr::new("deps")) {
95            if let Some(parent) = dir.parent() {
96                candidates.push(parent.join(runner_binary_name()));
97            }
98        }
99    }
100    candidates
101}
102
103fn is_runner_binary_path(path: &Path) -> bool {
104    path.file_name() == Some(OsStr::new(runner_binary_name()))
105}
106
107fn runner_binary_name() -> &'static str {
108    if cfg!(windows) {
109        "soma-codemode-runner.exe"
110    } else {
111        "soma-codemode-runner"
112    }
113}
114
115fn reject_untrusted_permissions(path: &Path) -> Result<(), ToolError> {
116    #[cfg(unix)]
117    {
118        use std::os::unix::fs::MetadataExt;
119        let meta = std::fs::metadata(path).map_err(|err| {
120            ToolError::internal_message(format!("failed to inspect `{}`: {err}", path.display()))
121        })?;
122        if meta.mode() & 0o022 != 0 {
123            return Err(ToolError::internal_message(format!(
124                "SOMA_CODE_MODE_RUNNER_EXE points at `{}`, but the file is group/world writable",
125                path.display()
126            )));
127        }
128        let current_uid = nix::unistd::Uid::current().as_raw();
129        if meta.uid() != current_uid && meta.uid() != 0 {
130            return Err(ToolError::internal_message(format!(
131                "SOMA_CODE_MODE_RUNNER_EXE points at `{}`, but the file is not owned by the current user or root",
132                path.display()
133            )));
134        }
135    }
136    #[cfg(not(unix))]
137    {
138        let _ = path;
139    }
140    Ok(())
141}