qemu-devel
[Top][All Lists]
Advanced

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

Re: [Qemu-devel] Bug#919921: qemu-user Linux ELF loader fails to handle


From: Philippe Mathieu-Daudé
Subject: Re: [Qemu-devel] Bug#919921: qemu-user Linux ELF loader fails to handle pure BSS segments
Date: Mon, 7 Oct 2019 19:34:28 +0200
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.1.0

Hi Ben,

On 10/7/19 7:29 PM, Ben Hutchings wrote:
On Tue, 2019-01-22 at 21:31 -0800, Richard Henderson wrote:
On 1/22/19 1:39 AM, Philippe Mathieu-Daudé wrote:
Hi Ben,

On 1/22/19 6:43 AM, Michael Tokarev wrote:
Forwarding to qemu-devel@
http://bugs.debian.org/919921

Thanks!

20.01.2019 20:55, Ben Hutchings wrote:
Package: qemu-user
Version: 1:3.1+dfsg-2
Severity: normal
Tags: patch

I've been building and testing klibc across many architectures using
qemu-user, and I found that qemu-user fails to load a few programs on
a few architectures, reporting an EINVAL error code.  Here's the
"readelf -l" output for one such program:

      Elf file type is EXEC (Executable file)
      Entry point 0x10000100
      There are 5 program headers, starting at offset 52
           Program Headers:
        Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz
Flg Align
        PHDR           0x000034 0x10000034 0x10000034 0x000a0 0x000a0
R   0x4
        INTERP         0x0000d4 0x100000d4 0x100000d4 0x0002a 0x0002a
R   0x1
            [Requesting program interpreter:
/lib/klibc-R7FVdnsTBUFpWPgCV6FR07b-mf8.so]
        LOAD           0x000000 0x10000000 0x10000000 0x002f8 0x002f8 R
E 0x10000
        LOAD           0x010000 0x10020000 0x10020000 0x00000 0x08000
RW  0x10000
        GNU_STACK      0x000000 0x00000000 0x00000000 0x00000 0x00000
RWE 0x10
            Section to Segment mapping:
        Segment Sections...
         00
         01     .interp
         02     .interp .text .rodata .eh_frame
         03     .bss
         04

The unusual feature of this program, and all the others that failed,
is that there is a LOAD segment with a file-size of 0 (i.e.  only BSS,
no initialised data).  load_elf_image() will try to mmap() initialised
data for this section even though there is none and a length of 0 is
invalid.

The change that seems to fix this is to skip the mmap() in this case:

Is there a reason why my fix can't be applied?  Do I need to open a bug
report in Launchpad for this?

Simply send your patch formally to address@hidden.

--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -2316,11 +2316,13 @@ static void load_elf_image(const char *i
               vaddr_ps = TARGET_ELF_PAGESTART(vaddr);
               vaddr_len = TARGET_ELF_PAGELENGTH(eppnt->p_filesz +
vaddr_po);
   -            error = target_mmap(vaddr_ps, vaddr_len,
-                                elf_prot, MAP_PRIVATE | MAP_FIXED,
-                                image_fd, eppnt->p_offset - vaddr_po);
-            if (error == -1) {
-                goto exit_perror;
+            if (vaddr_len != 0) {

This is probably not the good fix, since now your process doesn't have
anything mapped to use his BSS :)

Not true.  The mapping happens in zero_bss.

What about this fix instead, using the segment memory size rather than
the file size:

-- >8 --
@@ -2314,7 +2314,7 @@ static void load_elf_image(const char *image_name,
int image_fd,
              vaddr = load_bias + eppnt->p_vaddr;
              vaddr_po = TARGET_ELF_PAGEOFFSET(vaddr);
              vaddr_ps = TARGET_ELF_PAGESTART(vaddr);
-            vaddr_len = TARGET_ELF_PAGELENGTH(eppnt->p_filesz + vaddr_po);
+            vaddr_len = TARGET_ELF_PAGELENGTH(eppnt->p_memsz + vaddr_po);

              error = target_mmap(vaddr_ps, vaddr_len,
                                  elf_prot, MAP_PRIVATE | MAP_FIXED,

No, there's only filesz bytes in the file.  I'd expect zero_bss to map over the
extra that you just mapped, but it doesn't help.


r~




reply via email to

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