qemu-user fails to set up a reasonable brk for static-pie

Bug #1814128 reported by Szabolcs Nagy
14
This bug affects 3 people
Affects Status Importance Assigned to Milestone
QEMU
New
Undecided
Unassigned

Bug Description

static pie binaries may not get a reasonable brk,
with glibc this means they crash in early tls setup code:
https://sourceware.org/bugzilla/show_bug.cgi?id=24152

qemu seems to put brk at the end of the data segment,
but if the stack starts (ends) right next to it then
allocation with brk fails.

in such situation i think qemu should arrange the
stack or brk to be elsewhere so there is plenty
space to grow (in case of glibc it's enough if tls
setup works: later allocations can fall back to mmap).

(ubuntu bionic x86_64 ldconfig.real from libc-bin package)
$ qemu-x86_64 -strace -d page /sbin/ldconfig.real
host mmap_min_addr=0x8000
guest_base 0x0
start end size prot
0000004000000000-00000040000f2000 00000000000f2000 r-x
00000040000f2000-00000040002f2000 0000000000200000 ---
00000040002f2000-00000040002fa000 0000000000008000 rw-
00000040002fa000-00000040002fb000 0000000000001000 ---
00000040002fb000-0000004000afb000 0000000000800000 rw-
start_brk 0x0000000000000000
end_code 0x00000040000f1ee8
start_code 0x0000004000000000
start_data 0x00000040002f2838
end_data 0x00000040002f8518
start_stack 0x0000004000afa130
brk 0x00000040002f9dd8
entry 0x0000004000009bc0
argv_start 0x0000004000afa138
env_start 0x0000004000afa148
auxv_start 0x0000004000afa280
28561 brk(NULL) = 0x00000040002fa000
28561 brk(0x00000040002fb1c0) = 0x00000040002fa000
--- SIGSEGV {si_signo=SIGSEGV, si_code=1, si_addr=0xffffffffffffffc0} ---
qemu: uncaught target signal 11 (Segmentation fault) - core dumped

$ readelf -hldSW /tmp/ldconfig.real
ELF Header:
  Magic: 7f 45 4c 46 02 01 01 03 00 00 00 00 00 00 00 00
  Class: ELF64
  Data: 2's complement, little endian
  Version: 1 (current)
  OS/ABI: UNIX - GNU
  ABI Version: 0
  Type: DYN (Shared object file)
  Machine: Advanced Micro Devices X86-64
  Version: 0x1
  Entry point address: 0x9bc0
  Start of program headers: 64 (bytes into file)
  Start of section headers: 1022920 (bytes into file)
  Flags: 0x0
  Size of this header: 64 (bytes)
  Size of program headers: 56 (bytes)
  Number of program headers: 8
  Size of section headers: 64 (bytes)
  Number of section headers: 38
  Section header string table index: 37

Section Headers:
  [Nr] Name Type Address Off Size ES Flg Lk Inf Al
  [ 0] NULL 0000000000000000 000000 000000 00 0 0 0
  [ 1] .note.ABI-tag NOTE 0000000000000200 000200 000020 00 A 0 0 4
  [ 2] .note.gnu.build-id NOTE 0000000000000220 000220 000024 00 A 0 0 4
  [ 3] .gnu.hash GNU_HASH 0000000000000248 000248 00001c 00 A 4 0 8
  [ 4] .dynsym DYNSYM 0000000000000268 000268 000018 18 A 5 1 8
  [ 5] .dynstr STRTAB 0000000000000280 000280 000001 00 A 0 0 1
  [ 6] .rela.dyn RELA 0000000000000288 000288 008748 18 A 4 0 8
  [ 7] .rela.plt RELA 00000000000089d0 0089d0 000318 18 AI 4 27 8
  [ 8] .init PROGBITS 0000000000008ce8 008ce8 000017 00 AX 0 0 4
  [ 9] .plt PROGBITS 0000000000008d00 008d00 000270 10 AX 0 0 16
  [10] .plt.got PROGBITS 0000000000008f70 008f70 000060 08 AX 0 0 8
  [11] .text PROGBITS 0000000000008fd0 008fd0 0bd29c 00 AX 0 0 16
  [12] __libc_freeres_fn PROGBITS 00000000000c6270 0c6270 0016b3 00 AX 0 0 16
  [13] __libc_thread_freeres_fn PROGBITS 00000000000c7930 0c7930 00108f 00 AX 0 0 16
  [14] .fini PROGBITS 00000000000c89c0 0c89c0 000009 00 AX 0 0 4
  [15] .rodata PROGBITS 00000000000c89e0 0c89e0 01af08 00 A 0 0 32
  [16] .stapsdt.base PROGBITS 00000000000e38e8 0e38e8 000001 00 A 0 0 1
  [17] .eh_frame_hdr PROGBITS 00000000000e38ec 0e38ec 001f94 00 A 0 0 4
  [18] .eh_frame PROGBITS 00000000000e5880 0e5880 00c5b8 00 A 0 0 8
  [19] .gcc_except_table PROGBITS 00000000000f1e38 0f1e38 0000b0 00 A 0 0 1
  [20] .tdata PROGBITS 00000000002f2838 0f2838 000028 00 WAT 0 0 8
  [21] .tbss NOBITS 00000000002f2860 0f2860 000040 00 WAT 0 0 8
  [22] .init_array INIT_ARRAY 00000000002f2860 0f2860 000010 08 WA 0 0 8
  [23] .fini_array FINI_ARRAY 00000000002f2870 0f2870 000010 08 WA 0 0 8
  [24] .data.rel.ro PROGBITS 00000000002f2880 0f2880 0034c4 00 WA 0 0 32
  [25] .dynamic DYNAMIC 00000000002f5d48 0f5d48 0001a0 10 WA 5 0 8
  [26] .got PROGBITS 00000000002f5ee8 0f5ee8 000110 08 WA 0 0 8
  [27] .got.plt PROGBITS 00000000002f6000 0f6000 000148 08 WA 0 0 8
  [28] .data PROGBITS 00000000002f6160 0f6160 001bd4 00 WA 0 0 32
  [29] __libc_subfreeres PROGBITS 00000000002f7d38 0f7d38 000060 00 WA 0 0 8
  [30] __libc_IO_vtables PROGBITS 00000000002f7da0 0f7da0 000768 00 WA 0 0 32
  [31] __libc_atexit PROGBITS 00000000002f8508 0f8508 000008 00 WA 0 0 8
  [32] __libc_thread_subfreeres PROGBITS 00000000002f8510 0f8510 000008 00 WA 0 0 8
  [33] .bss NOBITS 00000000002f8520 0f8518 001890 00 WA 0 0 32
  [34] __libc_freeres_ptrs NOBITS 00000000002f9db0 0f8518 000028 00 WA 0 0 8
  [35] .note.stapsdt NOTE 0000000000000000 0f8518 0014cc 00 0 0 4
  [36] .gnu_debuglink PROGBITS 0000000000000000 0f99e4 000034 00 0 0 4
  [37] .shstrtab STRTAB 0000000000000000 0f9a18 0001ab 00 0 0 1
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
  L (link order), O (extra OS processing required), G (group), T (TLS),
  C (compressed), x (unknown), o (OS specific), E (exclude),
  l (large), p (processor specific)

