From bfd521ff49b96d1a52fce233f742fa673554f4e6 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sun, 20 Apr 2025 16:20:56 +0200 Subject: [PATCH] Fix sudo for procmgr --- Cargo.lock | 65 +++++++++++++++++++++++++++++++++++++++++++++++-- Cargo.toml | 7 ++++++ src/bin/sudo.rs | 49 ++++++++++++++++++++----------------- 3 files changed, 96 insertions(+), 25 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 920ed0df7b..e3c10a5a01 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -113,6 +113,11 @@ name = "extra" version = "0.1.0" source = "git+https://gitlab.redox-os.org/redox-os/libextra.git#cf213969493db8667052a591e32a1e26d43c4234" +[[package]] +name = "generic-rt" +version = "0.1.0" +source = "git+https://gitlab.redox-os.org/redox-os/relibc#a30f13ee9b560f30cbfb41349b056d9b078862ef" + [[package]] name = "getrandom" version = "0.2.15" @@ -124,6 +129,17 @@ dependencies = [ "wasi", ] +[[package]] +name = "goblin" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f27c1b4369c2cd341b5de549380158b105a04c331be5db9110eef7b6d2742134" +dependencies = [ + "log", + "plain", + "scroll", +] + [[package]] name = "hermit-abi" version = "0.1.19" @@ -165,6 +181,12 @@ dependencies = [ "redox_syscall", ] +[[package]] +name = "log" +version = "0.4.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" + [[package]] name = "numtoa" version = "0.2.4" @@ -183,6 +205,12 @@ dependencies = [ "sdl2-sys", ] +[[package]] +name = "plain" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6" + [[package]] name = "proc-macro2" version = "1.0.88" @@ -211,6 +239,18 @@ dependencies = [ "libredox", ] +[[package]] +name = "redox-rt" +version = "0.1.0" +source = "git+https://gitlab.redox-os.org/redox-os/relibc#a30f13ee9b560f30cbfb41349b056d9b078862ef" +dependencies = [ + "bitflags 2.6.0", + "generic-rt", + "goblin", + "plain", + "redox_syscall", +] + [[package]] name = "redox-scheme" version = "0.5.0" @@ -247,8 +287,7 @@ dependencies = [ [[package]] name = "redox_syscall" version = "0.5.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2f103c6d277498fbceb16e84d317e2a400f160f46904d5f5410848c829511a3" +source = "git+https://gitlab.redox-os.org/redox-os/syscall.git#8f646a63ac9c3aa532a37ddfdc136ec19878f0d6" dependencies = [ "bitflags 2.6.0", ] @@ -284,6 +323,26 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "scroll" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04c565b551bafbef4157586fa379538366e4385d42082f255bfd96e4fe8519da" +dependencies = [ + "scroll_derive", +] + +[[package]] +name = "scroll_derive" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1db149f81d46d2deba7cd3c50772474707729550221e69588478ebf9ada425ae" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "sdl2" version = "0.35.2" @@ -395,7 +454,9 @@ dependencies = [ "libc", "libredox", "orbclient", + "plain", "redox-daemon", + "redox-rt", "redox-scheme", "redox_event", "redox_liner", diff --git a/Cargo.toml b/Cargo.toml index a9ec5d7caa..f0a9817d14 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -55,6 +55,7 @@ path = "src/bin/usermod.rs" clap = "2.33.0" extra = { git = "https://gitlab.redox-os.org/redox-os/libextra.git" } orbclient = "0.3.47" +plain = "0.2.3" redox-daemon = "0.1.3" redox_liner = "0.5.2" libc = "0.2.171" @@ -66,5 +67,11 @@ redox_syscall = "0.5" redox_users = "0.4.6" termion = "4" +[target.'cfg(target_os = "redox")'.dependencies] +redox-rt = { git = "https://gitlab.redox-os.org/redox-os/relibc", default-features = false } + +[patch.crates-io] +redox_syscall = { git = "https://gitlab.redox-os.org/redox-os/syscall.git" } + [profile.release] lto = true diff --git a/src/bin/sudo.rs b/src/bin/sudo.rs index 3114a74f8a..61e4392e6e 100644 --- a/src/bin/sudo.rs +++ b/src/bin/sudo.rs @@ -7,14 +7,16 @@ use std::process::{Command, exit}; use extra::option::OptionalExt; use libredox::flag::O_CLOEXEC; +use redox_rt::protocol::ProcCall; +use redox_rt::sys::proc_call; use redox_scheme::scheme::SchemeSync; use redox_scheme::{ CallerCtx, OpenResult, RequestKind, Response, SendFdRequest, SignalBehavior, Socket, }; use redox_users::{All, AllGroups, AllUsers, Config, get_uid}; -use syscall::error::*; use syscall::flag::*; use syscall::schemev2::NewFdFlags; +use syscall::{dup, error::*}; use termion::input::TermRead; const MAX_ATTEMPTS: u16 = 3; @@ -94,9 +96,13 @@ pub fn main() { } } + // FIXME move to libredox + unsafe extern "C" { + safe fn redox_cur_procfd_v0() -> usize; + } + // Elevate privileges of our own process with help from the sudo daemon - let self_proc = syscall::open("/scheme/thisproc/current/open_via_dup", 0).unwrap(); - syscall::sendfd(file, self_proc, 0, 0).unwrap(); + syscall::sendfd(file, dup(redox_cur_procfd_v0(), &[]).unwrap(), 0, 0).unwrap(); run_command_as_root(&cmd, &args.collect()); } @@ -220,28 +226,25 @@ impl Scheme { let handle = self.handles.get_mut(&req.id()).ok_or(Error::new(EBADF))?; match std::mem::replace(handle, Handle::Placeholder) { Handle::AwaitingContextFd => { - let mut context_file = usize::MAX; - req.obtain_fd(socket, FobtainFdFlags::empty(), Err(&mut context_file))?; - let context_file = unsafe { OwnedFd::from_raw_fd(context_file as RawFd) }; + let mut proc_fd = usize::MAX; + req.obtain_fd(socket, FobtainFdFlags::empty(), Err(&mut proc_fd))?; + let proc_fd = unsafe { OwnedFd::from_raw_fd(proc_fd as RawFd) }; - let context_uid_fd = unsafe { - OwnedFd::from_raw_fd( - syscall::dup(context_file.as_raw_fd() as usize, b"uid")? as RawFd - ) - }; - let context_gid_fd = unsafe { - OwnedFd::from_raw_fd( - syscall::dup(context_file.as_raw_fd() as usize, b"gid")? as RawFd - ) - }; + let [ruid, euid, suid] = [0, 0, 0]; + let [rgid, egid, sgid] = [0, 0, 0]; + let mut payload = [0; size_of::() * 6]; + plain::slice_from_mut_bytes(&mut payload) + .unwrap() + .copy_from_slice(&[ruid, euid, suid, rgid, egid, sgid]); - // The caller was previously authenticated as member of the sudo group. Allow it to - // elevate privileges of a single process (likely itself). - syscall::write(context_uid_fd.as_raw_fd() as usize, b"0") - .map_err(|_| Error::new(EIO))?; - - syscall::write(context_gid_fd.as_raw_fd() as usize, b"0") - .map_err(|_| Error::new(EIO))?; + if let Err(err) = proc_call( + proc_fd.as_raw_fd() as usize, + &mut payload, + CallFlags::empty(), + &[ProcCall::SetResugid as u64], + ) { + eprintln!("failed to setresugid: {err}"); + } } old => { *handle = old;