From 475d018f9367893ed5f3af43f1a08f867078cf24 Mon Sep 17 00:00:00 2001 From: Asahi Lina Date: Wed, 16 Oct 2024 00:46:07 +0900 Subject: [PATCH] muvm-guest: Support root and user init scripts Introduce two scripts that can be placed in ~/.local/share/muvm - init.sh: Executed as root, before dropping privileges - user.sh: Executed as the user, after dropping privileges If the files are also present in lower-priority XDG dirs (systemwide), those are executed first. This makes it possible to add custom VM configuration and setup or debugging scripts without having to hack on the muvm code. Signed-off-by: Asahi Lina --- Cargo.lock | 7 ++++++ crates/muvm/Cargo.toml | 1 + crates/muvm/src/guest/bin/muvm-guest.rs | 29 +++++++++++++++++++++++++ 3 files changed, 37 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index 8dc5c9b..d081954 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -382,6 +382,7 @@ dependencies = [ "tokio", "tokio-stream", "uuid", + "xdg", ] [[package]] @@ -807,3 +808,9 @@ name = "windows_x86_64_msvc" version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" + +[[package]] +name = "xdg" +version = "2.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "213b7324336b53d2414b2db8537e56544d981803139155afa84f76eeebb7a546" diff --git a/crates/muvm/Cargo.toml b/crates/muvm/Cargo.toml index 17f1ecc..4451d51 100644 --- a/crates/muvm/Cargo.toml +++ b/crates/muvm/Cargo.toml @@ -23,6 +23,7 @@ tempfile = { version = "3.10.1", default-features = false, features = [] } tokio = { version = "1.38.0", default-features = false, features = ["io-util", "macros", "net", "process", "rt-multi-thread", "sync"] } tokio-stream = { version = "0.1.15", default-features = false, features = ["net", "sync"] } uuid = { version = "1.10.0", default-features = false, features = ["std", "v7"] } +xdg = "2.5.2" [features] default = [] diff --git a/crates/muvm/src/guest/bin/muvm-guest.rs b/crates/muvm/src/guest/bin/muvm-guest.rs index 311b2ca..4a8d5d0 100644 --- a/crates/muvm/src/guest/bin/muvm-guest.rs +++ b/crates/muvm/src/guest/bin/muvm-guest.rs @@ -1,4 +1,5 @@ use std::cmp; +use std::env; use std::os::unix::process::CommandExt as _; use std::process::Command; @@ -13,6 +14,7 @@ use muvm::guest::sommelier::exec_sommelier; use muvm::guest::user::setup_user; use muvm::guest::x11::setup_x11_forwarding; use muvm::utils::env::find_in_path; +use nix::unistd::User; use rustix::process::{getrlimit, setrlimit, Resource}; fn main() -> Result<()> { @@ -40,6 +42,18 @@ fn main() -> Result<()> { } Command::new("/usr/lib/systemd/systemd-udevd").spawn()?; + let user = User::from_uid(options.uid)?.unwrap(); + + // Hack to fetch the XDG directories for our target user, before we + // change uid. + // SAFETY: Safe if and only if `muvm-guest` program is not multithreaded. + // See https://doc.rust-lang.org/std/env/fn.set_var.html#safety + env::set_var("HOME", user.dir); + let xdg_dirs = xdg::BaseDirectories::with_prefix("muvm")?; + // SAFETY: Safe if and only if `muvm-guest` program is not multithreaded. + // See https://doc.rust-lang.org/std/env/fn.set_var.html#safety + env::remove_var("HOME"); + setup_fex()?; configure_network()?; @@ -50,6 +64,14 @@ fn main() -> Result<()> { .spawn()?; } + for init_file in xdg_dirs.find_data_files("init.sh") { + Command::new(init_file) + .arg(format!("{}", options.uid)) + .arg(format!("{}", options.gid)) + .status() + .context("Failed to execute init.sh")?; + } + let run_path = match setup_user(options.username, options.uid, options.gid) { Ok(p) => p, Err(err) => return Err(err).context("Failed to set up user, bailing out"), @@ -63,6 +85,13 @@ fn main() -> Result<()> { setup_x11_forwarding(run_path)?; + for init_file in xdg_dirs.find_data_files("user.sh") { + eprintln!("{:?}", init_file); + Command::new(init_file) + .status() + .context("Failed to execute user.sh")?; + } + // Will not return if successful. exec_sommelier(&options.command, &options.command_args) .context("Failed to execute sommelier")?;