OSDev.org

The Place to Start for Operating System Developers
It is currently Mon Sep 23, 2019 7:13 am

All times are UTC - 6 hours




Post new topic Reply to topic  [ 5 posts ] 
Author Message
 Post subject: why won't this PIE run?
PostPosted: Fri Mar 15, 2019 10:11 am 
Offline
Member
Member
User avatar

Joined: Sat Oct 16, 2010 3:38 pm
Posts: 636
Still having trouble with my linker...

I am targetting Linux, and trying to make my linker output a PIE because it seems to be the new standard and is more secure anyway. I link against the C runtime and the C standard library. I invoke it as follows:

Code:
comptools-x86_64-linux-gnu-ld -shared /usr/lib/x86_64-linux-gnu/Scrt1.o /usr/lib/x86_64-linux-gnu/crti.o hello.o /usr/lib/x86_64-linux-gnu/crtn.o -L. -lc -t hello.lds


hello.lds contains the following code (custom syntax, but should be clear enough):

Code:
. = 0;

entry _start;

section .text
{
   load .init;
   load .fini;
   load .rodata;
   load .text;
}

align 0x1000;
section .data
{
   load .data;
}

align 0x1000;
section .bss
{
   load .bss;
}


The output I get has the following program headers:

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

Program Headers:
  Type           Offset             VirtAddr           PhysAddr
                 FileSiz            MemSiz              Flags  Align
  PHDR           0x0000000000000040 0x0000000000004040 0x0000000000004040
                 0x00000000000001c0 0x00000000000001c0  R E    0x8
  INTERP         0x0000000000003000 0x0000000000003000 0x0000000000003000
                 0x000000000000001c 0x000000000000001c  RW     0x1000
      [Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
  LOAD           0x0000000000000000 0x0000000000004000 0x0000000000004000
                 0x0000000000000200 0x0000000000000200  R E    0x1000
  LOAD           0x0000000000000000 0x0000000000002000 0x0000000000002000
                 0x0000000000000000 0x0000000000000020  RW     0x1000
  LOAD           0x0000000000001000 0x0000000000001000 0x0000000000001000
                 0x0000000000000004 0x0000000000000004  RW     0x1000
  LOAD           0x0000000000002000 0x0000000000000000 0x0000000000000000
                 0x0000000000000093 0x0000000000000093  R E    0x1000
  LOAD           0x0000000000003000 0x0000000000003000 0x0000000000003000
                 0x00000000000004d7 0x00000000000004d7  RWE    0x1000
  DYNAMIC        0x000000000000334c 0x000000000000334c 0x000000000000334c
                 0x00000000000000f0 0x00000000000000f0  RWE    0x8

Section to Segment mapping:
  Segment Sections...
   00     
   01     .interp
   02     
   03     .bss
   04     .data
   05     .text
   06     .dynstr .dynamic .plt .plt.rela .got.rela .hash .dynsym .got.plt .got .interp
   07     .dynamic


Running this program produces a segfault, but without any core dump. However, if i run it with "/lib64/ld-linux-x86-64.so.2 ./a.out", I get the following error:

Code:
./a.out: error while loading shared libraries: ./a.out: failed to map segment from shared object


Looking at the code of the dynamic linker, this happens if mmap() fails. I don't see why it would, however. A comment in the code claims that it expects there are no holes in the segments. There are no holes in the above, but I wondered what would happen if I sort the program headers a little. So I wrote up a quick program which sorts the program headers, and writes the result to "result". This gives me the following:

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

Program Headers:
  Type           Offset             VirtAddr           PhysAddr
                 FileSiz            MemSiz              Flags  Align
  PHDR           0x0000000000000040 0x0000000000004040 0x0000000000004040
                 0x00000000000001c0 0x00000000000001c0  R E    0x8
  INTERP         0x0000000000003000 0x0000000000003000 0x0000000000003000
                 0x000000000000001c 0x000000000000001c  RW     0x1000
      [Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
  LOAD           0x0000000000002000 0x0000000000000000 0x0000000000000000
                 0x0000000000000093 0x0000000000000093  R E    0x1000
  LOAD           0x0000000000001000 0x0000000000001000 0x0000000000001000
                 0x0000000000000004 0x0000000000000004  RW     0x1000
  LOAD           0x0000000000000000 0x0000000000002000 0x0000000000002000
                 0x0000000000000000 0x0000000000000020  RW     0x1000
  LOAD           0x0000000000003000 0x0000000000003000 0x0000000000003000
                 0x00000000000004d7 0x00000000000004d7  RWE    0x1000
  LOAD           0x0000000000000000 0x0000000000004000 0x0000000000004000
                 0x0000000000000200 0x0000000000000200  R E    0x1000
  DYNAMIC        0x000000000000334c 0x000000000000334c 0x000000000000334c
                 0x00000000000000f0 0x00000000000000f0  RWE    0x8

Section to Segment mapping:
  Segment Sections...
   00     
   01     .interp
   02     .text
   03     .data
   04     .bss
   05     .dynstr .dynamic .plt .plt.rela .got.rela .hash .dynsym .got.plt .got .interp
   06     
   07     .dynamic


Running this causes a segfault in the dynamic linker:

Code:
$ gdb result
GNU gdb (Ubuntu 8.1-0ubuntu3) 8.1.0.20180409-git
Copyright (C) 2018 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from result...(no debugging symbols found)...done.
(gdb) run
Starting program: /home/mariusz/Madd/CompTools/comptools-build/result

Program received signal SIGSEGV, Segmentation fault.
dl_main (phdr=0x555555552040, phnum=8, user_entry=<optimised out>,
    auxv=<optimised out>) at rtld.c:1148
1148   rtld.c: No such file or directory.
(gdb) where
#0  dl_main (phdr=0x555555552040, phnum=8, user_entry=<optimised out>,
    auxv=<optimised out>) at rtld.c:1148
#1  0x00007ffff7defdd0 in _dl_sysdep_start (
    start_argptr=start_argptr@entry=0x7fffffffde80,
    dl_main=dl_main@entry=0x7ffff7dd7660 <dl_main>) at ../elf/dl-sysdep.c:253
