|
|
Subscribe / Log in / New account

GNU C Library 2.39 released

GNU C Library 2.39 released

Posted Feb 2, 2024 16:14 UTC (Fri) by alkbyby (subscriber, #61687)
Parent article: GNU C Library 2.39 released

This from release notes

>> When enabled with non-lazy binding, the dynamic linker will rewrite indirect branches in PLT with direct branches.

looks extremely cool. Some programs will see a detectable performance win. Question: why it is tunable and apparently off by default? Anyone knows ?


to post comments

GNU C Library 2.39 released

Posted Feb 2, 2024 16:29 UTC (Fri) by farnz (subscriber, #17727) [Link] (2 responses)

For this to function, the PLT must be mapped as writeable, and then later mapped as executable. In some environments (both SELinux and systemd have tunables of their own to enforce this on processes), once a page has been mapped as writeable, it cannot later be mapped as executable.

And it's only a benefit for legacy binaries; if you have source code, you can recompile with -fno-plt to get the same benefit statically instead of via dynamic linking shenanigans.

GNU C Library 2.39 released

Posted Feb 3, 2024 17:52 UTC (Sat) by alkbyby (subscriber, #61687) [Link] (1 responses)

Interesting.

-fno-plt while it removes jumps to plt, it still leaves indirect calls via GOT. Those indirect jumps aren't very cheap.

What this new feature seems to be about is it'll rewrite indirect via-got jumps in plt to regular "static" jumps. And yes, as it notes explicitly, it requires eager binding (so ld.so will rewrite entire .plt then mprotect it exec-only). So, yes, it still leaves extra jump, but those extra jumps are cheaper jumps.

And so I am curious why not just always do it whenever binary or environment variable asks for eager binding. My understanding is that some fairly common distros seems to be defaulting to -Wl,-z,now (eagering binding).

Also, I'd be curious to see if anyone has numbers about performance impact of this (and also versus -fno-plt).

I wasn't aware of security features that forbid to mprotect something from writeble to executable (btw, any pointers? I've heard write^exec, but not write -> never-exec you're seemingly referring to). Still, it should be possible to deal with it. E.g. you can rewrite entire plt to fresh memfd file and mmap it exec-only over original plt location. But even if not like this, it could try to do .plt rewriting, observe failure and fall back to original approach. And still get likely significant win in most common cases.

GNU C Library 2.39 released

Posted Feb 5, 2024 10:33 UTC (Mon) by farnz (subscriber, #17727) [Link]

-fno-plt can also remove indirect calls via GOT in the same cases where this new feature can remove indirect calls via the GOT; there are PLT calls that don't go via the GOT, and PLT calls that do (to support symbol interposition, IIRC). But if you build with -fno-plt and -Wl,-z,-now, both the GOT and PLT indirections will be removed.

See systemd's MemoryDenyWriteExecute setting as an example of a security feature that prevents you calling mprotect with PROT_EXEC set, or mmap with both PROT_EXEC and PROT_WRITE set; this effectively makes it impossible to write to a block of memory and then make it executable, since you can neither map a new region writeable + executable, nor can you ever change a region to executable via mprotect

GNU C Library 2.39 released

Posted Feb 4, 2024 22:07 UTC (Sun) by judas_iscariote (guest, #47386) [Link]

Because execmem and because it will break fragile debugging tools that depend on PLT calls to track things.


Copyright © 2025, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds