Page MenuHomeFreeBSD

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

Authored by alfredo.junior_eldorado.org.br on Mon, Dec 2, 10:56 PM.

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

Lint
Lint OK
Unit
No Unit Test Coverage
Build Status
Buildable 27916
Build 26085: arc lint + arc unit

Event Timeline

kib accepted this revision.Mon, Dec 2, 11:03 PM
kib added inline comments.
libexec/rtld-elf/map_object.c
233

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

This revision is now accepted and ready to land.Mon, Dec 2, 11:03 PM
kib added inline comments.Mon, Dec 2, 11:05 PM
libexec/rtld-elf/map_object.c
233

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.junior_eldorado.org.br 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.Tue, Dec 3, 8:40 PM
kib accepted this revision.Tue, Dec 3, 9:23 PM
This revision is now accepted and ready to land.Tue, Dec 3, 9:23 PM