GNU IFUNC is the real culprit behind CVE-2024-3094
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_resolveris similarly regretted by Apple’s own engineers. -
Safer alternatives exist: global function pointers hardened with
mprotect(2),LD_PRELOADdispatch 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
initfunction achieves nearly identical pre-main execution.