-
Notifications
You must be signed in to change notification settings - Fork 0
nacl_helper_bootstrap: associate .rodata with :text PHDR, fix build with GCC #6
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
|
That does seem like an ld bug based on the manual.
|
|
Building with GCC and Scons seems to work fine for me. Tests pass and the loaders work with Daemon. For example |
|
Add this file as #! /usr/bin/env bash
set -u -e
export LANGUAGE='C.UTF-8'
export LANG="${LANGUAGE}"
CC="${CC:-cc}"
PYTHON="${PYTHON:-python3}"
declare -a CCARGS
CCARGS+=(-static)
CCARGS+=(-D_FORTIFY_SOURCE=2)
CCARGS+=(-D_GNU_SOURCE=1)
CCARGS+=(-D_LARGEFILE64_SOURCE=1)
CCARGS+=(-D_POSIX_C_SOURCE=199506)
CCARGS+=(-D_XOPEN_SOURCE=600)
CCARGS+=(-U__STDC_HOSTED__)
CCARGS+=(-D__STDC_HOSTED__=1)
CCARGS+=(-D__STDC_LIMIT_MACROS=1)
CCARGS+=(-D__STDC_FORMAT_MACROS=1)
CCARGS+=(-I ../../../../include-hax)
CCARGS+=(-std=gnu99)
CCARGS+=(-fno-pic -fno-PIC)
CCARGS+=(-fno-pie -fno-PIE)
CCARGS+=(-fvisibility=hidden)
CCARGS+=(-fno-stack-protector)
CCARGS+=(-ffreestanding)
CCARGS+=(-Wno-builtin-macro-redefined)
CCARGS+=(--param ssp-buffer-size=4)
CCARGS+=(-Os)
CCARGS+=(-c)
CCARGS+=(-o nacl_bootstrap.c.o)
CCARGS+=(nacl_bootstrap.c)
declare -a BFDARGS
BFDARGS+=(--compiler "${CC}")
BFDARGS+=(-m 'elf_x86_64')
BFDARGS+=(--build-id)
BFDARGS+=(--static)
BFDARGS+=(-z 'max-page-size=0x1000')
BFDARGS+=(--defsym RESERVE_TOP='0x0')
BFDARGS+=(--script nacl_bootstrap.x)
BFDARGS+=(-o nacl_bootstrap_raw)
BFDARGS+=(nacl_bootstrap.c.o)
rm -f nacl_bootstrap.c.o nacl_bootstrap_raw nacl_helper_bootstrap
set -x
"${CC}" "${CCARGS[@]}" ${CFLAGS:-}
"${PYTHON}" ./ld_bfd.py "${BFDARGS[@]}"
"${PYTHON}" ./nacl_bootstrap_munge_phdr.py nacl_bootstrap_raw nacl_helper_bootstrapThen run it this way: CC=gcc ./build.sh && ./nacl_helper_bootstrapIf it still works, then you have a lucky environment. What scons does is hard to trace. The script is made to facilitate the removal or the adding of flags for testing them. |
|
What's the point of using this |
|
This is extracted from what scons does. |
|
I see, thanks. I confirm that it depends on the toolchain version and the result is the same with scons or your script. Broken with Arch Linux (binutils 2.45.1) but worked with 2.44 |
|
In fact it doesn't look to be that related to binutils:
On Debian it always work with GCC, whatever the binutils version. On Ubuntu it stops working with GCC 8 on Ubuntu 20.04 Focal, with GCC 7 it works on Focal, but it was working with GCC 8 on 18.04 Bionic… The patch always fixes the bug. |
4ba6efa to
e24dc95
Compare
|
The bug is triggered (at least on Arch Linux which I tested) when there is a The broken binary has a faulty PT_LOAD command that overwrites the text section with zeroes. Definitely seems like a bug with ld. What do you think of the approach in the |
Extracted from:
Disclosure: this 6-characters fix is the result of me toying with ChatGPT as I used that bug for an experiment:
The bug as I experienced it 8 months ago was that the
nacl_helper_bootstrapwas segfaulting when built with GCC, not when built with Clang. At the time I identified the bug I could build it with GCC up to GCC 12 in an old Debian chroot. On a more recent Ubuntu today, I could not build the bootstrap helper with any GCC version, including some as old as GCC 9.So out of curiosity I did some experiments with ChatGPT, submitting the results of my existing discoveries done in my previous debugging sessions, the description of how I built the tool and some dump of built executable metadata, and even an hexdump of the bogus binary itself. I kept secret the fact the old GCCs that were building properly the binary were running on an older system with older binaries in
PATH.ChatGPT suggested this fix, explaining that supposedly a
ld.bfdchange happened in binutils modifying the behavior, the explanation proposed was that the.rodatasection isn't assigned to any PHDR because the.rodatalayout has no PHDR tag, so with older binutils the.rodatawas implicitly attached to the previous PHDR, but that with newer binutils it wasn't, so the_startentry point would jump to unmapped memory and crash. This explanation is consistent with my observation where I noticed in debugger that it was crashing early on_start. The suggestion of a behavioral change due to a different environment (which I had not disclosed) and not in GCC is also consistent with my observation.It is suggested that the fact the code runs when built with Clang is fortuitous.
I verified that with this small change the bootstrap helper not only builds with GCC but also runs properly.