qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH] linux-user: SIGSEGV protection on host/guest si


From: Alex Barcelo
Subject: Re: [Qemu-devel] [PATCH] linux-user: SIGSEGV protection on host/guest signal masks
Date: Mon, 24 Sep 2012 13:28:08 +0200

Not related to this patch submission, but maybe interesting: I have
been testing qemu-system inside qemu-user, and (once this patch is
applied) the combination works and is capable to run a minimal linux
(one that I found on qemu site for testing purposes).

Awfully slow, and with lots of clock issues (I have been playing
around with qemu clock options, but still). But "It Works (TM)".

On Mon, Sep 24, 2012 at 1:23 PM, Alex Barcelo <address@hidden> wrote:
>
> 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 <address@hidden>
> ---
>  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
>



reply via email to

[Prev in Thread] Current Thread [Next in Thread]