Use extension trait for making a Command that runs unsandboxed

This commit is contained in:
Charlie Le 2024-11-21 14:26:54 -05:00
commit 1e6ed8fb21
3 changed files with 33 additions and 26 deletions

View file

@ -34,7 +34,7 @@ use crate::{
}, },
}, is_flatpak::IS_FLATPAK, linux_distro::LinuxDistro, openxr_prober::is_openxr_ready, paths::get_data_dir, profile::{Profile, XRServiceType}, stateless_action, steam_linux_runtime_injector::{ }, is_flatpak::IS_FLATPAK, linux_distro::LinuxDistro, openxr_prober::is_openxr_ready, paths::get_data_dir, profile::{Profile, XRServiceType}, stateless_action, steam_linux_runtime_injector::{
restore_runtime_entrypoint, set_runtime_entrypoint_launch_opts_from_profile, restore_runtime_entrypoint, set_runtime_entrypoint_launch_opts_from_profile,
}, util::{cmd_utils::make_command, file_utils::{setcap_cap_sys_nice_eip, setcap_cap_sys_nice_eip_cmd}}, vulkaninfo::VulkanInfo, xr_devices::XRDevice }, util::{cmd_utils::CommandUnsandbox, file_utils::{setcap_cap_sys_nice_eip, setcap_cap_sys_nice_eip_cmd}}, vulkaninfo::VulkanInfo, xr_devices::XRDevice
}; };
use adw::{prelude::*, ResponseAppearance}; use adw::{prelude::*, ResponseAppearance};
use gtk::glib::{self, clone}; use gtk::glib::{self, clone};
@ -43,7 +43,7 @@ use relm4::{
new_action_group, new_stateful_action, new_stateless_action, new_action_group, new_stateful_action, new_stateless_action,
prelude::*, prelude::*,
}; };
use std::{collections::VecDeque, fs::remove_file, time::Duration}; use std::{collections::VecDeque, fs::remove_file, process::Command, time::Duration};
pub struct App { pub struct App {
application: adw::Application, application: adw::Application,
@ -163,7 +163,8 @@ impl App {
self.debug_view.sender().emit(DebugViewMsg::ClearLog); self.debug_view.sender().emit(DebugViewMsg::ClearLog);
self.xr_devices = vec![]; self.xr_devices = vec![];
if *IS_FLATPAK { if *IS_FLATPAK {
make_command(String::from("rm"), Some(&[prof.xrservice_type.ipc_file_path().to_str().unwrap()]), None, true) Command::new_unsandboxed("rm", None)
.arg(prof.xrservice_type.ipc_file_path().to_str().unwrap())
.output() .output()
.expect("Failed to remove xrservice IPC file"); .expect("Failed to remove xrservice IPC file");
} else { } else {

View file

@ -3,12 +3,12 @@ use super::{
state::JobWorkerState, state::JobWorkerState,
}; };
use crate::{ use crate::{
profile::{LighthouseDriver, Profile}, ui::SENDER_IO_ERR_MSG, util::cmd_utils::make_command profile::{LighthouseDriver, Profile}, ui::SENDER_IO_ERR_MSG, util::cmd_utils::CommandUnsandbox
}; };
use nix::unistd::Pid; use nix::unistd::Pid;
use relm4::{prelude::*, Worker}; use relm4::{prelude::*, Worker};
use std::{ use std::{
collections::VecDeque, io::{BufRead, BufReader}, mem, os::unix::process::ExitStatusExt, process::Stdio, sync::{Arc, Mutex}, thread collections::VecDeque, io::{BufRead, BufReader}, mem, os::unix::process::ExitStatusExt, process::{Command, Stdio}, sync::{Arc, Mutex}, thread
}; };
macro_rules! logger_thread { macro_rules! logger_thread {
@ -85,7 +85,15 @@ impl Worker for InternalJobWorker {
match &mut job { match &mut job {
WorkerJob::Cmd(data) => { WorkerJob::Cmd(data) => {
let data = data.clone(); let data = data.clone();
if let Ok(mut cmd) = make_command(data.command, Some(&data.args), Some(data.environment), data.host_spawn) let mut cmd: Command;
if data.host_spawn {
cmd = Command::new_unsandboxed(&data.command, Some(data.environment))
} else {
cmd = Command::new(&data.command);
cmd.envs(data.environment);
}
if let Ok(mut cmd) = cmd
.args(data.args)
.stdin(Stdio::piped()) .stdin(Stdio::piped())
.stderr(Stdio::piped()) .stderr(Stdio::piped())
.stdout(Stdio::piped()) .stdout(Stdio::piped())

View file

@ -1,26 +1,24 @@
use std::{collections::HashMap, ffi::OsStr, process::Command}; use std::{collections::HashMap, process::Command};
use crate::is_flatpak::IS_FLATPAK; use crate::is_flatpak::IS_FLATPAK;
pub fn make_command<S: AsRef<OsStr>, T: AsRef<OsStr>>( pub trait CommandUnsandbox {
cmd: S, fn new_unsandboxed(program: &str, envs: Option<HashMap<String, String>>) -> Self;
args: Option<&[T]>, }
env: Option<HashMap<String, String>>,
host_spawn: bool, impl CommandUnsandbox for Command {
) -> Command { fn new_unsandboxed(program: &str, envs: Option<HashMap<String, String>>) -> Self {
if *IS_FLATPAK && host_spawn { if *IS_FLATPAK {
let mut flatpak_env = vec![]; let mut cmd = Command::new("flatpak-spawn");
for (key, value) in env.unwrap_or_default() { cmd.arg("--host");
flatpak_env.push(format!("--env={}={}", key, value)); for (key, value) in envs.unwrap_or_default() {
} cmd.arg(format!("--env={}={}", key, value));
let mut command = Command::new("flatpak-spawn"); }
command.arg("--host") cmd.arg(program);
.args(flatpak_env) return cmd;
.arg(cmd) }
.args(args.unwrap_or_default()); let mut cmd = Command::new(program);
return command; cmd.envs(envs.unwrap_or_default());
} cmd
let mut command = Command::new(cmd); }
command.args(args.unwrap_or_default()).envs(env.unwrap_or_default());
command
} }