qemu-devel
[Top][All Lists]
Advanced

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

Re: [Qemu-devel] Signal management in qemu-user


From: Alex Barcelo
Subject: Re: [Qemu-devel] Signal management in qemu-user
Date: Thu, 24 May 2012 00:38:43 +0200

>> 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.
>
> Alex has the following SIGSEGV workaround queued for our openSUSE package:
> http://repo.or.cz/w/qemu/agraf.git/commit/0760e24b52ff20a328f168ed23b52c9b9c0fd28f
>
> Don't know if it fixes your specific problem. Peter had some ideas how
> to refactor signal handling but iirc didn't have time to work on it himself.

Is it similar at all? (it's easy for me to believe everyone who knows
more than me about qemu internal and patches --everybody in this
mailing list fits this xD). But this bug seems more subtle. I have a
modified test case, maybe a bit more natural:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <malloc.h>
#include <signal.h>

unsigned char *testfun;

void sighandler(int signum) {
    printf("Hello, I'm in a signal handler\n");
    mprotect(testfun, 1024, PROT_READ|PROT_EXEC|PROT_WRITE);
    testfun[ 1]=0x20;
}

int main ( void )
{
    unsigned int ra;
    signal(SIGSEGV, sighandler);
    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)() );

    mprotect(testfun, 1024, PROT_READ);

    //400687: b8 20 00 00 00          mov    $0x20,%eax
    //40068d: c3                      retq
    // This self-modifying code will break because of the sigsegv signal block
    printf ( "0x%02X\n",
             ((unsigned int (*)())testfun)() );
}

// ------------------

This *always* goes wrong without calling the signal handler The output
in usermode emulation is "0x0D\n0x0D" when it should be:
---
0x0D
Hello, I'm in a signal handler
0x20
---
Alexander's patch hasn't any impact on the test case.

I'm a bit lost, and not sure what is the responsible of this. But it's
some kind of bug. I am eager to follow any leads and to think and
generate more test cases, but (maybe) I'm failing to see some basic
logic on signal flow.



reply via email to

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