Pass old stack pointer in uc_stack.

This commit is contained in:
4lDO2
2024-07-31 15:51:16 +02:00
parent cdae79c129
commit cce268afbf
3 changed files with 23 additions and 11 deletions
+10 -5
View File
@@ -4,7 +4,7 @@ use syscall::*;
use crate::{
proc::{fork_inner, FdGuard},
signal::{inner_fastcall, RtSigarea, SigStack, PROC_CONTROL_STRUCT},
signal::{inner_fastcall, PosixStackt, RtSigarea, SigStack, PROC_CONTROL_STRUCT},
RtTcb,
};
@@ -314,16 +314,21 @@ extern "C" {
fn __relibc_internal_sigentry_crit_second();
fn __relibc_internal_sigentry_crit_third();
}
pub unsafe fn arch_pre(stack: &mut SigStack, area: &mut SigArea) {
pub unsafe fn arch_pre(stack: &mut SigStack, area: &mut SigArea) -> PosixStackt {
if stack.regs.eip == __relibc_internal_sigentry_crit_first as usize {
let stack_ptr = stack.regs.esp as *const usize;
stack.regs.esp = stack_ptr.read();
stack.regs.eip = stack_ptr.sub(1).read();
} else if stack.regs.eip == __relibc_internal_sigentry_crit_second as usize {
stack.regs.eip = area.tmp_eip;
} else if stack.regs.eip == __relibc_internal_sigentry_crit_third as usize {
} else if stack.regs.eip == __relibc_internal_sigentry_crit_second as usize
|| stack.regs.eip == __relibc_internal_sigentry_crit_third as usize
{
stack.regs.eip = area.tmp_eip;
}
PosixStackt {
sp: stack.regs.esp as *mut (),
size: 0, // TODO
flags: 0, // TODO
}
}
#[no_mangle]
pub unsafe fn manually_enter_trampoline() {
+12 -5
View File
@@ -11,7 +11,7 @@ use syscall::{
use crate::{
proc::{fork_inner, FdGuard},
signal::{inner_c, RtSigarea, SigStack, PROC_CONTROL_STRUCT},
signal::{inner_c, PosixStackt, RtSigarea, SigStack, PROC_CONTROL_STRUCT},
RtTcb, Tcb,
};
@@ -424,7 +424,8 @@ extern "C" {
fn __relibc_internal_sigentry_crit_second();
fn __relibc_internal_sigentry_crit_third();
}
pub unsafe fn arch_pre(stack: &mut SigStack, area: &mut SigArea) {
/// Fixes some edge cases, and calculates the value for uc_stack.
pub unsafe fn arch_pre(stack: &mut SigStack, area: &mut SigArea) -> PosixStackt {
// It is impossible to update RSP and RIP atomically on x86_64, without using IRETQ, which is
// almost as slow as calling a SIGRETURN syscall would be. Instead, we abuse the fact that
// signals are disabled in the prologue of the signal trampoline, which allows us to emulate
@@ -438,12 +439,18 @@ pub unsafe fn arch_pre(stack: &mut SigStack, area: &mut SigArea) {
let stack_ptr = stack.regs.rsp as *const usize;
stack.regs.rsp = stack_ptr.read();
stack.regs.rip = stack_ptr.sub(1).read();
} else if stack.regs.rip == __relibc_internal_sigentry_crit_second as usize {
} else if stack.regs.rip == __relibc_internal_sigentry_crit_second as usize
|| stack.regs.rip == __relibc_internal_sigentry_crit_third as usize
{
// Almost finished, just reexecute the jump before tmp_rip is overwritten by this
// deeper-level signal.
stack.regs.rip = area.tmp_rip;
} else if stack.regs.rip == __relibc_internal_sigentry_crit_third as usize {
stack.regs.rip = area.tmp_rip;
}
PosixStackt {
sp: stack.regs.rsp as *mut (),
size: 0, // TODO
flags: 0, // TODO
}
}
+1 -1
View File
@@ -80,7 +80,7 @@ unsafe fn inner(stack: &mut SigStack) {
// asm counts from 0
stack.sig_num += 1;
arch_pre(stack, &mut *os.arch.get());
stack.old_stack = arch_pre(stack, &mut *os.arch.get());
let sigaction = {
let guard = SIGACTIONS_LOCK.lock();