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