I'm working in a "big" (=complex, strange) project[1] and come across a bug
in signal management. I have been able to narrow it down to this program:

#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)() );
}

Running it in a i386 machine works and gives an output of "0x0d\n0x20".
Running it in a qemu-i386 segfaults. Because the self-modifying code raises
a SIGSEGV in the qemu (I understand that it is the method used by qemu to
handle self-modifying code). But the sigprocmask disables the SIGSEGV and
the qemu-user... does nothing to avoid it. So the SIGSEGV is unmanaged and
breaks the program.

I will work in this bug (assuming that nobody is working on it). I suppose
that I have to make qemu aware of the signals on the guest and the signals
on himself. And do NOT allow the guest doing dangerous manipulations
(intercepting the syscall).

Is there something I have to take into acoount? Am I right in my
assumptions? Some guru to give me some advice ;) ?

[1] The project is puting a qemu-system-i386 crosscompiled in a qemu-ppc.
The "first guest" has LOTS of self-modifying code (qemu-system). I have
been bughunting to achieve this "qemu-tower". And correct signal management
is a must (as qemu uses lots of signal management, and an incomplete
implementation on qemu-user means segfault and things breaking).

Reply via email to