From 628f91dd9668ebaab062522a91e12c1b7d2491d6 Mon Sep 17 00:00:00 2001 From: Yaroslav Pietukhov <77742707+valsoray-dev@users.noreply.github.com> Date: Fri, 13 Jun 2025 20:09:32 +0300 Subject: [PATCH] Disallow running CLI with root privileges (#32583) In #31331, I made a change that prevents Zed from running with root privileges, but I forgot about the CLI. So if you run the CLI without the `--foreground` flag, it just freezes without any messages. This PR fixes that. Release Notes: - N/A --- Cargo.lock | 1 + crates/cli/src/main.rs | 3 +++ crates/util/Cargo.toml | 1 + crates/util/src/util.rs | 22 ++++++++++++++++++++++ crates/zed/Cargo.toml | 2 +- crates/zed/src/main.rs | 17 +---------------- 6 files changed, 29 insertions(+), 17 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 34c9860a56..e64097c15c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -17348,6 +17348,7 @@ dependencies = [ "itertools 0.14.0", "libc", "log", + "nix 0.29.0", "rand 0.8.5", "regex", "rust-embed", diff --git a/crates/cli/src/main.rs b/crates/cli/src/main.rs index 441f701f01..75d083fcd9 100644 --- a/crates/cli/src/main.rs +++ b/crates/cli/src/main.rs @@ -127,6 +127,9 @@ fn parse_path_with_position(argument_str: &str) -> anyhow::Result { } fn main() -> Result<()> { + #[cfg(unix)] + util::prevent_root_execution(); + // Exit flatpak sandbox if needed #[cfg(any(target_os = "linux", target_os = "freebsd"))] { diff --git a/crates/util/Cargo.toml b/crates/util/Cargo.toml index 805c390639..6a874fd329 100644 --- a/crates/util/Cargo.toml +++ b/crates/util/Cargo.toml @@ -45,6 +45,7 @@ workspace-hack.workspace = true [target.'cfg(unix)'.dependencies] command-fds = "0.3.1" libc.workspace = true +nix = { workspace = true, features = ["user"] } [target.'cfg(windows)'.dependencies] tendril = "0.4.3" diff --git a/crates/util/src/util.rs b/crates/util/src/util.rs index 1165b91ffd..11fb8642c8 100644 --- a/crates/util/src/util.rs +++ b/crates/util/src/util.rs @@ -213,6 +213,28 @@ where items.sort_by(compare); } +/// Prevents execution of the application with root privileges on Unix systems. +/// +/// This function checks if the current process is running with root privileges +/// and terminates the program with an error message unless explicitly allowed via the +/// `ZED_ALLOW_ROOT` environment variable. +#[cfg(unix)] +pub fn prevent_root_execution() { + let is_root = nix::unistd::geteuid().is_root(); + let allow_root = std::env::var("ZED_ALLOW_ROOT").is_ok_and(|val| val == "true"); + + if is_root && !allow_root { + eprintln!( + "\ +Error: Running Zed as root or via sudo is unsupported. + Doing so (even once) may subtly break things for all subsequent non-root usage of Zed. + It is untested and not recommended, don't complain when things break. + If you wish to proceed anyways, set `ZED_ALLOW_ROOT=true` in your environment." + ); + std::process::exit(1); + } +} + #[cfg(unix)] fn load_shell_from_passwd() -> Result<()> { let buflen = match unsafe { libc::sysconf(libc::_SC_GETPW_R_SIZE_MAX) } { diff --git a/crates/zed/Cargo.toml b/crates/zed/Cargo.toml index 1e448acc5b..457ce2b81b 100644 --- a/crates/zed/Cargo.toml +++ b/crates/zed/Cargo.toml @@ -88,7 +88,7 @@ markdown_preview.workspace = true menu.workspace = true migrator.workspace = true mimalloc = { version = "0.1", optional = true } -nix = { workspace = true, features = ["pthread", "signal", "user"] } +nix = { workspace = true, features = ["pthread", "signal"] } node_runtime.workspace = true notifications.workspace = true outline.workspace = true diff --git a/crates/zed/src/main.rs b/crates/zed/src/main.rs index ce21b7e66e..93afdb48c0 100644 --- a/crates/zed/src/main.rs +++ b/crates/zed/src/main.rs @@ -162,22 +162,7 @@ fn fail_to_open_window(e: anyhow::Error, _cx: &mut App) { pub fn main() { #[cfg(unix)] - { - let is_root = nix::unistd::geteuid().is_root(); - let allow_root = env::var("ZED_ALLOW_ROOT").is_ok_and(|val| val == "true"); - - // Prevent running Zed with root privileges on Unix systems unless explicitly allowed - if is_root && !allow_root { - eprintln!( - "\ -Error: Running Zed as root or via sudo is unsupported. - Doing so (even once) may subtly break things for all subsequent non-root usage of Zed. - It is untested and not recommended, don't complain when things break. - If you wish to proceed anyways, set `ZED_ALLOW_ROOT=true` in your environment." - ); - process::exit(1); - } - } + util::prevent_root_execution(); // Check if there is a pending installer // If there is, run the installer and exit