#2  0x00007ffff7dd7128 in _dl_start_final (arg=0x7fffffffde80) at rtld.c:414
#3  _dl_start (arg=0x7fffffffde80) at rtld.c:521
#4  0x00007ffff7dd6098 in _start () from /lib64/ld-linux-x86-64.so.2
#5  0x0000000000000001 in ?? ()
#6  0x00007fffffffe1fb in ?? ()
#7  0x0000000000000000 in ?? ()
(gdb) print phdr
$1 = (const Elf64_Phdr *) 0x555555552040


So it thinks the program header table is at some random address, which is not accessible.

I have no diea what is going on here at all. I have attached both binaries: a.out is the direct output of the linker, "result" is the same but with program headers sorted.

Does anyone have any hint what might be happening?


Attachments:
bins.zip [2.75 KiB]
Downloaded 4 times

_________________
Glidix: An x86_64 POSIX-compliant operating system, aiming to be as optimized as possible, especially in graphics.
https://glidix.madd-games.org/
Top
 Profile  
 
 Post subject: Re: why won't this PIE run?
PostPosted: Sat Mar 16, 2019 12:19 pm 
Offline
Member
Member

Joined: Thu May 17, 2007 1:27 pm
Posts: 607
That is a very stupid question, but does "gcc -pie hello.o" work? What is your hello.lds?

EDIT: The offset 0 R/W segment is quite strange - your linker script maps the file header as R/W?
EDIT2: The linker (or kernel) might also just refuse to map something as RWE.

_________________
managarm: A microkernel-based OS that is capable of running a Wayland desktop


Top
 Profile  
 
 Post subject: Re: why won't this PIE run?
PostPosted: Sat Mar 16, 2019 1:39 pm 
Offline
Member
Member

Joined: Wed Aug 30, 2017 8:24 am
Posts: 241
Korona wrote:
EDIT: The offset 0 R/W segment is quite strange - your linker script maps the file header as R/W?

That I thought as well, but the second load segment also has file size 0. There just isn't a .data section in the file, so no reference to any file data is made. I didn't even know this could happen.


Top
 Profile  
 
 Post subject: Re: why won't this PIE run?
PostPosted: Sat Mar 16, 2019 6:03 pm 
Offline
Member
Member
User avatar

Joined: Sat Oct 16, 2010 3:38 pm
Posts: 636
gcc -pie hello.o does work, and the resulting binary runs.

There is no .data section because the code does not use any initialised data; and the reason one of the segments has file size zero is because it is the '.bss' section.

With PIC disabled, when I try to link using my own linker, it refuses because of "undefined references" to random stuff in libc, and also things like "__dso_handle" (not sure where these would be defined).

The RWE cannot be the problem, since the symptoms are different when I sort the program headers.

_________________
Glidix: An x86_64 POSIX-compliant operating system, aiming to be as optimized as possible, especially in graphics.
https://glidix.madd-games.org/


Top
 Profile  
 
 Post subject: Re: why won't this PIE run?
PostPosted: Sat Mar 16, 2019 6:04 pm 
Offline
Member
Member
User avatar

Joined: Sat Oct 16, 2010 3:38 pm
Posts: 636
nullplan wrote:
Korona wrote:
EDIT: The offset 0 R/W segment is quite strange - your linker script maps the file header as R/W?

That I thought as well, but the second load segment also has file size 0. There just isn't a .data section in the file, so no reference to any file data is made. I didn't even know this could happen.


I provided the code of 'hello.lds' in my first post.

The file header part is generated implicitly by the ELF64 driver.

_________________
Glidix: An x86_64 POSIX-compliant operating system, aiming to be as optimized as possible, especially in graphics.
https://glidix.madd-games.org/


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 5 posts ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: No registered users and 5 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group