[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Bug ld/31795] ld.bfd makes ELFs of type ET_EXEC for static PIEs when lo
From: |
mintsuki at protonmail dot com |
Subject: |
[Bug ld/31795] ld.bfd makes ELFs of type ET_EXEC for static PIEs when load address is non-0 |
Date: |
Tue, 28 May 2024 16:22:24 +0000 |
https://sourceware.org/bugzilla/show_bug.cgi?id=31795
--- Comment #59 from mintsuki <mintsuki at protonmail dot com> ---
(In reply to Adhemerval Zanella from comment #58)
> (In reply to mintsuki from comment #41)
> > (In reply to Adhemerval Zanella from comment #39)
> > > (In reply to Fangrui Song from comment #37)
> > > > I agree with mintsuki . The "-pie -Ttext-segment=non-zero => ET_EXEC"
> > > > hack
> > > > should not be needed.
> > > >
> > > > From https://sourceware.org/pipermail/binutils/2013-December/083381.html
> > > >
> > > > > Linker sets e_type in ELF header to ET_DYN for -pie
> > > > > -Ttext-segment=0xXXX.
> > > > > When I added -Ttext-segment=0xXXX, one goal was to load
> > > > > small model executable above 4GB on Linux/x86-64, which
> > > > > was done with -pie -Ttext-segment=0xXXX. But -pie sets
> > > > > e_type in ELF header to ET_DYN and kernel may ignore
> > > > > p_vaddr in ELF header to load ET_DYN binary at a random
> > > > > address. This patch changes ld to set e_type in ELF header
> > > > > to ET_EXEC if the first PT_LOAD segment has non-zero
> > > > > p_vaddr. If this is unacceptable as generic ELF change,
> > > > > I can make it specific to x86.
> > > >
> > > > Was the intention for the following command to load the text segment at
> > > > an
> > > > address >= 0x600000000000 ?
> > > >
> > > > ```
> > > > % cat a.c
> > > > #include <stdio.h>
> > > > int main() { printf("%p\n", main); }
> > > > % gcc -pie -Wl,-no-pie a.c -fuse-ld=bfd
> > > > -Wl,--no-relax,-Ttext-segment=0x600000000000 -o a
> > > > % ./a
> > > > 0x600000001139
> > > > % ./a
> > > > 0x600000001139 # no ASLR
> > > > ```
> > > >
> > > > Changing ET_DYN to ET_EXEC fulfills the address requirement but disables
> > > > ASLR.
> > > > Is it intentional?
> > >
> > > That's my understanding of reading the -Ttext-segment documentation. The
> > > question is whether we relax the semantic to have it as a minimum address
> > > or
> > > define it as the expected address (thus disabling ASLR as a consequence).
> >
> > My understanding is that the PT_LOAD PHDR addresses could be slid, as long
> > as they are slid above the specified address. The fact that the first
> > PT_LOAD PHDR is 0 or not should be irrelevant. It makes no sense for it to
> > be relevant, let alone for it to dictate the ELF type to be ET_EXEC.
> >
> > This is how Limine behaves, and how I interpret the ELF format.
>
> Unfortunately, this is not what binutils documentation states ("When
> creating an ELF executable, it will set the address of the first byte of the
> text segment") nor how Linux handles it (where ET_DYN does not enforce
> e_entry).
>
> And it seems to be a Linux-specific issue, since on FreeBSD:
>
> $ cc -pie a.c -fuse-ld=lld -Wl,--no-relax,--image-base=0x600000000000
> -Wl,-z,notext -o a-lld
> $ readelf -h a-lld
> ELF Header:
> Magic: 7f 45 4c 46 02 01 01 09 00 00 00 00 00 00 00 00
> Class: ELF64
> Data: 2's complement, little endian
> Version: 1 (current)
> OS/ABI: FreeBSD
> ABI Version: 0
> Type: DYN (Shared object file)
> Machine: Advanced Micro Devices x86-64
> Version: 0x1
> Entry point address: 0x6000000016b0
> Start of program headers: 64 (bytes into file)
> Start of section headers: 12928 (bytes into file)
> Flags: 0
> Size of this header: 64 (bytes)
> Size of program headers: 56 (bytes)
> Number of program headers: 11
> Size of section headers: 64 (bytes)
> Number of section headers: 39
> Section header string table index: 37
> $ readelf -d a-lld | grep -w FLAGS_1
> 0x000000006ffffffb FLAGS_1 PIE
> $ doas sysctl -w kern.elf64.aslr.pie_enable=1
> kern.elf64.aslr.pie_enable: 0 -> 1
> $ ./a-lld
> 0x6000000019d0
> $ ./a-lld
> 0x6000000019d0
>
> So maybe we either enable this iff targeting Linux, or check if kernel is
> willing to enforce e_entry even for DYN.
>
> I am not sure if the correct approach is relaxing the
> '-Ttext-segment/--image-base' to be a minimum address. For this, I would
> add another linker option.
I am not sure what you mean with "willing to enforce e_entry".
In any case, how about checking what the generated ELF file's OS/ABI is and
only doing the DYN->EXEC hack if it happens to be GNU/Linux?
--
You are receiving this mail because:
You are on the CC list for the bug.
- [Bug ld/31795] ld.bfd makes ELFs of type ET_EXEC for static PIEs when load address is non-0, (continued)
- [Bug ld/31795] ld.bfd makes ELFs of type ET_EXEC for static PIEs when load address is non-0, mintsuki at protonmail dot com, 2024/05/28
- [Bug ld/31795] ld.bfd makes ELFs of type ET_EXEC for static PIEs when load address is non-0, hjl.tools at gmail dot com, 2024/05/28
- [Bug ld/31795] ld.bfd makes ELFs of type ET_EXEC for static PIEs when load address is non-0, hjl.tools at gmail dot com, 2024/05/28
- [Bug ld/31795] ld.bfd makes ELFs of type ET_EXEC for static PIEs when load address is non-0, mintsuki at protonmail dot com, 2024/05/28
- [Bug ld/31795] ld.bfd makes ELFs of type ET_EXEC for static PIEs when load address is non-0, mintsuki at protonmail dot com, 2024/05/28
- [Bug ld/31795] ld.bfd makes ELFs of type ET_EXEC for static PIEs when load address is non-0, hjl.tools at gmail dot com, 2024/05/28
- [Bug ld/31795] ld.bfd makes ELFs of type ET_EXEC for static PIEs when load address is non-0, mintsuki at protonmail dot com, 2024/05/28
- [Bug ld/31795] ld.bfd makes ELFs of type ET_EXEC for static PIEs when load address is non-0, hjl.tools at gmail dot com, 2024/05/28
- [Bug ld/31795] ld.bfd makes ELFs of type ET_EXEC for static PIEs when load address is non-0, mintsuki at protonmail dot com, 2024/05/28
- [Bug ld/31795] ld.bfd makes ELFs of type ET_EXEC for static PIEs when load address is non-0, adhemerval.zanella at linaro dot org, 2024/05/28
- [Bug ld/31795] ld.bfd makes ELFs of type ET_EXEC for static PIEs when load address is non-0,
mintsuki at protonmail dot com <=
- [Bug ld/31795] ld.bfd makes ELFs of type ET_EXEC for static PIEs when load address is non-0, adhemerval.zanella at linaro dot org, 2024/05/28
- [Bug ld/31795] ld.bfd makes ELFs of type ET_EXEC for static PIEs when load address is non-0, mintsuki at protonmail dot com, 2024/05/28
- [Bug ld/31795] ld.bfd makes ELFs of type ET_EXEC for static PIEs when load address is non-0, mintsuki at protonmail dot com, 2024/05/28
- [Bug ld/31795] ld.bfd makes ELFs of type ET_EXEC for static PIEs when load address is non-0, adhemerval.zanella at linaro dot org, 2024/05/28
- [Bug ld/31795] ld.bfd makes ELFs of type ET_EXEC for static PIEs when load address is non-0, mintsuki at protonmail dot com, 2024/05/28
- [Bug ld/31795] ld.bfd makes ELFs of type ET_EXEC for static PIEs when load address is non-0, i at maskray dot me, 2024/05/28
- [Bug ld/31795] ld.bfd makes ELFs of type ET_EXEC for static PIEs when load address is non-0, mintsuki at protonmail dot com, 2024/05/29
- [Bug ld/31795] ld.bfd makes ELFs of type ET_EXEC for PIEs when load address is non-0, mintsuki at protonmail dot com, 2024/05/29