drop privileges for proxy thread

This commit is contained in:
Robin Appelman 2025-11-10 23:04:16 +01:00
commit b595282810
3 changed files with 54 additions and 0 deletions

33
Cargo.lock generated
View file

@ -586,12 +586,14 @@ dependencies = [
"sd-notify", "sd-notify",
"serde", "serde",
"serde_test", "serde_test",
"syscalls",
"thiserror", "thiserror",
"tokio", "tokio",
"tokio-stream", "tokio-stream",
"toml", "toml",
"tracing", "tracing",
"tracing-subscriber", "tracing-subscriber",
"uzers",
] ]
[[package]] [[package]]
@ -811,6 +813,17 @@ dependencies = [
"syn", "syn",
] ]
[[package]]
name = "serde_repr"
version = "0.1.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "175ee3e80ae9982737ca543e96133087cbd9a485eecc3bc4de9c1a37b47ea59c"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]] [[package]]
name = "serde_spanned" name = "serde_spanned"
version = "1.0.3" version = "1.0.3"
@ -898,6 +911,16 @@ dependencies = [
"unicode-ident", "unicode-ident",
] ]
[[package]]
name = "syscalls"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90db46b5b4962319605d435986c775ea45a0ad2561c09e1d5372b89afeb49cf4"
dependencies = [
"serde",
"serde_repr",
]
[[package]] [[package]]
name = "thiserror" name = "thiserror"
version = "2.0.17" version = "2.0.17"
@ -1077,6 +1100,16 @@ version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
[[package]]
name = "uzers"
version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4df81ff504e7d82ad53e95ed1ad5b72103c11253f39238bcc0235b90768a97dd"
dependencies = [
"libc",
"log",
]
[[package]] [[package]]
name = "valuable" name = "valuable"
version = "0.1.1" version = "0.1.1"

View file

@ -21,6 +21,8 @@ futures-concurrency = "7.6.3"
humansize = { version = "2.1.3", features = ["no_alloc"] } humansize = { version = "2.1.3", features = ["no_alloc"] }
neli = "0.7.1" neli = "0.7.1"
either = "1.15.0" either = "1.15.0"
uzers = "0.12.1"
syscalls = "0.7.0"
[dev-dependencies] [dev-dependencies]
serde_test = "1.0.177" serde_test = "1.0.177"

View file

@ -11,9 +11,11 @@ use std::path::{Path, PathBuf};
use std::sync::Arc; use std::sync::Arc;
use std::sync::atomic::{AtomicU64, Ordering}; use std::sync::atomic::{AtomicU64, Ordering};
use std::thread::spawn; use std::thread::spawn;
use syscalls::{Sysno, syscall};
use thiserror::Error; use thiserror::Error;
use tokio::runtime::Builder; use tokio::runtime::Builder;
use tracing::error; use tracing::error;
use uzers::{get_group_by_name, get_user_by_name};
#[derive(Debug, Error)] #[derive(Debug, Error)]
pub enum ProxyError { pub enum ProxyError {
@ -60,6 +62,13 @@ impl ActiveProxy {
(None, ns_handle) (None, ns_handle)
}; };
let nobody_uid = get_user_by_name("nobody")
.map(|user| user.uid())
.unwrap_or(65534);
let nobody_gid = get_group_by_name("nobody")
.map(|group| group.gid())
.unwrap_or(65534);
let source = config.source.clone(); let source = config.source.clone();
spawn(move || { spawn(move || {
let rt = match Builder::new_current_thread().enable_io().build() { let rt = match Builder::new_current_thread().enable_io().build() {
@ -90,6 +99,16 @@ impl ActiveProxy {
error!(%error, "Failed to join target network namespace for proxy"); error!(%error, "Failed to join target network namespace for proxy");
return; return;
} }
// raw syscall since the libc `setuid`/`setgui` set it for the entire process
unsafe {
if let Err(error) = syscall!(Sysno::setgid, nobody_gid)
.and_then(|_| syscall!(Sysno::setuid, nobody_uid))
{
error!(%error, "Failed drop privileges for proxy thread");
}
}
proxy.run(destination, abort_reg, run_stats).await; proxy.run(destination, abort_reg, run_stats).await;
}); });
}); });