GNU IFUNC is the real culprit behind CVE-2024-3094

· security · Source ↗

The xz-utils backdoor succeeded not just because of supply-chain manipulation, but because GNU IFUNC let malicious library code run before main() inside sshd’s address space.

What Matters

  • Debian/Fedora patched OpenSSH to depend on libsystemd to fix a race condition; Portable OpenSSH explicitly refused that dependency.
  • libsystemd pulls in xz-utils; xz-utils used GNU IFUNC — so attacker code ran inside sshd before main(), bypassing RELRO.
  • IFUNC lets a resolver function run arbitrary code while the Global Offset Table is still writable, defeating RELRO’s core guarantee.
  • Rich Felker (musl maintainer): “Ifunc is just an utterly dumb way to do runtime microarch specific code selection.”
  • Apple’s analogous Mach-O feature .symbol_resolver is similarly regretted by Apple’s own engineers.
  • Safer alternatives exist: global function pointers hardened with mprotect(2), LD_PRELOAD dispatch scripts, or per-feature-set binaries — all more portable than IFUNC.
  • [HN: @phire] IFUNC wasn’t required; once attacker code is in any linked library, it could patch sshd on disk or via debug APIs regardless.
  • [HN: @AshamedCaptain] Calling IFUNC “the real culprit” overstates it — a plain C++ constructor or init function achieves nearly identical pre-main execution.

Original | Discuss on HN