Bug#749122: ld.so crashes when sections are placed at different addresses

2014-05-26 Thread Aurelien Jarno
On Mon, May 26, 2014 at 10:42:54AM +0200, Goswin von Brederlow wrote:
 On Sat, May 24, 2014 at 03:17:25PM +0200, Aurelien Jarno wrote:
  On Sat, May 24, 2014 at 12:23:23PM +0200, Goswin von Brederlow wrote:
   Package: libc6
   Version: 2.18-7
   Severity: normal
   File: /lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
   
   Hi,
   
   I want to mmap a large file to 0x1 because the data contains
   pointers and was originally at that offset. Mapping somewhere else and
   relocating all the pointers is impossible. Unfortunately on amd64
   binaries are normaly mapped at 0x0040 and 0x0060a000 onwards,
   conflicting with mapping the file. So I tried to link my binary to be
   at a different address. But that makes ld.so crash with SIGSEGV or
   SIGILL.
   
   --
   echo 'int main() { return 0; }' | gcc-4.8 
   -Wl,--section-start=.interp=0x7000 -x c -
   gdb ./a.out
   
   Program received signal SIGSEGV, Segmentation fault.
   dl_main (phdr=phdr@entry=0x6fe00040, phnum=phnum@entry=8, 
   user_entry=user_entry@entry=0x7fffe3c8, auxv=optimized out)
   at rtld.c:1169
  
  The kernel maps the PHDR entry at address 0x6fe00040 (this can also be
  seen using LD_SHOW_AUXV=1), but in practice nothing is mapped at this
  address, so ld.so crashes on the first access at this address.
  
  This is likely due to a non conform ELF file format, anyway it's clearly
  not a bug in libc. Please dig more about the issue and report the bug
  against the correct package. Closing the bug.
 
 Looking more closely at what is mapped there seems indeed be something
 missing, which would be the kernels fault I guess.
 
 But something is wrong with ld.so too. readelf shows this:
 
   Type   Offset VirtAddr   PhysAddr
  FileSizMemSiz  Flags  Align
   PHDR   0x0040 0x00200040 0x
  0x01c0 0x01c0  R E8
   INTERP 0x0020 0x7000 0x7000
  0x001c 0x001c  R  1
   [Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
   LOAD   0x0020 0x7000 0x7000
  0x04cc 0x04cc  R E20
   LOAD   0x002004d0 0x702004d0 0x702004d0
  0x0230 0x0238  RW 20
   DYNAMIC0x002004e8 0x702004e8 0x702004e8
  0x01d0 0x01d0  RW 8
   NOTE   0x0020001c 0x701c 0x701c
  0x0044 0x0044  R  4
   GNU_EH_FRAME   0x002003a4 0x73a4 0x73a4
  0x0034 0x0034  R  4
   GNU_STACK  0x 0x 0x
  0x 0x  RW 10
 
 But ld.so says:
 % LD_SHOW_AUXV=1 ./a.out 
 AT_SYSINFO_EHDR: 0x7fff0bb76000
 AT_HWCAP:bfe9fbff
 AT_PAGESZ:   4096
 AT_CLKTCK:   100
 AT_PHDR: 0x6fe00040
 AT_PHENT:56
 AT_PHNUM:8
 AT_BASE: 0x7fc226189000
 AT_FLAGS:0x0
 AT_ENTRY:0x7210
 AT_UID:  1000
 AT_EUID: 1000
 AT_GID:  1000
 AT_EGID: 1000
 AT_SECURE:   0
 AT_RANDOM:   0x7fff0bb12ab9
 AT_EXECFN:   ./a.out
 AT_PLATFORM: x86_64
 
 0x6fe00040 != 0x00200040
 
 So is readelf wrong or ld.so?

As said previously, the AT_PHDR address is provided by the kernel in
the aux vector. ld.so just uses this address and hasn't parsed the ELF
header at that point.

-- 
Aurelien Jarno  GPG: 4096R/1DDD8C9B
aurel...@aurel32.net http://www.aurel32.net


-- 
To UNSUBSCRIBE, email to debian-bugs-dist-requ...@lists.debian.org
with a subject of unsubscribe. Trouble? Contact listmas...@lists.debian.org



Bug#749122: ld.so crashes when sections are placed at different addresses

2014-05-24 Thread Goswin von Brederlow
Package: libc6
Version: 2.18-7
Severity: normal
File: /lib/x86_64-linux-gnu/ld-linux-x86-64.so.2

Hi,

I want to mmap a large file to 0x1 because the data contains
pointers and was originally at that offset. Mapping somewhere else and
relocating all the pointers is impossible. Unfortunately on amd64
binaries are normaly mapped at 0x0040 and 0x0060a000 onwards,
conflicting with mapping the file. So I tried to link my binary to be
at a different address. But that makes ld.so crash with SIGSEGV or
SIGILL.

--
echo 'int main() { return 0; }' | gcc-4.8 
-Wl,--section-start=.interp=0x7000 -x c -
gdb ./a.out

Program received signal SIGSEGV, Segmentation fault.
dl_main (phdr=phdr@entry=0x6fe00040, phnum=phnum@entry=8, 
user_entry=user_entry@entry=0x7fffe3c8, auxv=optimized out)
at rtld.c:1169
1169rtld.c: No such file or directory.
(gdb) bt
#0  dl_main (phdr=phdr@entry=0x6fe00040, phnum=phnum@entry=8, 
user_entry=user_entry@entry=0x7fffe3c8, auxv=optimized out)
at rtld.c:1169
#1  0x77df2215 in _dl_sysdep_start (
start_argptr=start_argptr@entry=0x7fffe480, 
dl_main=dl_main@entry=0x77dde670 dl_main) at ../elf/dl-sysdep.c:249
#2  0x77de19f6 in _dl_start_final (arg=0x7fffe480) at rtld.c:332
#3  _dl_start (arg=0x7fffe480) at rtld.c:558
#4  0x77dde188 in _start () from /lib64/ld-linux-x86-64.so.2
#5  0x0001 in ?? ()
#6  0x7fffe6fd in ?? ()
#7  0x in ?? ()
--
echo 'int main() { return 0; }' | gcc-4.8 -Wl,--section-start=.interp=0x4 
-x c -
gdb ./a.out 

During startup program terminated with signal SIGKILL, Killed.
(gdb) bt
No stack.
--
Surprisingly the following works again:

echo 'int main() { return 0; }' | gcc-4.8 
-Wl,--section-start=.interp=0x7200 -x c -

The difference seems to be where the section headers are placed in the
output file.

Working:   Start of section headers:  2528 (bytes into file)
Crashing:  Start of section headers:  2099168 (bytes into file)

MfG
Goswin

-- System Information:
Debian Release: jessie/sid
  APT prefers unstable
  APT policy: (500, 'unstable'), (1, 'experimental')
Architecture: amd64 (x86_64)
Foreign Architectures: i386

Kernel: Linux 3.14-1-amd64 (SMP w/4 CPU cores)
Locale: LANG=C, LC_CTYPE=de_DE (charmap=ISO-8859-1)
Shell: /bin/sh linked to /bin/dash

Versions of packages libc6:amd64 depends on:
ii  libgcc1  1:4.9.0-1

libc6:amd64 recommends no packages.

Versions of packages libc6:amd64 suggests:
ii  debconf [debconf-2.0]  1.5.53
pn  glibc-doc  none
ii  locales2.18-5

-- debconf information excluded


-- 
To UNSUBSCRIBE, email to debian-bugs-dist-requ...@lists.debian.org
with a subject of unsubscribe. Trouble? Contact listmas...@lists.debian.org