diff options
| author | Markus Pettersson <markus.pettersson@mullvad.net> | 2025-03-12 13:29:35 +0100 |
|---|---|---|
| committer | Markus Pettersson <markus.pettersson@mullvad.net> | 2025-03-12 17:11:37 +0100 |
| commit | 54e0beacffabe26e216e32fb808c643b1e59022d (patch) | |
| tree | 0971bdc53aa817cbb3011bcc22e99e2900f5a10c | |
| parent | 619276793f4162e92da4d02b072e10f3ed24a0da (diff) | |
| download | mullvadvpn-54e0beacffabe26e216e32fb808c643b1e59022d.tar.xz mullvadvpn-54e0beacffabe26e216e32fb808c643b1e59022d.zip | |
Handle `SIGPIPE`
Fix `SIGPIPE` being ignored, which would cause the `mullvad-cli` to
panic if it received a `PIPE` signal (e.g. it was piped into `echo`).
| -rw-r--r-- | CHANGELOG.md | 2 | ||||
| -rw-r--r-- | Cargo.lock | 1 | ||||
| -rw-r--r-- | mullvad-cli/Cargo.toml | 1 | ||||
| -rw-r--r-- | mullvad-cli/src/main.rs | 18 |
4 files changed, 22 insertions, 0 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 5cbecd44cb..5650f6bbe0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,6 +32,8 @@ Line wrap the file at 100 chars. Th - Remove "Any" option for tunnel protocol. The default is now WireGuard. ### Fixed +- Fix `mullvad-cli` panicking if it tried to write to a closed pipe on Linux and macOS. + #### macOS - Fix routing issue caused by upgrading `tun`. diff --git a/Cargo.lock b/Cargo.lock index 03ab60ca35..8c6137b930 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2643,6 +2643,7 @@ dependencies = [ "mullvad-types", "mullvad-version", "natord", + "nix 0.29.0", "serde", "serde_json", "talpid-types", diff --git a/mullvad-cli/Cargo.toml b/mullvad-cli/Cargo.toml index a489123847..70e7a63e1a 100644 --- a/mullvad-cli/Cargo.toml +++ b/mullvad-cli/Cargo.toml @@ -34,6 +34,7 @@ serde_json = { workspace = true } [target.'cfg(all(unix, not(target_os = "android")))'.dependencies] clap_complete = { version = "4.4.8" } +nix = { version = "0.29.0", features = ["signal"] } [target.'cfg(windows)'.build-dependencies] winres = "0.1" diff --git a/mullvad-cli/src/main.rs b/mullvad-cli/src/main.rs index 67990bd888..c77e894d8e 100644 --- a/mullvad-cli/src/main.rs +++ b/mullvad-cli/src/main.rs @@ -152,6 +152,12 @@ enum Cli { #[tokio::main] async fn main() -> Result<()> { + // Handle SIGPIPE + // https://stackoverflow.com/questions/65755853/simple-word-count-rust-program-outputs-valid-stdout-but-panicks-when-piped-to-he/65760807 + // https://github.com/typst/typst/pull/5444 + #[cfg(unix)] + handle_sigpipe().unwrap(); + match Cli::parse() { Cli::Account(cmd) => cmd.handle().await, Cli::Bridge(cmd) => cmd.handle().await, @@ -189,3 +195,15 @@ async fn main() -> Result<()> { } } } + +/// Install the default signal handler for `SIGPIPE`. +/// +/// By default, Rust replaces it with an empty handler because reasons: https://github.com/rust-lang/rust/issues/119980 +#[cfg(unix)] +fn handle_sigpipe() -> Result<(), nix::errno::Errno> { + use nix::sys::signal::{signal, SigHandler, Signal}; + // SAFETY: We do not use the previous signal handler, which could cause UB if done carelessly: + // https://pubs.opengroup.org/onlinepubs/9699919799/functions/signal.html + unsafe { signal(Signal::SIGPIPE, SigHandler::SigDfl) }?; + Ok(()) +} |
