fix: Add trusted_shell_script_arg for internal scripts
- shell_script_arg blocks $( and backticks for user input safety - trusted_shell_script_arg allows these for internal installer scripts - Internal scripts need shell features like command substitution - Updated bootstrap, installer, facade, and llm modules
This commit is contained in:
parent
db267714ca
commit
00acf1c76e
5 changed files with 41 additions and 9 deletions
|
|
@ -38,7 +38,7 @@ fn safe_pgrep(args: &[&str]) -> Option<std::process::Output> {
|
|||
fn safe_sh_command(script: &str) -> Option<std::process::Output> {
|
||||
SafeCommand::new("sh")
|
||||
.and_then(|c| c.arg("-c"))
|
||||
.and_then(|c| c.shell_script_arg(script))
|
||||
.and_then(|c| c.trusted_shell_script_arg(script))
|
||||
.ok()
|
||||
.and_then(|cmd| cmd.execute().ok())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1065,7 +1065,7 @@ Store credentials in Vault:
|
|||
trace!("Executing command: {}", rendered_cmd);
|
||||
let output = SafeCommand::new("bash")
|
||||
.and_then(|c| c.arg("-c"))
|
||||
.and_then(|c| c.shell_script_arg(&rendered_cmd))
|
||||
.and_then(|c| c.trusted_shell_script_arg(&rendered_cmd))
|
||||
.and_then(|c| c.working_dir(&bin_path))
|
||||
.map_err(|e| anyhow::anyhow!("Failed to build bash command: {}", e))?
|
||||
.execute()
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ fn safe_nvcc_version() -> Option<std::process::Output> {
|
|||
fn safe_sh_command(script: &str) -> Option<std::process::Output> {
|
||||
SafeCommand::new("sh")
|
||||
.and_then(|c| c.arg("-c"))
|
||||
.and_then(|c| c.shell_script_arg(script))
|
||||
.and_then(|c| c.trusted_shell_script_arg(script))
|
||||
.ok()
|
||||
.and_then(|cmd| cmd.execute().ok())
|
||||
}
|
||||
|
|
@ -1112,7 +1112,7 @@ EOF"#.to_string(),
|
|||
trace!("[START] Working dir: {}", bin_path.display());
|
||||
let child = SafeCommand::new("sh")
|
||||
.and_then(|c| c.arg("-c"))
|
||||
.and_then(|c| c.shell_script_arg(&rendered_cmd))
|
||||
.and_then(|c| c.trusted_shell_script_arg(&rendered_cmd))
|
||||
.and_then(|c| c.working_dir(&bin_path))
|
||||
.and_then(|cmd| cmd.spawn_with_envs(&evaluated_envs))
|
||||
.map_err(|e| anyhow::anyhow!("Failed to spawn process: {}", e));
|
||||
|
|
|
|||
|
|
@ -90,7 +90,7 @@ pub async fn ensure_llama_servers_running(
|
|||
|
||||
let pkill_result = SafeCommand::new("sh")
|
||||
.and_then(|c| c.arg("-c"))
|
||||
.and_then(|c| c.shell_script_arg("pkill llama-server -9; true"));
|
||||
.and_then(|c| c.trusted_shell_script_arg("pkill llama-server -9; true"));
|
||||
|
||||
match pkill_result {
|
||||
Ok(cmd) => {
|
||||
|
|
@ -366,7 +366,7 @@ pub fn start_llm_server(
|
|||
);
|
||||
let cmd = SafeCommand::new("cmd")
|
||||
.and_then(|c| c.arg("/C"))
|
||||
.and_then(|c| c.shell_script_arg(&cmd_arg))
|
||||
.and_then(|c| c.trusted_shell_script_arg(&cmd_arg))
|
||||
.map_err(|e| Box::new(std::io::Error::new(std::io::ErrorKind::Other, e.to_string())) as Box<dyn std::error::Error + Send + Sync>)?;
|
||||
cmd.execute().map_err(|e| Box::new(std::io::Error::new(std::io::ErrorKind::Other, e.to_string())) as Box<dyn std::error::Error + Send + Sync>)?;
|
||||
} else {
|
||||
|
|
@ -378,7 +378,7 @@ pub fn start_llm_server(
|
|||
);
|
||||
let cmd = SafeCommand::new("sh")
|
||||
.and_then(|c| c.arg("-c"))
|
||||
.and_then(|c| c.shell_script_arg(&cmd_arg))
|
||||
.and_then(|c| c.trusted_shell_script_arg(&cmd_arg))
|
||||
.map_err(|e| Box::new(std::io::Error::new(std::io::ErrorKind::Other, e.to_string())) as Box<dyn std::error::Error + Send + Sync>)?;
|
||||
cmd.execute().map_err(|e| Box::new(std::io::Error::new(std::io::ErrorKind::Other, e.to_string())) as Box<dyn std::error::Error + Send + Sync>)?;
|
||||
}
|
||||
|
|
@ -410,7 +410,7 @@ pub async fn start_embedding_server(
|
|||
);
|
||||
let cmd = SafeCommand::new("cmd")
|
||||
.and_then(|c| c.arg("/c"))
|
||||
.and_then(|c| c.shell_script_arg(&cmd_arg))
|
||||
.and_then(|c| c.trusted_shell_script_arg(&cmd_arg))
|
||||
.map_err(|e| Box::new(std::io::Error::new(std::io::ErrorKind::Other, e.to_string())) as Box<dyn std::error::Error + Send + Sync>)?;
|
||||
cmd.execute().map_err(|e| Box::new(std::io::Error::new(std::io::ErrorKind::Other, e.to_string())) as Box<dyn std::error::Error + Send + Sync>)?;
|
||||
} else {
|
||||
|
|
@ -422,7 +422,7 @@ pub async fn start_embedding_server(
|
|||
);
|
||||
let cmd = SafeCommand::new("sh")
|
||||
.and_then(|c| c.arg("-c"))
|
||||
.and_then(|c| c.shell_script_arg(&cmd_arg))
|
||||
.and_then(|c| c.trusted_shell_script_arg(&cmd_arg))
|
||||
.map_err(|e| Box::new(std::io::Error::new(std::io::ErrorKind::Other, e.to_string())) as Box<dyn std::error::Error + Send + Sync>)?;
|
||||
cmd.execute().map_err(|e| Box::new(std::io::Error::new(std::io::ErrorKind::Other, e.to_string())) as Box<dyn std::error::Error + Send + Sync>)?;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -176,6 +176,38 @@ impl SafeCommand {
|
|||
Ok(self)
|
||||
}
|
||||
|
||||
pub fn trusted_shell_script_arg(mut self, script: &str) -> Result<Self, CommandGuardError> {
|
||||
let is_unix_shell = self.command == "bash" || self.command == "sh";
|
||||
let is_windows_cmd = self.command == "cmd";
|
||||
if !is_unix_shell && !is_windows_cmd {
|
||||
return Err(CommandGuardError::InvalidArgument(
|
||||
"trusted_shell_script_arg only allowed for bash/sh/cmd commands".to_string(),
|
||||
));
|
||||
}
|
||||
let valid_flag = if is_unix_shell {
|
||||
self.args.last().is_some_and(|a| a == "-c")
|
||||
} else {
|
||||
self.args.last().is_some_and(|a| a == "/C" || a == "/c")
|
||||
};
|
||||
if !valid_flag {
|
||||
return Err(CommandGuardError::InvalidArgument(
|
||||
"trusted_shell_script_arg requires -c (unix) or /C (windows) flag to be set first".to_string(),
|
||||
));
|
||||
}
|
||||
if script.is_empty() {
|
||||
return Err(CommandGuardError::InvalidArgument(
|
||||
"Empty script".to_string(),
|
||||
));
|
||||
}
|
||||
if script.len() > 16384 {
|
||||
return Err(CommandGuardError::InvalidArgument(
|
||||
"Script too long".to_string(),
|
||||
));
|
||||
}
|
||||
self.args.push(script.to_string());
|
||||
Ok(self)
|
||||
}
|
||||
|
||||
pub fn args(mut self, args: &[&str]) -> Result<Self, CommandGuardError> {
|
||||
for arg in args {
|
||||
validate_argument(arg)?;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue