mirror of
git://sourceware.org/git/glibc.git
synced 2026-09-08 23:58:31 +08:00
Commit 21841f0d56 ("PowerPC: Influence cpu/arch hwcap features via
GLIBC_TUNABLES") changed the INIT_ARCH() macro used by powerpc32/power4
and (via a one-line include) powerpc64 multiarch IFUNC resolvers to
read hwcap and hwcap2 through a direct
&GLRO(dl_powerpc_cpu_features)
reference, instead of the previous __GLRO() wrapper. The __GLRO() macro
performs a volatile NULL check on _rtld_global_ro, which matters because
IFUNC resolvers can run before _rtld_global_ro has been relocated for the
current library.
This regression triggers when a shared library's IFUNC symbol from libm
is resolved via BIND_NOW (full RELRO) before libm's own GOT is relocated:
the resolver's INIT_ARCH() then dereferences a NULL _rtld_global_ro and
segfaults at the hwcap load. The concrete failure seen was rsyslogd
crashing on startup on powerpc64 (e5500, BE) with
rsyslogd -> librsyslog -> libfastjson -> modf() IFUNC in libm
when libfastjson lacked a DT_NEEDED on libm, so libm was relocated after
libfastjson's IFUNC resolvers ran.
Restore the __GLRO()-based access for both hwcap and hwcap2, matching
the pre-2.41 behaviour and how use_cached_memopt is already read in the
same macro. This is a no-op once _rtld_global_ro is fully initialised
and simply reinstates the early-startup NULL guard.
Add a regression test (ppc64 only; ppc32 has additional early-startup
constraints that make the same test infeasible there). The module is
linked with -z,now and intentionally has no DT_NEEDED on libm, so the
IFUNC resolver for modf() runs before libm is fully relocated.
Signed-off-by: Michael Pfeifroth <micpf@westermo.com>
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>