All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] Signal management in qemu-user
@ 2012-05-17  9:23 Alex Barcelo
  2012-05-17 13:33 ` Andreas Färber
  0 siblings, 1 reply; 8+ messages in thread
From: Alex Barcelo @ 2012-05-17  9:23 UTC (permalink / raw)
  To: qemu-devel

[-- Attachment #1: Type: text/plain, Size: 2296 bytes --]

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).

[-- Attachment #2: Type: text/html, Size: 2596 bytes --]

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [Qemu-devel] Signal management in qemu-user
  2012-05-17  9:23 [Qemu-devel] Signal management in qemu-user Alex Barcelo
@ 2012-05-17 13:33 ` Andreas Färber
  2012-05-17 13:42   ` Peter Maydell
  2012-05-23 22:38   ` Alex Barcelo
  0 siblings, 2 replies; 8+ messages in thread
From: Andreas Färber @ 2012-05-17 13:33 UTC (permalink / raw)
  To: Alex Barcelo; +Cc: Peter Maydell, qemu-devel, Alexander Graf

Am 17.05.2012 11:23, schrieb Alex Barcelo:
> 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.

Andreas

-- 
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [Qemu-devel] Signal management in qemu-user
  2012-05-17 13:33 ` Andreas Färber
@ 2012-05-17 13:42   ` Peter Maydell
  2012-05-17 14:16     ` Andreas Färber
  2012-05-23 22:38   ` Alex Barcelo
  1 sibling, 1 reply; 8+ messages in thread
From: Peter Maydell @ 2012-05-17 13:42 UTC (permalink / raw)
  To: Andreas Färber; +Cc: Alex Barcelo, qemu-devel, Alexander Graf

On 17 May 2012 14:33, Andreas Färber <afaerber@suse.de> wrote:
> Am 17.05.2012 11:23, schrieb Alex Barcelo:
>> 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.

No, that's a different issue, see the analysis here:
 http://lists.gnu.org/archive/html/qemu-devel/2012-02/msg02868.html
In that case an internal-to-QEMU allocation fails (because the guest
imposes a severe rlimit), we don't handle it very well and die
horribly. The commit you link to above is a sticking plaster on
the problem and definitely not OK for master.

> Peter had some ideas how to refactor signal handling but iirc
> didn't have time to work on it himself.

That was mostly to do with solving the problem of signals occurring
during emulation of a system call and the consequent race conditions:
 http://lists.gnu.org/archive/html/qemu-devel/2011-12/msg00384.html

I think Alex Barcelo's problem here is unrelated. I'm not very
surprised by it, though -- linux-user is not very robust in
complex edge cases (and in particular is really poor for
threaded programs).

-- PMM

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [Qemu-devel] Signal management in qemu-user
  2012-05-17 13:42   ` Peter Maydell
@ 2012-05-17 14:16     ` Andreas Färber
  0 siblings, 0 replies; 8+ messages in thread
From: Andreas Färber @ 2012-05-17 14:16 UTC (permalink / raw)
  To: Peter Maydell; +Cc: Alex Barcelo, qemu-devel, Alexander Graf

Am 17.05.2012 15:42, schrieb Peter Maydell:
> On 17 May 2012 14:33, Andreas Färber <afaerber@suse.de> wrote:
>> Am 17.05.2012 11:23, schrieb Alex Barcelo:
>>> 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.
> 
> No, that's a different issue, see the analysis here:
>  http://lists.gnu.org/archive/html/qemu-devel/2012-02/msg02868.html
> In that case an internal-to-QEMU allocation fails (because the guest
> imposes a severe rlimit), we don't handle it very well and die
> horribly. The commit you link to above is a sticking plaster on
> the problem and definitely not OK for master.

Note the term "workaround". :-)

/-F

-- 
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [Qemu-devel] Signal management in qemu-user
  2012-05-17 13:33 ` Andreas Färber
  2012-05-17 13:42   ` Peter Maydell
