[PATCH] powerpc: Restore NULL check on _rtld_global_ro in INIT_ARCH [BZ #34503]

Michael Pfeifroth micpf@westermo.com
Mon Aug 10 10:06:42 GMT 2026


Commit 21841f0d562f ("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.

Signed-off-by: Michael Pfeifroth <micpf@westermo.com>
---
 sysdeps/powerpc/powerpc32/power4/multiarch/init-arch.h | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/sysdeps/powerpc/powerpc32/power4/multiarch/init-arch.h b/sysdeps/powerpc/powerpc32/power4/multiarch/init-arch.h
index 9aab67a5..e681b452 100644
--- a/sysdeps/powerpc/powerpc32/power4/multiarch/init-arch.h
+++ b/sysdeps/powerpc/powerpc32/power4/multiarch/init-arch.h
@@ -36,9 +36,9 @@
 /* Get the hardware information post the tunables set, the macro checks
    it and fills the previous ones.  */
 #define INIT_ARCH() \
-  const struct cpu_features *features = &GLRO(dl_powerpc_cpu_features);    \
-  unsigned long int hwcap = features->hwcap;               \
-  unsigned long int __attribute__((unused)) hwcap2 = features->hwcap2; \
+  unsigned long int hwcap = __GLRO(dl_powerpc_cpu_features.hwcap); \
+  unsigned long int __attribute__((unused)) hwcap2 =           \
+    __GLRO(dl_powerpc_cpu_features.hwcap2);                \
   bool __attribute__((unused)) use_cached_memopt =     \
     __GLRO(dl_powerpc_cpu_features.use_cached_memopt);     \
   if (hwcap & PPC_FEATURE_ARCH_2_06)               \
--
2.34.1


More information about the Libc-alpha mailing list