diff --git a/Cargo.lock b/Cargo.lock index 0b602f6a587..d2be0d12e6e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5745,6 +5745,7 @@ dependencies = [ "nym-types", "nym-validator-client", "opentelemetry", + "pledge", "rand 0.7.3", "serde", "serde_json", @@ -5754,6 +5755,7 @@ dependencies = [ "tokio-util", "toml 0.5.11", "tracing", + "unveil", "url", ] @@ -7215,6 +7217,15 @@ version = "0.3.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" +[[package]] +name = "pledge" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "252599417b7d9a43b7fdc63dd790b0848666a8910b2ebe1a25118309c3c981e5" +dependencies = [ + "libc", +] + [[package]] name = "platforms" version = "3.1.2" @@ -10417,6 +10428,15 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0976c77def3f1f75c4ef892a292c31c0bbe9e3d0702c63044d7c76db298171a3" +[[package]] +name = "unveil" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e7fa867d559102001ec694165ed17d5f82e95213060a65f9c8b6280084bbfec" +dependencies = [ + "libc", +] + [[package]] name = "url" version = "2.4.1" diff --git a/mixnode/Cargo.toml b/mixnode/Cargo.toml index 9ad7c5081f2..b2b106ca61e 100644 --- a/mixnode/Cargo.toml +++ b/mixnode/Cargo.toml @@ -62,6 +62,8 @@ nym-topology = { path = "../common/topology" } nym-validator-client = { path = "../common/client-libs/validator-client" } nym-bin-common = { path = "../common/bin-common", features = ["output_format"] } cpu-cycles = { path = "../cpu-cycles", optional = true } +unveil = "0.3.2" +pledge = "0.4.2" [dev-dependencies] tokio = { workspace = true, features = [ diff --git a/mixnode/src/commands/build_info.rs b/mixnode/src/commands/build_info.rs index 3b763adf3f7..215d930597b 100644 --- a/mixnode/src/commands/build_info.rs +++ b/mixnode/src/commands/build_info.rs @@ -5,6 +5,8 @@ use clap::Args; use nym_bin_common::bin_info_owned; use nym_bin_common::output_format::OutputFormat; +use pledge::pledge; + #[derive(Args)] pub(crate) struct BuildInfo { #[clap(short, long, default_value_t = OutputFormat::default())] @@ -12,5 +14,7 @@ pub(crate) struct BuildInfo { } pub(crate) fn execute(args: BuildInfo) { + pledge("stdio rpath", None).unwrap(); + println!("{}", args.output.format(&bin_info_owned!())) } diff --git a/mixnode/src/commands/describe.rs b/mixnode/src/commands/describe.rs index 5576296bcd0..bca8ba85d9e 100644 --- a/mixnode/src/commands/describe.rs +++ b/mixnode/src/commands/describe.rs @@ -8,6 +8,8 @@ use colored::Colorize; use std::io; use std::io::Write; +use pledge::pledge; + #[derive(Args)] pub(crate) struct Describe { /// The id of the mixnode you want to describe @@ -39,6 +41,8 @@ fn read_user_input() -> String { } pub(crate) fn execute(args: Describe) -> anyhow::Result<()> { + pledge("stdio rpath wpath cpath", None).unwrap(); + // ensure that the mixnode has in fact been initialized let config = try_load_current_config(&args.id)?; diff --git a/mixnode/src/commands/init.rs b/mixnode/src/commands/init.rs index 3e678d3d4ae..89081a773c6 100644 --- a/mixnode/src/commands/init.rs +++ b/mixnode/src/commands/init.rs @@ -13,6 +13,8 @@ use nym_crypto::asymmetric::{encryption, identity}; use std::net::IpAddr; use std::{fs, io}; +use pledge::pledge; + #[derive(Args, Clone)] pub(crate) struct Init { /// Id of the mixnode we want to create config for @@ -63,6 +65,8 @@ fn init_paths(id: &str) -> io::Result<()> { } pub(crate) fn execute(args: &Init) -> anyhow::Result<()> { + pledge("stdio rpath cpath wpath fattr", None).unwrap(); + let override_config_fields = OverrideConfig::from(args.clone()); let id = override_config_fields.id.clone(); eprintln!("Initialising mixnode {id}..."); diff --git a/mixnode/src/commands/node_details.rs b/mixnode/src/commands/node_details.rs index 24dc71cb2f6..cad96eb061b 100644 --- a/mixnode/src/commands/node_details.rs +++ b/mixnode/src/commands/node_details.rs @@ -6,6 +6,8 @@ use crate::node::MixNode; use clap::Args; use nym_bin_common::output_format::OutputFormat; +use pledge::pledge; + #[derive(Args)] pub(crate) struct NodeDetails { /// The id of the mixnode you want to show details for @@ -17,6 +19,8 @@ pub(crate) struct NodeDetails { } pub(crate) fn execute(args: &NodeDetails) -> anyhow::Result<()> { + pledge("stdio rpath", None).unwrap(); + let config = try_load_current_config(&args.id)?; MixNode::new(config)?.print_node_details(args.output); diff --git a/mixnode/src/commands/run.rs b/mixnode/src/commands/run.rs index c4ab5125fbb..ecdf12a6a1d 100644 --- a/mixnode/src/commands/run.rs +++ b/mixnode/src/commands/run.rs @@ -11,6 +11,10 @@ use nym_bin_common::output_format::OutputFormat; use nym_config::helpers::SPECIAL_ADDRESSES; use nym_validator_client::nyxd; use std::net::IpAddr; + +use pledge::pledge; +use unveil::unveil; + #[derive(Args, Clone)] pub(crate) struct Run { /// Id of the nym-mixnode we want to run @@ -70,11 +74,30 @@ fn show_binding_warning(address: &str) { } pub(crate) async fn execute(args: &Run) -> anyhow::Result<()> { + pledge("stdio rpath inet dns unveil", None).unwrap(); + eprintln!("Starting mixnode {}...", args.id); let mut config = try_load_current_config(&args.id)?; config = override_config(config, OverrideConfig::from(args.clone())); + unveil("/etc/ssl", "r") + .or_else(unveil::Error::ignore_platform).unwrap(); + + unveil(config.storage_paths.node_description.display().to_string(), "r") + .or_else(unveil::Error::ignore_platform).unwrap(); + + unveil(config.storage_paths.keys.private_identity_key().display().to_string(), "r") + .or_else(unveil::Error::ignore_platform).unwrap(); + unveil(config.storage_paths.keys.public_identity_key().display().to_string(), "r") + .or_else(unveil::Error::ignore_platform).unwrap(); + unveil(config.storage_paths.keys.private_encryption_key().display().to_string(), "r") + .or_else(unveil::Error::ignore_platform).unwrap(); + unveil(config.storage_paths.keys.public_encryption_key().display().to_string(), "r") + .or_else(unveil::Error::ignore_platform).unwrap(); + + pledge("stdio rpath inet dns", None).unwrap(); + if !version_check(&config) { error!("failed the local version check"); bail!("failed the local version check") diff --git a/mixnode/src/commands/sign.rs b/mixnode/src/commands/sign.rs index 2604a72d1c5..28d205840c6 100644 --- a/mixnode/src/commands/sign.rs +++ b/mixnode/src/commands/sign.rs @@ -14,6 +14,8 @@ use std::convert::TryFrom; use super::version_check; +use pledge::pledge; + #[derive(Args, Clone)] #[clap(group(ArgGroup::new("sign").required(true).args(&["wallet_address", "text", "contract_msg"])))] pub(crate) struct Sign { @@ -113,6 +115,8 @@ fn print_signed_contract_msg( } pub(crate) fn execute(args: &Sign) -> anyhow::Result<()> { + pledge("stdio rpath", None).unwrap(); + let config = try_load_current_config(&args.id)?; if !version_check(&config) { @@ -129,6 +133,8 @@ pub(crate) fn execute(args: &Sign) -> anyhow::Result<()> { }; let identity_keypair = load_identity_keys(&config)?; + pledge("stdio", None).unwrap(); + match signed_target { SignedTarget::Text(text) => { print_signed_text(identity_keypair.private_key(), &text, args.output) diff --git a/mixnode/src/main.rs b/mixnode/src/main.rs index d6383477cc0..bb6e81f8402 100644 --- a/mixnode/src/main.rs +++ b/mixnode/src/main.rs @@ -16,6 +16,8 @@ use nym_mixnode_common::measure; #[cfg(feature = "cpucycles")] use tracing::instrument; +use pledge::pledge; + mod commands; mod config; pub(crate) mod error; @@ -60,6 +62,8 @@ async fn main() -> anyhow::Result<()> { maybe_print_banner(crate_name!(), crate_version!()); } + pledge("stdio rpath cpath wpath fattr inet dns unveil", None).unwrap(); + cfg_if::cfg_if! { if #[cfg(feature = "cpucycles")] { setup_tracing!("mixnode");