[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:25:53 +0000 |
https://sourceware.org/bugzilla/show_bug.cgi?id=31795
--- Comment #61 from mintsuki <mintsuki at protonmail dot com> ---
(In reply to mintsuki from comment #59)
> (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?
Actually I don't think that may be possible, at least not by checking the
OS/ABI field alone, given on my Linux host it seems to be a generic UNIX -
System V value...
--
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, 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, 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, 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