diff --git a/Cargo.lock b/Cargo.lock index 02ce92c312..fa5a500e3e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -20,6 +20,7 @@ version = "0.0.0" dependencies = [ "hashbrown", "linked_list_allocator", + "plain", "redox-initfs", "redox-path", "redox-rt", diff --git a/Cargo.toml b/Cargo.toml index b7b2b3366f..3413303d20 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,6 +15,7 @@ hashbrown = { version = "0.14", default-features = false, features = [ "ahash", ] } linked_list_allocator = "0.10" +plain = "0.2" redox-initfs = { git = "https://gitlab.redox-os.org/redox-os/redox-initfs.git", default-features = false } redox_syscall = { version = "0.5.4", default-features = false } redox-scheme = { git = "https://gitlab.redox-os.org/redox-os/redox-scheme.git" } diff --git a/src/exec.rs b/src/exec.rs index 77d00c068a..3d247cbc9d 100644 --- a/src/exec.rs +++ b/src/exec.rs @@ -7,6 +7,14 @@ use syscall::{Error, EINTR}; use redox_rt::proc::*; pub fn main() -> ! { + let auth = FdGuard::new( + syscall::open("/scheme/kernel.proc/authority", O_CLOEXEC) + .expect("failed to get proc authority"), + ); + let this_thr_fd = + FdGuard::new(syscall::dup(*auth, b"cur-context").expect("failed to open open_via_dup")); + let this_thr_fd = unsafe { redox_rt::initialize_freestanding(this_thr_fd) }; + let envs = { let mut env = [0_u8; 4096]; @@ -37,29 +45,27 @@ pub fn main() -> ! { (*(core::ptr::addr_of!(__initfs_header) as *const redox_initfs::types::Header)).initfs_size }; - spawn("initfs daemon", move |write_fd| unsafe { - // Creating a reference to NULL is UB. Mask the UB for now using black_box. - // FIXME use a raw pointer and inline asm for reading instead for the initfs header. - let initfs_start = core::ptr::addr_of!(__initfs_header); - let initfs_length = initfs_length.get() as usize; + spawn( + "initfs daemon", + &auth, + &this_thr_fd, + move |write_fd| unsafe { + // Creating a reference to NULL is UB. Mask the UB for now using black_box. + // FIXME use a raw pointer and inline asm for reading instead for the initfs header. + let initfs_start = core::ptr::addr_of!(__initfs_header); + let initfs_length = initfs_length.get() as usize; - crate::initfs::run( - core::slice::from_raw_parts(initfs_start, initfs_length), - write_fd, - ); - }); + crate::initfs::run( + core::slice::from_raw_parts(initfs_start, initfs_length), + write_fd, + ); + }, + ); - let auth = FdGuard::new(syscall::open("/scheme/kernel.proc/authority", O_CLOEXEC).expect("failed to get proc authority")); - - spawn("process manager", |write_fd| { + spawn("process manager", &auth, &this_thr_fd, |write_fd| { crate::procmngr::run(write_fd, &auth) }); - let this_thr_fd = FdGuard::new( - syscall::dup(*auth, b"cur-context").expect("failed to open open_via_dup"), - ); - let (init_proc_fd, init_thr_fd) = unsafe { - redox_rt::proc::make_init(this_thr_fd) - }; + let init_proc_fd = unsafe { redox_rt::proc::make_init() }; const CWD: &[u8] = b"/scheme/initfs"; const DEFAULT_SCHEME: &[u8] = b"initfs"; @@ -86,8 +92,8 @@ pub fn main() -> ! { fexec_impl( image_file, + this_thr_fd, init_proc_fd, - init_thr_fd, &memory, path.as_bytes(), [path], @@ -101,13 +107,13 @@ pub fn main() -> ! { unreachable!() } -pub(crate) fn spawn(name: &str, inner: impl FnOnce(usize)) { +pub(crate) fn spawn(name: &str, auth: &FdGuard, this_thr_fd: &FdGuard, inner: impl FnOnce(usize)) { let read = syscall::open("/scheme/pipe", O_CLOEXEC).expect("failed to open sync read pipe"); // The write pipe will not inherit O_CLOEXEC, but is closed by the daemon later. let write = syscall::dup(read, b"write").expect("failed to open sync write pipe"); - match fork_impl() { + match fork_impl(&ForkArgs::Init { this_thr_fd, auth }) { Err(err) => { panic!("Failed to fork in order to start {name}: {err}"); } diff --git a/src/procmngr.rs b/src/procmngr.rs index af04a1bf88..3052a6206a 100644 --- a/src/procmngr.rs +++ b/src/procmngr.rs @@ -1,8 +1,9 @@ use core::cell::RefCell; +use core::mem::size_of; use alloc::rc::Rc; -use alloc::vec::Vec; use alloc::vec; +use alloc::vec::Vec; use hashbrown::hash_map::DefaultHashBuilder; use hashbrown::{HashMap, HashSet}; @@ -13,7 +14,9 @@ use redox_scheme::{ }; use slab::Slab; use syscall::schemev2::NewFdFlags; -use syscall::{Error, FobtainFdFlags, Result, EBADF, EBADFD, EEXIST, EINVAL, ENOENT, O_CLOEXEC, O_CREAT}; +use syscall::{ + Error, FobtainFdFlags, Result, EBADF, EBADFD, EEXIST, EINVAL, ENOENT, O_CLOEXEC, O_CREAT, +}; pub fn run(write_fd: usize, auth: &FdGuard) { let socket = Socket::create("proc").expect("failed to open proc scheme socket"); @@ -157,9 +160,7 @@ impl<'a> ProcScheme<'a> { self.processes.insert( child_pid, Process { - threads: vec! [Rc::new(RefCell::new(Thread { - fd: new_ctxt_fd, - }))], + threads: vec![Rc::new(RefCell::new(Thread { fd: new_ctxt_fd }))], ppid: parent_pid, pgid, sid, @@ -176,8 +177,7 @@ impl<'a> ProcScheme<'a> { fn new_thread(&mut self, pid: ProcessId) -> Result { let proc = self.processes.get_mut(&pid).ok_or(Error::new(EBADFD))?; let fd = todo!(); - proc.threads - .push(Rc::new(RefCell::new(Thread { fd }))); + proc.threads.push(Rc::new(RefCell::new(Thread { fd }))); Ok(fd) } } @@ -188,22 +188,26 @@ impl Scheme for ProcScheme<'_> { return Err(Error::new(EEXIST)); } return Ok(OpenResult::ThisScheme { - number: self - .handles - .insert(Handle::Init), + number: self.handles.insert(Handle::Init), flags: NewFdFlags::empty(), }); } Err(Error::new(ENOENT)) } - fn read(&mut self, id: usize, buf: &mut [u8], _offset: u64, _fcntl_flags: u32) -> Result { + fn read( + &mut self, + id: usize, + buf: &mut [u8], + _offset: u64, + _fcntl_flags: u32, + ) -> Result { match self.handles[id] { Handle::Proc(pid) => { let process = self.processes.get(&pid).ok_or(Error::new(EBADFD))?; let metadata = ProcMeta { - pid: pid.into(), - pgid: process.pgid.into(), - ppid: process.ppid.into(), + pid: pid.0 as u32, + pgid: process.pgid.0 as u32, + ppid: process.ppid.0 as u32, euid: process.euid, egid: process.egid, ruid: process.ruid, @@ -211,6 +215,10 @@ impl Scheme for ProcScheme<'_> { ens: process.ens, rns: process.rns, }; + *buf.get_mut(..size_of::()) + .and_then(|b| plain::from_mut_bytes(b).ok()) + .ok_or(Error::new(EINVAL))? = metadata; + Ok(size_of::()) } Handle::Init => return Err(Error::new(EBADF)), } @@ -224,16 +232,21 @@ impl Scheme for ProcScheme<'_> { number: self.handles.insert(Handle::Proc(child_pid)), flags: NewFdFlags::empty(), }) - }, + } b"new-thread" => Ok(OpenResult::OtherScheme { fd: self.new_thread(pid)?.take(), }), - w if w.starts_with("thread-") => { - let idx = core::str::from_utf8(&w["thread-".len()..]).ok().and_then(|s| s.parse::().ok()).ok_or(Error::new(EINVAL))?; + w if w.starts_with(b"thread-") => { + let idx = core::str::from_utf8(&w["thread-".len()..]) + .ok() + .and_then(|s| s.parse::().ok()) + .ok_or(Error::new(EINVAL))?; let process = self.processes.get(&pid).ok_or(Error::new(EBADFD))?; let thread = process.threads.get(idx).ok_or(Error::new(ENOENT))?.borrow(); - return Ok(OpenResult::OtherScheme { fd: syscall::dup(*thread.fd, &[])? }); + return Ok(OpenResult::OtherScheme { + fd: syscall::dup(*thread.fd, &[])?, + }); } _ => return Err(Error::new(EINVAL)), }, diff --git a/src/start.rs b/src/start.rs index ebaeb17505..f85ec084ab 100644 --- a/src/start.rs +++ b/src/start.rs @@ -78,8 +78,6 @@ pub unsafe extern "C" fn start() -> ! { ) .expect("mprotect failed for rest of memory"); - redox_rt::initialize_freestanding(); - // FIXME make the initfs read-only crate::exec::main();