qemu-user needs SIGSEGV (at least) for some internal use. If the guest application masks it and does unsafe sigprocmask, then the application crashes. Problems happen in applications with self-modifying code (who also change the signal mask). Other guest applications may have related problems if they use the SIGSEGV.
A way to be more safe is adding a wrapper for all sigprocmask calls from the guest. The wrapper proposed here is quite simple, but the code can be improved, here I try to ensure that the wrapper is set up properly. Here, a test case where qemu-user goes wrong: //////////// #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/mman.h> #include <malloc.h> #include <signal.h> unsigned char *testfun; int main ( void ) { unsigned int ra; testfun=memalign(getpagesize(),1024); // We block the SIGSEGV signal, used by qemu-user sigset_t set; sigemptyset(&set); sigaddset(&set, 11); sigprocmask(SIG_BLOCK, &set, NULL); mprotect(testfun, 1024, PROT_READ|PROT_EXEC|PROT_WRITE); //400687: b8 0d 00 00 00 mov $0xd,%eax //40068d: c3 retq testfun[ 0]=0xb8; testfun[ 1]=0x0d; testfun[ 2]=0x00; testfun[ 3]=0x00; testfun[ 4]=0x00; testfun[ 5]=0xc3; printf ( "0x%02X\n", ((unsigned int (*)())testfun)() ); //400687: b8 20 00 00 00 mov $0x20,%eax //40068d: c3 retq // This self-modifying code will break because of the sigsegv signal block testfun[ 1]=0x20; printf ( "0x%02X\n", ((unsigned int (*)())testfun)() ); } //////////// On an i386 native host: 0x0D 0x20 On a non-patched qemu-i386: 0x0D Segmentation fault Alex Barcelo (2): signal: added a wrapper for sigprocmask function signal: sigsegv protection on do_sigprocmask linux-user/qemu.h | 1 + linux-user/signal.c | 27 +++++++++++++++++++++++++++ linux-user/syscall.c | 14 +++++++------- 3 files changed, 35 insertions(+), 7 deletions(-) -- 1.7.5.4