qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH] linux-user: SIGSEGV protection on host/guest signal masks
@ 2012-09-24 11:23 Alex Barcelo
  2012-09-24 11:28 ` Alex Barcelo
  2012-09-24 12:53 ` Peter Maydell
  0 siblings, 2 replies; 4+ messages in thread
From: Alex Barcelo @ 2012-09-24 11:23 UTC (permalink / raw)
  To: qemu-devel; +Cc: Riku Voipio, Alex Barcelo


There are some situations where the guest application changes the SIGSEGV and messes with qemu-user way of handling self-modifying code.

In case of qemu-system, this happens. Emulation of qemu-system inside qemu-user doesn't work because of this. This patch doesn't aim to do a complete signal protection and achieve bulletproof signal management for every test case, instead it is a small easy-to-understand patch that resolves the most common problem.

Signed-off-by: Alex Barcelo <abarcelo@ac.upc.edu>
---
 linux-user/syscall.c |   18 ++++++++++++++++++
 1 files changed, 18 insertions(+), 0 deletions(-)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 6257a04..95bb818 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -5897,6 +5897,16 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
         }
         break;
 #endif
+
+/*
+ * Use SETSIGNAL and GETSIGNAL macros for SIGSEGV protection.
+ *
+ * This should protect SIGSEGV unconscious manipulations from guest apps
+ * (but we still do not let the emulated software play the signal game)
+ */
+#define SETSIGNAL(set) sigdelset( (set), SIGSEGV)
+#define GETSIGNAL(get) sigaddset( (get), SIGSEGV)
+
 #ifdef TARGET_NR_sigprocmask
     case TARGET_NR_sigprocmask:
         {
@@ -5952,6 +5962,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
                 target_to_host_old_sigset(&set, p);
                 unlock_user(p, arg2, 0);
                 set_ptr = &set;
+                // override SIGSEGV when changing mask
+                SETSIGNAL(set_ptr);
             } else {
                 how = 0;
                 set_ptr = NULL;
@@ -5960,6 +5972,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
             if (!is_error(ret) && arg3) {
                 if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
                     goto efault;
+                // ignore real SIGSEGV state in mask
+                GETSIGNAL(&oldset);
                 host_to_target_old_sigset(p, &oldset);
                 unlock_user(p, arg3, sizeof(target_sigset_t));
             }
@@ -5992,6 +6006,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
                 target_to_host_sigset(&set, p);
                 unlock_user(p, arg2, 0);
                 set_ptr = &set;
+                // override SIGSEGV when changing mask
+                SETSIGNAL(set_ptr);
             } else {
                 how = 0;
                 set_ptr = NULL;
@@ -6001,6 +6017,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
                 if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
                     goto efault;
                 host_to_target_sigset(p, &oldset);
+                // ignore real SIGSEGV state in mask
+                GETSIGNAL(&oldset);
                 unlock_user(p, arg3, sizeof(target_sigset_t));
             }
         }
-- 
1.7.5.4

^ permalink raw reply related	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2012-09-25  7:07 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-09-24 11:23 [Qemu-devel] [PATCH] linux-user: SIGSEGV protection on host/guest signal masks Alex Barcelo
2012-09-24 11:28 ` Alex Barcelo
2012-09-24 12:53 ` Peter Maydell
2012-09-25  7:07   ` Alex Barcelo

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).