From ad5f3814fa665fe1c7123b02a91feeec80b0d50d Mon Sep 17 00:00:00 2001 From: jD91mZM2 <me@krake.one> Date: Tue, 30 Jul 2019 15:54:25 +0200 Subject: [PATCH] Add way to ignore signals --- src/arch/x86_64/interrupt/syscall.rs | 10 +++++----- src/context/signal.rs | 11 +++++++++-- syscall | 2 +- 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/src/arch/x86_64/interrupt/syscall.rs b/src/arch/x86_64/interrupt/syscall.rs index 1e2baba1..dd6b812f 100644 --- a/src/arch/x86_64/interrupt/syscall.rs +++ b/src/arch/x86_64/interrupt/syscall.rs @@ -1,6 +1,6 @@ use crate::arch::macros::InterruptStack; use crate::arch::{gdt, pti}; -use crate::syscall::flag::{PTRACE_STOP_PRE_SYSCALL, PTRACE_STOP_POST_SYSCALL, PTRACE_FLAG_SYSEMU}; +use crate::syscall::flag::{PTRACE_FLAG_IGNORE, PTRACE_STOP_PRE_SYSCALL, PTRACE_STOP_POST_SYSCALL}; use crate::{ptrace, syscall}; use x86::shared::msr; @@ -22,11 +22,11 @@ macro_rules! with_interrupt_stack { unsafe fn $wrapped(stack: *mut InterruptStack) { let _guard = ptrace::set_process_regs(stack); - let not_sysemu = ptrace::breakpoint_callback(PTRACE_STOP_PRE_SYSCALL, None) - .and_then(|_| ptrace::next_breakpoint().map(|b| b & PTRACE_FLAG_SYSEMU != PTRACE_FLAG_SYSEMU)); + let thumbs_up = ptrace::breakpoint_callback(PTRACE_STOP_PRE_SYSCALL, None) + .and_then(|_| ptrace::next_breakpoint().map(|f| !f.contains(PTRACE_FLAG_IGNORE))); - if not_sysemu.unwrap_or(true) { - // If not on a sysemu breakpoint + if thumbs_up.unwrap_or(true) { + // If syscall not ignored let $stack = &mut *stack; $stack.scratch.rax = $code; } diff --git a/src/context/signal.rs b/src/context/signal.rs index d89d31d4..942fb28c 100644 --- a/src/context/signal.rs +++ b/src/context/signal.rs @@ -1,7 +1,7 @@ use alloc::sync::Arc; use core::mem; use syscall::data::PtraceEvent; -use syscall::flag::{PTRACE_STOP_SIGNAL, SIG_DFL, SIG_IGN, SIGCHLD, SIGCONT, SIGSTOP, SIGTSTP, SIGTTIN, SIGTTOU}; +use syscall::flag::{PTRACE_FLAG_IGNORE, PTRACE_STOP_SIGNAL, SIG_DFL, SIG_IGN, SIGCHLD, SIGCONT, SIGKILL, SIGSTOP, SIGTSTP, SIGTTIN, SIGTTOU}; use syscall::ptrace_event; use crate::context::{contexts, switch, Status, WaitpidKey}; @@ -24,7 +24,14 @@ pub extern "C" fn signal_handler(sig: usize) { let handler = action.sa_handler.map(|ptr| ptr as usize).unwrap_or(0); - ptrace::breakpoint_callback(PTRACE_STOP_SIGNAL, Some(ptrace_event!(PTRACE_STOP_SIGNAL, sig, handler))); + let thumbs_down = ptrace::breakpoint_callback(PTRACE_STOP_SIGNAL, Some(ptrace_event!(PTRACE_STOP_SIGNAL, sig, handler))) + .and_then(|_| ptrace::next_breakpoint().map(|f| f.contains(PTRACE_FLAG_IGNORE))); + + if sig != SIGKILL && thumbs_down.unwrap_or(false) { + // If signal can be and was ignored + crate::syscall::sigreturn().unwrap(); + unreachable!(); + } if handler == SIG_DFL { match sig { diff --git a/syscall b/syscall index 51f0ef28..75a1e6f9 160000 --- a/syscall +++ b/syscall @@ -1 +1 @@ -Subproject commit 51f0ef2826ef2b0369766c8f23c8069ae0a56846 +Subproject commit 75a1e6f970bad42c7460b8164e59028c61eaf645 -- GitLab