diff mbox

[Bug,656285,NEW] arm-semi mishandling SYS_HEAPINFO

Message ID 20101007125628.8009.23815.malonedeb@soybean.canonical.com
State New
Headers show

Commit Message

Stephen Clarke Oct. 7, 2010, 12:56 p.m. UTC
Public bug reported:

I am running qemu-arm on a 32-bit fedora-7 i386 machine:

$ /home/bri0633/users/clarkes/qemu/build/arm-linux-user/qemu-arm --version
qemu-arm version 0.12.3, Copyright (c) 2003-2008 Fabrice Bellard

When I try to run an arm semi-hosted executable, I sometimes get
unexpected segv and sometimes not, depending on the executable.  The
symptom is:

$ /home/bri0633/users/clarkes/qemu/build/arm-linux-user/qemu-arm -cpu cortex-a9 -- a.out
qemu: uncaught target signal 11 (Segmentation fault) - core dumped
Segmentation fault


It appear to be because of the handling of the SYS_HEAPINFO syscall in arm-semi.c.  There it tries to allocate 128M for the heap by calling do_brk() which calls target_mmap().  This is the DEBUG_MMAP diagnostic:

mmap: start=0x00009000 len=0x08001000 prot=rw- flags=MAP_FIXED MAP_ANON
MAP_PRIVATE fd=0 offset=00000000

but this mmap is failing because there are shared libraries (and the
gate page) mapped there:

$ ldd /home/bri0633/users/clarkes/qemu/build/arm-linux-user/qemu-arm
        linux-gate.so.1 =>  (0x00880000)
        librt.so.1 => /lib/librt.so.1 (0x03409000)
        libpthread.so.0 => /lib/libpthread.so.0 (0x00d7d000)
        libm.so.6 => /lib/libm.so.6 (0x00d4b000)
        libc.so.6 => /lib/libc.so.6 (0x00bf5000)
        /lib/ld-linux.so.2 (0x00bd6000)

However, it seems that the code in arm-semi.c does not interpret the result of do_brk() correctly, and thinks that the mapping succeeded.
The following patch appears to fix the problem:

$ diff -u arm-semi.c.orig arm-semi.c

Do you think this is a genuine bug?
Steve.

Comments

Peter Maydell April 18, 2011, 3:50 p.m. UTC | #1
I've just submitted a patchset which I think fixes this bug (among
others):

http://patchwork.ozlabs.org/patch/91789/ [1/3] linux-user: Don't use MAP_FIXED in do_brk()
http://patchwork.ozlabs.org/patch/91790/ [2/3] arm-semi.c: Use correct check for failure of do_brk()
http://patchwork.ozlabs.org/patch/91793/ [3/3] m68k-semi.c: Use correct check for failure of do_brk()
Peter Maydell July 12, 2011, 4:38 p.m. UTC | #2
The patches I mention in commit #4 (and also a fix by Cedric Vincent for
some other brk related bugs) have now been committed to qemu master.


** Changed in: qemu
       Status: New => Fix Committed
Peter Maydell Aug. 12, 2011, 5:52 p.m. UTC | #3
QEMU 0.15.0 has been released with a fix for this bug.


** Changed in: qemu
       Status: Fix Committed => Fix Released
diff mbox

Patch

--- arm-semi.c.orig     2010-09-21 13:19:15.000000000 +0100
+++ arm-semi.c  2010-10-07 13:23:13.000000000 +0100
@@ -475,7 +475,7 @@ 
                 /* Try a big heap, and reduce the size if that fails.  */
                 for (;;) {
                     ret = do_brk(limit);
-                    if (ret != -1)
+                    if (ret == limit)
                         break;
                     limit = (ts->heap_base >> 1) + (limit >> 1);
                 }

Do you think this is a genuine bug?
Steve.

** Affects: qemu
     Importance: Undecided
         Status: New

-- 
arm-semi mishandling SYS_HEAPINFO
https://bugs.launchpad.net/bugs/656285
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.

Status in QEMU: New

Bug description:
I am running qemu-arm on a 32-bit fedora-7 i386 machine:

$ /home/bri0633/users/clarkes/qemu/build/arm-linux-user/qemu-arm --version
qemu-arm version 0.12.3, Copyright (c) 2003-2008 Fabrice Bellard

When I try to run an arm semi-hosted executable, I sometimes get unexpected segv and sometimes not, depending on the executable.  The symptom is:

$ /home/bri0633/users/clarkes/qemu/build/arm-linux-user/qemu-arm -cpu cortex-a9 -- a.out
qemu: uncaught target signal 11 (Segmentation fault) - core dumped
Segmentation fault


It appear to be because of the handling of the SYS_HEAPINFO syscall in arm-semi.c.  There it tries to allocate 128M for the heap by calling do_brk() which calls target_mmap().  This is the DEBUG_MMAP diagnostic:

mmap: start=0x00009000 len=0x08001000 prot=rw- flags=MAP_FIXED MAP_ANON MAP_PRIVATE fd=0 offset=00000000

but this mmap is failing because there are shared libraries (and the gate page) mapped there:

$ ldd /home/bri0633/users/clarkes/qemu/build/arm-linux-user/qemu-arm
        linux-gate.so.1 =>  (0x00880000)
        librt.so.1 => /lib/librt.so.1 (0x03409000)
        libpthread.so.0 => /lib/libpthread.so.0 (0x00d7d000)
        libm.so.6 => /lib/libm.so.6 (0x00d4b000)
        libc.so.6 => /lib/libc.so.6 (0x00bf5000)
        /lib/ld-linux.so.2 (0x00bd6000)

However, it seems that the code in arm-semi.c does not interpret the result of do_brk() correctly, and thinks that the mapping succeeded.
The following patch appears to fix the problem:

$ diff -u arm-semi.c.orig arm-semi.c
--- arm-semi.c.orig     2010-09-21 13:19:15.000000000 +0100
+++ arm-semi.c  2010-10-07 13:23:13.000000000 +0100
@@ -475,7 +475,7 @@ 
                 /* Try a big heap, and reduce the size if that fails.  */
                 for (;;) {
                     ret = do_brk(limit);
-                    if (ret != -1)
+                    if (ret == limit)
                         break;
                     limit = (ts->heap_base >> 1) + (limit >> 1);
                 }