qemu-devel
[Top][All Lists]
Advanced

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

[Qemu-devel] [Bug 656285] [NEW] arm-semi mishandling SYS_HEAPINFO


From: Stephen Clarke
Subject: [Qemu-devel] [Bug 656285] [NEW] arm-semi mishandling SYS_HEAPINFO
Date: Thu, 07 Oct 2010 12:56:28 -0000

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

Do you think this is a genuine bug?
Steve.





reply via email to

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