@ 2012-05-23 22:38   ` Alex Barcelo
  2012-05-23 22:50     ` Andreas Färber
  2012-05-23 23:04     ` Peter Maydell
  1 sibling, 2 replies; 8+ messages in thread
From: Alex Barcelo @ 2012-05-23 22:38 UTC (permalink / raw)
  To: Andreas Färber; +Cc: Peter Maydell, qemu-devel, Alexander Graf

>> 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.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [Qemu-devel] Signal management in qemu-user
  2012-05-23 22:38   ` Alex Barcelo
@ 2012-05-23 22:50     ` Andreas Färber
  2012-05-23 23:04     ` Peter Maydell
  1 sibling, 0 replies; 8+ messages in thread
From: Andreas Färber @ 2012-05-23 22:50 UTC (permalink / raw)
  To: Alex Barcelo; +Cc: Peter Maydell, qemu-devel, Alexander Graf

Am 24.05.2012 00:38, schrieb Alex Barcelo:
>>> 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?

Peter answered that already: No, it isn't. Sorry for the confusion.

Andreas

-- 
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [Qemu-devel] Signal management in qemu-user
  2012-05-23 22:38   ` Alex Barcelo
  2012-05-23 22:50     ` Andreas Färber
@ 2012-05-23 23:04     ` Peter Maydell
  2012-05-24  7:19       ` Alex Barcelo
  1 sibling, 1 reply; 8+ messages in thread
From: Peter Maydell @ 2012-05-23 23:04 UTC (permalink / raw)
  To: Alex Barcelo; +Cc: Alexander Graf, Andreas Färber, qemu-devel

On 23 May 2012 23:38, Alex Barcelo <abarcelo@ac.upc.edu> wrote:
> This *always* goes wrong without calling the signal handler

I haven't looked too closely, but I suspect we're just not
paying any attention to whether memory does or doesn't have
the PROT_EXEC permission when we translate code from it.

This is the kind of corner case that the linux-user code is
often not very good at, because not many guest programs play
this sort of game.

-- PMM

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [Qemu-devel] Signal management in qemu-user
  2012-05-23 23:04     ` Peter Maydell
@ 2012-05-24  7:19       ` Alex Barcelo
  0 siblings, 0 replies; 8+ messages in thread
From: Alex Barcelo @ 2012-05-24  7:19 UTC (permalink / raw)
  To: Peter Maydell; +Cc: Alexander Graf, Andreas Färber, qemu-devel

On Thu, May 24, 2012 at 1:04 AM, Peter Maydell <peter.maydell@linaro.org> wrote:
> On 23 May 2012 23:38, Alex Barcelo <abarcelo@ac.upc.edu> wrote:
>> This *always* goes wrong without calling the signal handler
>
> I haven't looked too closely, but I suspect we're just not
> paying any attention to whether memory does or doesn't have
> the PROT_EXEC permission when we translate code from it.

Ok, makes sense.

> This is the kind of corner case that the linux-user code is
> often not very good at, because not many guest programs play
> this sort of game.

I see. But, does qemu-system play this sort of game? I haven't been
able to find this sort of protect-catch-unprotect for execution, and
my goal is to run qemu-system on top of qemu-user. The self-modifying
code is done through the write protection of memory pages, but I can't
see which would be the root problem. It seems that self-modifying code
is done in two levels, in qemu-user and in qemu-system, but this
should not be a problem... once the signal mask is correctly managed
by usermode. Am I right?

I plan to bugfix the usermode masking problem as best as I can, but
first I wanted to make sure that this will bring me closer to the
goal.

Thanks a lot for your time and patience

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2012-05-24  7:20 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-05-17  9:23 [Qemu-devel] Signal management in qemu-user Alex Barcelo
2012-05-17 13:33 ` Andreas Färber
2012-05-17 13:42   ` Peter Maydell
2012-05-17 14:16     ` Andreas Färber
2012-05-23 22:38   ` Alex Barcelo
2012-05-23 22:50     ` Andreas Färber
2012-05-23 23:04     ` Peter Maydell
2012-05-24  7:19       ` Alex Barcelo

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.