qemu-devel
[Top][All Lists]
Advanced

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

Re: [Qemu-devel] qemu-img segfaults on MIPS hosts due to not having an e


From: Daniel P. Berrange
Subject: Re: [Qemu-devel] qemu-img segfaults on MIPS hosts due to not having an executable stack
Date: Mon, 13 Jun 2016 15:45:55 +0100
User-agent: Mutt/1.6.1 (2016-04-27)

On Mon, Jun 13, 2016 at 03:11:08PM +0100, Peter Maydell wrote:
> I investigated this qemu-img segfault today
>  https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=815409
> 
> It's pretty confusing, but as you can see from this gdb log:
> 
> 0x00513488      185             if (sizef < 0 || sizef > UINT64_MAX) {
> 2: x/3i $pc
> => 0x513488 <parse_option_size+124>:    move    at,at
>    0x51348c <parse_option_size+128>:    bc1f    0x5134fc 
> <parse_option_size+240>
>    0x513490 <parse_option_size+132>:    lw      v0,40(sp)
> (gdb)
> 0x0051348c      185             if (sizef < 0 || sizef > UINT64_MAX) {
> 2: x/3i $pc
> => 0x51348c <parse_option_size+128>:    bc1f    0x5134fc 
> <parse_option_size+240>
>    0x513490 <parse_option_size+132>:    lw      v0,40(sp)
>    0x513494 <parse_option_size+136>:    lui     v0,0x53
> (gdb) info reg
>           zero       at       v0       v1       a0       a1       a2       a3
>  R0   00000000 00000001 00540000 40f00000 00000000 40f00000 00000000 00000000
>             t0       t1       t2       t3       t4       t5       t6       t7
>  R8   00000001 00000000 00010000 005280dc 00000001 fffffffc 812299b0 8d5c8000
>             s0       s1       s2       s3       s4       s5       s6       s7
>  R16  77ff6fbc 0096e764 00526f34 764c8e90 00526f34 00000001 00000000 0098a8b0
>             t8       t9       k0       k1       gp       sp       s8       ra
>  R24  00000007 76d38400 764ca040 00000000 00571af0 764c8e30 00000000 0051345c
>         status       lo       hi badvaddr    cause       pc
>       00109cf3 00000000 00000000 764c8ff8 00800024 0051348c
>           fcsr      fir  restart
>       00000004 00730000 00000000
> (gdb) si
> warning: GDB can't find the start of the function at 0x764c8e18.
> 
> Program received signal SIGSEGV, Segmentation fault.
> 0x764c8e18 in ?? ()
> 2: x/3i $pc
> => 0x764c8e18:  lw      v0,40(sp)
>    0x764c8e1c:  break   0x202
>    0x764c8e20:  tne     zero,zero,0x2f4
> 
> when we try to singlestep the bc1f insn we suddenly find ourselves
> sat with a segfault at a PC which is slightly below the user SP.
> 
> This turns out to be because the in-kernel fp emulation assumes the
> stack is always executable; the kernel sources say:
>  http://lxr.free-electrons.com/source/arch/mips/math-emu/dsemul.c#L73
> "The strategy is to push the instruction onto the user stack and put
>  a trap after it which we can catch and jump to the required address"
> 
> which is what we've got here; the "BREAK 514" noted in the comment
> is the "break 0x202" in the debugger log.
> 
> QEMU currently allocates coroutine stacks with a plain g_malloc(),
> which makes them r/w but not exec. That's a bug in QEMU which we
> should fix (though I'm not sure how best to identify the required
> permissions for stacks). It's a bit unhelpful of the kernel to
> assume an executable stack and not give a useful diagnostic or
> failure mode if it's not true, though.

I'd suggest we just #ifdef the code base on architecture, on that basis
all platforms except mips are probably happy with non-exec stack.

eg, just change the g_malloc(size) to

  mmap(0, size,
  #ifdef (TARGET_MIPS)
       /* FP emulation in linux requires executable stack */
       PROT_READ | PROT_WRITE | PROT_EXEC,
  #else
       PROT_READ | PROT_WRITE,
  #endif
       MAP_PRIVATE | MAP_ANONYMOUS,
       -1, 0);



Regards,
Daniel
-- 
|: http://berrange.com      -o-    http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org              -o-             http://virt-manager.org :|
|: http://autobuild.org       -o-         http://search.cpan.org/~danberr/ :|
|: http://entangle-photo.org       -o-       http://live.gnome.org/gtk-vnc :|



reply via email to

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