Create a safe wrapper by protecting the signal mask. Instead of doing a simple passthrough of the sigprocmask, the wrapper manipulates the signal mask in a safe way for the qemu internal. This is done by avoiding SIGSEGV bit mask manipulation from the guest.
We also return the same bit on the SIGSEGV. This is not required for most applications, but if the application checks it, then it will see that somethings fishy about it (and, in fact, maybe it should). If we do not want the guest to be aware of those manipulations, then it should be implemented in another way, but this seems quite clean and consistent. The wrapper can be improved to add more features for better signal managing, but this seems enough for "simple" self-modifying code. Signed-off-by: Alex Barcelo <abarc...@ac.upc.edu> --- linux-user/signal.c | 19 ++++++++++++++++++- 1 files changed, 18 insertions(+), 1 deletions(-) diff --git a/linux-user/signal.c b/linux-user/signal.c index 3d25b7d..b965d89 100644 --- a/linux-user/signal.c +++ b/linux-user/signal.c @@ -5468,7 +5468,24 @@ long do_rt_sigreturn(CPUArchState *env) */ int do_sigprocmask(int how, const sigset_t *set, sigset_t *oldset) { - return sigprocmask(how, set, oldset); + int ret; + sigset_t val; + sigset_t *temp; + if (set) { + val = *set; + temp = &val; + sigdelset(temp, SIGSEGV); + } else { + temp = NULL; + } + ret = sigprocmask(how, temp, oldset); + + /* Force set state of SIGSEGV, may be best for some apps, maybe not so good + * This is not required for qemu to work */ + if (oldset) { + sigaddset(oldset, SIGSEGV); + } + return ret; } void process_pending_signals(CPUArchState *cpu_env) -- 1.7.5.4