Use SignalThread call and fix fork sighandler sync with procmgr.

This commit is contained in:
4lDO2
2025-04-04 14:56:42 +02:00
parent 93e88b0ce8
commit dc2988968e
5 changed files with 66 additions and 23 deletions
+22 -3
View File
@@ -1,8 +1,12 @@
use core::{fmt::Debug, mem::size_of};
use crate::{
arch::*, auxv_defs::*, read_proc_meta, static_proc_info, RtTcb, DYNAMIC_PROC_INFO,
STATIC_PROC_INFO,
arch::*,
auxv_defs::*,
protocol::{ProcCall, ThreadCall},
read_proc_meta, static_proc_info,
sys::{proc_call, thread_call},
RtTcb, DYNAMIC_PROC_INFO, STATIC_PROC_INFO,
};
use alloc::{boxed::Box, collections::BTreeMap, vec};
@@ -22,7 +26,7 @@ use goblin::elf64::{
use syscall::{
error::*,
flag::{MapFlags, SEEK_SET},
GrantDesc, GrantFlags, Map, ProcSchemeAttrs, SetSighandlerData, MAP_FIXED_NOREPLACE,
CallFlags, GrantDesc, GrantFlags, Map, ProcSchemeAttrs, SetSighandlerData, MAP_FIXED_NOREPLACE,
MAP_SHARED, O_CLOEXEC, PAGE_SIZE, PROT_EXEC, PROT_READ, PROT_WRITE,
};
@@ -410,6 +414,7 @@ where
proc_control_addr: 0,
},
);
// TODO: sync with procmgr
}
unsafe {
@@ -833,6 +838,20 @@ pub fn fork_inner(initial_rsp: *mut usize, args: &ForkArgs) -> Result<usize> {
&crate::signal::current_setsighandler_struct(),
)?;
}
if let Some(ref proc_fd) = new_proc_fd {
proc_call(
**proc_fd,
&mut [],
CallFlags::empty(),
&[ProcCall::SyncSigPctl as usize],
)?;
}
thread_call(
*new_thr_fd,
&mut [],
CallFlags::empty(),
&[ThreadCall::SyncSigTctl as usize],
)?;
}
copy_env_regs(**cur_thr_fd, *new_thr_fd)?;
}
+2
View File
@@ -40,6 +40,7 @@ pub enum ThreadCall {
// TODO: replace with sendfd equivalent syscall for sending memory, or force userspace to
// obtain its TCB memory from this server
SyncSigTctl = 0,
SignalThread = 1,
}
impl ProcCall {
@@ -64,6 +65,7 @@ impl ThreadCall {
pub fn try_from_raw(raw: usize) -> Option<Self> {
Some(match raw {
0 => Self::SyncSigTctl,
1 => Self::SignalThread,
_ => return None,
})
}
+2 -2
View File
@@ -7,7 +7,7 @@ use syscall::{
};
use crate::{
arch::*, proc::FdGuard, protocol::ThreadCall, sync::Mutex, sys::thread_call, RtTcb, Tcb,
arch::*, proc::FdGuard, protocol::ThreadCall, sync::Mutex, sys::this_thread_call, RtTcb, Tcb,
};
#[cfg(target_arch = "x86_64")]
@@ -578,7 +578,7 @@ pub fn setup_sighandler(tcb: &RtTcb) {
syscall::dup(**tcb.thread_fd(), b"sighandler").expect("failed to open sighandler fd"),
);
let _ = syscall::write(*fd, &data).expect("failed to write to sighandler fd");
thread_call(
this_thread_call(
&mut [],
CallFlags::empty(),
&[ThreadCall::SyncSigTctl as usize],
+39 -17
View File
@@ -12,7 +12,7 @@ use syscall::{
use crate::{
arch::manually_enter_trampoline,
proc::FdGuard,
protocol::{ProcCall, ProcKillTarget, WaitFlags},
protocol::{ProcCall, ProcKillTarget, ThreadCall, WaitFlags},
signal::tmp_disable_signals,
DynamicProcInfo, RtTcb, Tcb, DYNAMIC_PROC_INFO,
};
@@ -51,7 +51,7 @@ pub fn posix_write(fd: usize, buf: &[u8]) -> Result<usize> {
#[inline]
pub fn posix_kill(target: ProcKillTarget, sig: usize) -> Result<()> {
match wrapper(false, || {
proc_call(
this_proc_call(
&mut [],
CallFlags::empty(),
&[ProcCall::Kill as usize, target.raw(), sig],
@@ -70,7 +70,7 @@ pub fn posix_sigqueue(pid: usize, sig: usize, arg: usize) -> Result<()> {
pid: posix_getpid(),
};
match wrapper(false, || {
proc_call(
this_proc_call(
&mut siginf,
CallFlags::empty(),
&[ProcCall::Sigq as usize, pid, sig],
@@ -133,11 +133,27 @@ pub fn sys_call(
)
}
}
pub fn proc_call(payload: &mut [u8], flags: CallFlags, metadata: &[usize]) -> Result<usize> {
sys_call(**crate::current_proc_fd(), payload, flags, metadata)
pub fn this_proc_call(payload: &mut [u8], flags: CallFlags, metadata: &[usize]) -> Result<usize> {
proc_call(**crate::current_proc_fd(), payload, flags, metadata)
}
pub fn thread_call(payload: &mut [u8], flags: CallFlags, metadata: &[usize]) -> Result<usize> {
sys_call(**RtTcb::current().thread_fd(), payload, flags, metadata)
pub fn proc_call(
proc_fd: usize,
payload: &mut [u8],
flags: CallFlags,
metadata: &[usize],
) -> Result<usize> {
sys_call(proc_fd, payload, flags, metadata)
}
pub fn thread_call(
thread_fd: usize,
payload: &mut [u8],
flags: CallFlags,
metadata: &[usize],
) -> Result<usize> {
sys_call(thread_fd, payload, flags, metadata)
}
pub fn this_thread_call(payload: &mut [u8], flags: CallFlags, metadata: &[usize]) -> Result<usize> {
thread_call(**RtTcb::current().thread_fd(), payload, flags, metadata)
}
#[derive(Clone, Copy, Debug)]
@@ -168,7 +184,7 @@ pub fn sys_waitpid(target: WaitpidTarget, status: &mut usize, flags: WaitFlags)
WaitpidTarget::ProcGroup { pgid } => (ProcCall::Waitpgid, pgid),
};
wrapper(true, || {
proc_call(
this_proc_call(
unsafe { plain::as_mut_bytes(status) },
CallFlags::empty(),
&[call as usize, pid, flags.bits() as usize],
@@ -176,8 +192,14 @@ pub fn sys_waitpid(target: WaitpidTarget, status: &mut usize, flags: WaitFlags)
})
}
pub fn posix_kill_thread(thread_fd: usize, signal: u32) -> Result<()> {
let killfd = FdGuard::new(syscall::dup(thread_fd, b"signal")?);
match wrapper(false, || syscall::write(*killfd, &signal.to_ne_bytes())) {
match wrapper(false, || {
thread_call(
thread_fd,
&mut [],
CallFlags::empty(),
&[ThreadCall::SignalThread as usize, signal as usize],
)
}) {
Ok(_) | Err(Error { errno: EINTR }) => Ok(()),
Err(error) => Err(error),
}
@@ -228,7 +250,7 @@ pub fn posix_setresugid(ids: &Resugid<Option<u32>>) -> Result<()> {
ids.sgid.unwrap_or(u32::MAX),
]);
proc_call(
this_proc_call(
&mut buf,
CallFlags::empty(),
&[ProcCall::SetResugid as usize],
@@ -276,7 +298,7 @@ pub fn posix_getresugid() -> Resugid<u32> {
}
}
pub fn posix_exit(status: i32) -> ! {
proc_call(
this_proc_call(
&mut [],
CallFlags::empty(),
&[ProcCall::Exit as usize, status as usize],
@@ -285,7 +307,7 @@ pub fn posix_exit(status: i32) -> ! {
unreachable!()
}
pub fn setrens(rns: usize, ens: usize) -> Result<()> {
proc_call(
this_proc_call(
&mut [],
CallFlags::empty(),
&[ProcCall::Setrens as usize, rns, ens],
@@ -293,7 +315,7 @@ pub fn setrens(rns: usize, ens: usize) -> Result<()> {
Ok(())
}
pub fn posix_getpgid(pid: usize) -> Result<usize> {
proc_call(
this_proc_call(
&mut [],
CallFlags::empty(),
&[ProcCall::Setpgid as usize, pid, usize::wrapping_neg(1)],
@@ -303,7 +325,7 @@ pub fn posix_setpgid(pid: usize, pgid: usize) -> Result<()> {
if pgid == usize::wrapping_neg(1) {
return Err(Error::new(EINVAL));
}
proc_call(
this_proc_call(
&mut [],
CallFlags::empty(),
&[ProcCall::Setpgid as usize, pid, pgid],
@@ -311,13 +333,13 @@ pub fn posix_setpgid(pid: usize, pgid: usize) -> Result<()> {
Ok(())
}
pub fn posix_getsid(pid: usize) -> Result<usize> {
proc_call(
this_proc_call(
&mut [],
CallFlags::empty(),
&[ProcCall::Getsid as usize, pid],
)
}
pub fn posix_setsid() -> Result<()> {
proc_call(&mut [], CallFlags::empty(), &[ProcCall::Setsid as usize])?;
this_proc_call(&mut [], CallFlags::empty(), &[ProcCall::Setsid as usize])?;
Ok(())
}
+1 -1
View File
@@ -336,7 +336,7 @@ pub unsafe fn init(auxvs: Box<[[usize; 2]]>) {
redox_rt::initialize(FdGuard::new(proc_fd));
// TODO: Is it safe to assume setup_sighandler has been called at this point?
redox_rt::sys::proc_call(
redox_rt::sys::this_proc_call(
&mut [],
syscall::CallFlags::empty(),
&[redox_rt::protocol::ProcCall::SyncSigPctl as usize],