program headers: do not rely on DYNAMIC coming before GNU_RELRO
authorkn <kn@openbsd.org>
Tue, 25 May 2021 17:01:36 +0000 (17:01 +0000)
committerkn <kn@openbsd.org>
Tue, 25 May 2021 17:01:36 +0000 (17:01 +0000)
commitf9a87ca699b091bcf816a107ab66f59f69ee1bb1
treea1585d39f3a0558cf7c538f336547ae1bfa0bf7f
parent0f12b4ad02a9560d20e5483b630ababad182582b
program headers: do not rely on DYNAMIC coming before GNU_RELRO

Except for some specific cases (thanks guenther) ELF mandates nothing
but the file header be at a fixed location, hence ld.so(1) must not
assume any specific order for headers, segments, etc.

Looping over the program header table to parse segment headers,
_dl_boot() creates the executable object upon DYNAMIC and expects it to
be set upon GNU_RELRO, resulting in a NULL dereference iff that order is
reversed.

Store relocation bits in temporary variables and update the executable
object once all segment headers are parsed to lift this dependency.

Under __mips__ _dl_boot() later on uses the same temporary variable, so
move nothing but the declaration out of MI code so as to not alter the
MD code's logic/behaviour.

Found while porting patchelf(1) from NixOS.

OK guenther
libexec/ld.so/loader.c