[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

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



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 0x10000 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 0x00400000 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=0x70000000 -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=0x7fffffffe3c8, 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
>                  FileSiz            MemSiz              Flags  Align
>   PHDR           0x0000000000000040 0x0000000000200040 0x0000000000000000
>                  0x00000000000001c0 0x00000000000001c0  R E    8
>   INTERP         0x0000000000200000 0x0000000070000000 0x0000000070000000
>                  0x000000000000001c 0x000000000000001c  R      1
>       [Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
>   LOAD           0x0000000000200000 0x0000000070000000 0x0000000070000000
>                  0x00000000000004cc 0x00000000000004cc  R E    200000
>   LOAD           0x00000000002004d0 0x00000000702004d0 0x00000000702004d0
>                  0x0000000000000230 0x0000000000000238  RW     200000
>   DYNAMIC        0x00000000002004e8 0x00000000702004e8 0x00000000702004e8
>                  0x00000000000001d0 0x00000000000001d0  RW     8
>   NOTE           0x000000000020001c 0x000000007000001c 0x000000007000001c
>                  0x0000000000000044 0x0000000000000044  R      4
>   GNU_EH_FRAME   0x00000000002003a4 0x00000000700003a4 0x00000000700003a4
>                  0x0000000000000034 0x0000000000000034  R      4
>   GNU_STACK      0x0000000000000000 0x0000000000000000 0x0000000000000000
>                  0x0000000000000000 0x0000000000000000  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:        0x70000210
> 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 != 0x0000000000200040
> 
> 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
aurelien@aurel32.net                 http://www.aurel32.net


Reply to: