Page MenuHomeFreeBSD

rtld: do not try to mmap a zero-sized PT_LOAD
ClosedPublic

Authored by alfredo on Dec 2 2019, 10:56 PM.
Referenced Files
F103264780: D22634.id.diff
Fri, Nov 22, 7:50 PM
F103236346: D22634.diff
Fri, Nov 22, 12:25 PM
Unknown Object (File)
Thu, Nov 21, 4:03 PM
Unknown Object (File)
Thu, Nov 21, 2:26 PM
Unknown Object (File)
Thu, Nov 21, 1:27 PM
Unknown Object (File)
Thu, Nov 21, 11:08 AM
Unknown Object (File)
Wed, Nov 20, 5:40 PM
Unknown Object (File)
Wed, Nov 20, 6:07 AM

Details

Summary

RTLD currently tries to mmap a zero-sized PT_LOAD header, that will return EINVAL and abort. (Thanks to @bdragon for suggesting the solution)

This was reproduced on PowerPC64 LLVM90/ELFv2 experimental build when trying to run binaries linked against /usr/loca/lib/libGLEW.so.2 (ports/graphics/glew). As example glewinfo and glinfo fails with:

ld-elf.so.1: /usr/local/lib/libGLEW.so.2: mmap of data failed: Invalid argument

Here it's how headers looks like: (note FileSiz zero in the fourth LOAD header):

[root@alfredo-2 /usr/ports/graphics/glew]# readelf -l /usr/local/lib/libGLEW.so.2        
 
Elf file type is DYN (Shared object file)
Entry point 0x80000
There are 8 program headers, starting at offset 64
 
Program Headers:
  Type           Offset             VirtAddr           PhysAddr
                 FileSiz            MemSiz              Flg    Align
  PHDR           0x0000000000000040 0x0000000000000040 0x0000000000000040
                 0x00000000000001c0 0x00000000000001c0  R      0x8
  LOAD           0x0000000000000000 0x0000000000000000 0x0000000000000000
                 0x000000000007097c 0x000000000007097c  R      0x10000
  LOAD           0x0000000000080000 0x0000000000080000 0x0000000000080000
                 0x0000000000061134 0x0000000000061134  R E    0x10000
  LOAD           0x00000000000f0000 0x00000000000f0000 0x00000000000f0000
                 0x000000000000a420 0x000000000000a420  RW     0x10000
  LOAD           0x0000000000100000 0x0000000000100000 0x0000000000100000
                 0x0000000000000000 0x0000000000005be8  RW     0x10000
  DYNAMIC        0x00000000000f3270 0x00000000000f3270 0x00000000000f3270
                 0x0000000000000130 0x0000000000000130  RW     0x8
  GNU_RELRO      0x00000000000f0000 0x00000000000f0000 0x00000000000f0000
                 0x000000000000a420 0x000000000000a420  R      0x1
  GNU_STACK      0x0000000000000000 0x0000000000000000 0x0000000000000000
                 0x0000000000000000 0x0000000000000000  RW     0
 
 Section to Segment mapping:
  Segment Sections...
   00    
   01     .dynsym .gnu.hash .hash .dynstr .rela.dyn .rela.plt .rodata .eh_frame
   02     .text .glink
   03     .data.rel.ro .dynamic .got .toc
   04     .bss .plt .branch_lt
   05     .dynamic
   06     .data.rel.ro .dynamic .got .toc
   07
Test Plan

Run glinfo and glewinfo on PowerPC64 LLVM90/ELFv2 experimental build

Diff Detail

Repository
rS FreeBSD src repository - subversion
Lint
Lint Not Applicable
Unit
Tests Not Applicable

Event Timeline

kib added inline comments.
libexec/rtld-elf/map_object.c
233 ↗(On Diff #65138)

Since you are changing the line, replace (caddr_t)-1 with MAP_FAILED.

This revision is now accepted and ready to land.Dec 2 2019, 11:03 PM
libexec/rtld-elf/map_object.c
233 ↗(On Diff #65138)

Also you may write the code by avoiding nested if:

if (data_vlimit != data_vaddr && mmap(data_addr, ...) == MAP_FAILED) {
<keep previous indentation there>
alfredo marked 2 inline comments as done.

Updated with reviewers comment.
I changed the indentation a bit as it looked incorrect after looking code around. Let me know if still need changes. Thanks!

This revision now requires review to proceed.Dec 3 2019, 8:40 PM
This revision is now accepted and ready to land.Dec 3 2019, 9:23 PM
This revision was automatically updated to reflect the committed changes.