Store proc_fd in MaybeUninit with external discriminant.

This commit is contained in:
4lDO2
2025-04-13 12:43:36 +02:00
parent 6e947a9b2f
commit 6d72048b13
3 changed files with 35 additions and 23 deletions
+18 -11
View File
@@ -11,11 +11,11 @@
use core::{
cell::{SyncUnsafeCell, UnsafeCell},
mem::size_of,
mem::{size_of, MaybeUninit},
};
use generic_rt::{ExpectTlsFree, GenericTcb};
use syscall::{Sigcontrol, O_CLOEXEC};
use syscall::Sigcontrol;
use self::{proc::FdGuard, protocol::ProcMeta, sync::Mutex};
@@ -196,10 +196,12 @@ pub unsafe fn initialize(#[cfg(feature = "proc")] proc_fd: FdGuard) {
ppid: metadata.ppid,
#[cfg(feature = "proc")]
proc_fd: Some(proc_fd),
proc_fd: MaybeUninit::new(proc_fd),
#[cfg(not(feature = "proc"))]
proc_fd: None,
proc_fd: MaybeUninit::uninit(),
has_proc_fd: cfg!(feature = "proc"),
});
#[cfg(feature = "proc")]
@@ -216,10 +218,12 @@ pub unsafe fn initialize(#[cfg(feature = "proc")] proc_fd: FdGuard) {
}
}
#[repr(C)] // TODO: is this required?
pub(crate) struct StaticProcInfo {
pid: u32,
ppid: u32, // TODO: dynamic
proc_fd: Option<FdGuard>,
proc_fd: MaybeUninit<FdGuard>,
has_proc_fd: bool,
}
struct DynamicProcInfo {
pgid: u32,
@@ -234,7 +238,8 @@ struct DynamicProcInfo {
static STATIC_PROC_INFO: SyncUnsafeCell<StaticProcInfo> = SyncUnsafeCell::new(StaticProcInfo {
pid: 0,
ppid: 0,
proc_fd: None,
proc_fd: MaybeUninit::uninit(),
has_proc_fd: false,
});
static DYNAMIC_PROC_INFO: Mutex<DynamicProcInfo> = Mutex::new(DynamicProcInfo {
pgid: u32::MAX,
@@ -252,10 +257,9 @@ pub(crate) fn static_proc_info() -> &'static StaticProcInfo {
}
#[inline]
pub fn current_proc_fd() -> &'static FdGuard {
static_proc_info()
.proc_fd
.as_ref()
.expect("proc fd must be present")
let info = static_proc_info();
assert!(info.has_proc_fd);
unsafe { info.proc_fd.assume_init_ref() }
}
struct ChildHookCommonArgs {
@@ -281,7 +285,10 @@ unsafe fn child_hook_common(args: ChildHookCommonArgs) {
.replace(StaticProcInfo {
pid: metadata.pid,
ppid: metadata.ppid,
proc_fd: args.new_proc_fd,
has_proc_fd: args.new_proc_fd.is_some(),
proc_fd: args
.new_proc_fd
.map_or_else(MaybeUninit::uninit, MaybeUninit::new),
})
.proc_fd;
drop(old_proc_fd);
+13 -7
View File
@@ -1,4 +1,7 @@
use core::{fmt::Debug, mem::size_of};
use core::{
fmt::Debug,
mem::{size_of, MaybeUninit},
};
use crate::{
arch::*,
@@ -887,10 +890,12 @@ struct NewChildProc {
pub fn new_child_process(args: &ForkArgs<'_>) -> Result<NewChildProc> {
match *args {
ForkArgs::Managed => {
let this_proc_fd = crate::static_proc_info()
.proc_fd
.as_ref()
.expect("cannot use ForkArgs::Managed without an existing proc info");
let proc_info = crate::static_proc_info();
assert!(
proc_info.has_proc_fd,
"cannot use ForkArgs::Managed without an existing proc info"
);
let this_proc_fd = unsafe { proc_info.proc_fd.assume_init_ref() };
let child_proc_fd = FdGuard::new(syscall::dup(**this_proc_fd, b"fork")?);
let only_thread_fd = FdGuard::new(syscall::dup(*child_proc_fd, b"thread-0")?);
let meta = read_proc_meta(&child_proc_fd)?;
@@ -961,7 +966,8 @@ pub unsafe fn make_init() -> [&'static FdGuard; 2] {
STATIC_PROC_INFO.get().write(crate::StaticProcInfo {
pid: 1,
ppid: 1,
proc_fd: Some(proc_fd),
proc_fd: MaybeUninit::new(proc_fd),
has_proc_fd: true,
});
*DYNAMIC_PROC_INFO.lock() = crate::DynamicProcInfo {
pgid: 1,
@@ -973,7 +979,7 @@ pub unsafe fn make_init() -> [&'static FdGuard; 2] {
sgid: 0,
};
[
(*STATIC_PROC_INFO.get()).proc_fd.as_ref().unwrap(),
(*STATIC_PROC_INFO.get()).proc_fd.assume_init_ref(),
managed_thr_fd,
]
}
+4 -5
View File
@@ -1,15 +1,14 @@
use core::mem::size_of;
use syscall::{Error, Result, ESRCH, O_CLOEXEC};
use syscall::Result;
use crate::{arch::*, proc::*, signal::tmp_disable_signals, static_proc_info, RtTcb};
/// Spawns a new context sharing the same address space as the current one (i.e. a new thread).
pub unsafe fn rlct_clone_impl(stack: *mut usize) -> Result<FdGuard> {
let cur_proc_fd = static_proc_info()
.proc_fd
.as_ref()
.ok_or(Error::new(ESRCH))?;
let proc_info = static_proc_info();
assert!(proc_info.has_proc_fd);
let cur_proc_fd = proc_info.proc_fd.assume_init_ref();
let cur_thr_fd = RtTcb::current().thread_fd();
let new_thr_fd = FdGuard::new(syscall::dup(**cur_proc_fd, b"new-thread")?);