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:
--- 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) {
+ 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;
+ }
}
vaddr_ef = vaddr + eppnt->p_filesz;
--- END ---
-- System Information:
Debian Release: buster/sid
APT prefers unstable-debug
APT policy: (500, 'unstable-debug'), (500, 'stable-updates'), (500,
'unstable'), (500, 'testing'), (500, 'stable'), (1, 'experimental')
Architecture: amd64 (x86_64)
Foreign Architectures: i386
Kernel: Linux 4.19.0-1-amd64 (SMP w/4 CPU cores)
Locale: LANG=en_GB.UTF-8, LC_CTYPE=en_GB.UTF-8 (charmap=UTF-8),
LANGUAGE=en_GB.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash
Init: systemd (via /run/systemd/system)
LSM: AppArmor: enabled
Versions of packages qemu-user depends on:
ii libc6 2.28-3
ii libcapstone3 3.0.5-3
ii libgcc1 1:8.2.0-13
ii libglib2.0-0 2.58.1-2
ii libstdc++6 8.2.0-13
ii zlib1g 1:1.2.11.dfsg-1
Versions of packages qemu-user recommends:
ii qemu-user-static [qemu-user-binfmt] 1:3.1+dfsg-2
Versions of packages qemu-user suggests:
ii sudo 1.8.26-2
-- no debconf information