Bug 24152 - __libc_setup_tls may crash if first __sbrk fails
Summary: __libc_setup_tls may crash if first __sbrk fails
Status: NEW
Alias: None
Product: glibc
Classification: Unclassified
Component: libc (show other bugs)
Version: 2.28
: P2 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2019-01-31 15:06 UTC by Szabolcs Nagy
Modified: 2020-08-12 00:16 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:
fweimer: security-


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Szabolcs Nagy 2019-01-31 15:06:19 UTC
in csu/libc-tls.c early libc startup code allocates
tls with __sbrk, this can fail and then errno=ENOMEM
crashes since tls is not yet set up.

ideally it should try to fall back to using mmap as
that's more reliable than brk.

in particular in case of --enable-static-pie builds
the static pie executables may not get reasonable
brk pointer at runtime (bug in old linux kernels)
and the same issue is still present in qemu-user
(first brk may fail).

$ 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 -ld /sbin/ldconfig.real 

Elf file type is DYN (Shared object file)
Entry point 0x9bc0
There are 8 program headers, starting at offset 64

Program Headers:
  Type           Offset             VirtAddr           PhysAddr
                 FileSiz            MemSiz              Flags  Align
  LOAD           0x0000000000000000 0x0000000000000000 0x0000000000000000
                 0x00000000000f1ee8 0x00000000000f1ee8  R E    0x200000
  LOAD           0x00000000000f2838 0x00000000002f2838 0x00000000002f2838
                 0x0000000000005ce0 0x00000000000075a0  RW     0x200000
  DYNAMIC        0x00000000000f5d48 0x00000000002f5d48 0x00000000002f5d48
                 0x00000000000001a0 0x00000000000001a0  RW     0x8
  NOTE           0x0000000000000200 0x0000000000000200 0x0000000000000200
                 0x0000000000000044 0x0000000000000044  R      0x4
  TLS            0x00000000000f2838 0x00000000002f2838 0x00000000002f2838
                 0x0000000000000028 0x0000000000000068  R      0x8
  GNU_EH_FRAME   0x00000000000e38ec 0x00000000000e38ec 0x00000000000e38ec
                 0x0000000000001f94 0x0000000000001f94  R      0x4
  GNU_STACK      0x0000000000000000 0x0000000000000000 0x0000000000000000
                 0x0000000000000000 0x0000000000000000  RW     0x10
  GNU_RELRO      0x00000000000f2838 0x00000000002f2838 0x00000000002f2838
                 0x00000000000037c8 0x00000000000037c8  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
Comment 1 Szabolcs Nagy 2019-01-31 15:49:19 UTC
reported to qemu too:
https://bugs.launchpad.net/qemu/+bug/1814128