Program Headers:
  Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
  LOAD 0x000000 0x0000000000000000 0x0000000000000000 0x0f1ee8 0x0f1ee8 R E 0x200000
  LOAD 0x0f2838 0x00000000002f2838 0x00000000002f2838 0x005ce0 0x0075a0 RW 0x200000
  DYNAMIC 0x0f5d48 0x00000000002f5d48 0x00000000002f5d48 0x0001a0 0x0001a0 RW 0x8
  NOTE 0x000200 0x0000000000000200 0x0000000000000200 0x000044 0x000044 R 0x4
  TLS 0x0f2838 0x00000000002f2838 0x00000000002f2838 0x000028 0x000068 R 0x8
  GNU_EH_FRAME 0x0e38ec 0x00000000000e38ec 0x00000000000e38ec 0x001f94 0x001f94 R 0x4
  GNU_STACK 0x000000 0x0000000000000000 0x0000000000000000 0x000000 0x000000 RW 0x10
  GNU_RELRO 0x0f2838 0x00000000002f2838 0x00000000002f2838 0x0037c8 0x0037c8 R 0x1

 Section to Segment mapping:
  Segment Sections...
   00 .note.ABI-tag .note.gnu.build-id .gnu.hash .dynsym .dynstr .rela.dyn .rela.plt .init .plt .plt.got .text __libc_freeres_fn __libc_thread_freeres_fn .fini .rodata .stapsdt.base .eh_frame_hdr .eh_frame .gcc_except_table
   01 .tdata .init_array .fini_array .data.rel.ro .dynamic .got .got.plt .data __libc_subfreeres __libc_IO_vtables __libc_atexit __libc_thread_subfreeres .bss __libc_freeres_ptrs
   02 .dynamic
   03 .note.ABI-tag .note.gnu.build-id
   04 .tdata .tbss
   05 .eh_frame_hdr
   06
   07 .tdata .init_array .fini_array .data.rel.ro .dynamic .got

Dynamic section at offset 0xf5d48 contains 22 entries:
  Tag Type Name/Value
 0x000000000000000c (INIT) 0x8ce8
 0x000000000000000d (FINI) 0xc89c0
 0x0000000000000019 (INIT_ARRAY) 0x2f2860
 0x000000000000001b (INIT_ARRAYSZ) 16 (bytes)
 0x000000000000001a (FINI_ARRAY) 0x2f2870
 0x000000000000001c (FINI_ARRAYSZ) 16 (bytes)
 0x000000006ffffef5 (GNU_HASH) 0x248
 0x0000000000000005 (STRTAB) 0x280
 0x0000000000000006 (SYMTAB) 0x268
 0x000000000000000a (STRSZ) 1 (bytes)
 0x000000000000000b (SYMENT) 24 (bytes)
 0x0000000000000015 (DEBUG) 0x0
 0x0000000000000003 (PLTGOT) 0x2f6000
 0x0000000000000002 (PLTRELSZ) 792 (bytes)
 0x0000000000000014 (PLTREL) RELA
 0x0000000000000017 (JMPREL) 0x89d0
 0x0000000000000007 (RELA) 0x288
 0x0000000000000008 (RELASZ) 34632 (bytes)
 0x0000000000000009 (RELAENT) 24 (bytes)
 0x000000006ffffffb (FLAGS_1) Flags: PIE
 0x000000006ffffff9 (RELACOUNT) 1443
 0x0000000000000000 (NULL) 0x0

To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.