Skip to content

Switch to -ftrampoline-impl=heap to avoid executable stacks which won't load with glibc >=2.41 #143

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
h-vetinari opened this issue Feb 10, 2025 · 1 comment

Comments

@h-vetinari
Copy link
Member

As described in conda-forge/pytorch-cpu-feedstock#350, glibc >=2.41 forbids loading libraries that have the NX-bit off. There are workarounds of course, but they are non-obvious, and as distros move to 2.41 (like the upcoming Ubuntu 25.04), more and more users will get hit by this.

Most (upstream) projects will just need to fix their asm to avoid this, but any users of GCC's nested function extensions will have a problem, because it uses a trampoline which turns off the NX-bit, see here.

Since GCC 14, it's possible to switch the trampoline implementation to the heap - and thus away from the (executable) stack -, so we should IMO switch to that by default (docs). That way, also projects that make use of nested functions will continue working for users on very new glibc.

The only downside is that this flag is only supported on linux-64 & linux-aarch64, not on linux-ppc64le. That's likely just a fact of life, unless & until GCC gains support for that flag on ppc at some point.

Related discussions (courtesy of @function2-llx):

@h-vetinari
Copy link
Member Author

Apparently, adding -Wl,-z,noexecstack to LDFLAGS should already be good enough, and then we don't need to rely on this being v14+ only

zatrazz added a commit to zatrazz/glibc that referenced this issue Apr 8, 2025
…Z 32653)

From the bug report [1], multiple programs still require to dlopen
shared libraries with either missing PT_GNU_STACK or with the executable
bit set.  Although, in some cases, it seems to be a hard-craft assembly
source without the required .note.GNU-stack marking (so the static linker
is forced to set the stack executable if the ABI requires it), other
cases seem that the library uses trampolines [2].

Unfortunately, READ_IMPLIES_EXEC is not an option since on some ABIs
(x86_64), the kernel clears the bit, making it unsupported.  To avoid
reinstating the broken code that changes stack permission on dlopen
(0ca8785), this patch extends the glibc.rtld.execstack tunable to
allow an option to force an executable stack at the program startup.

The tunable is a security issue because it defeats the PT_GNU_STACK
hardening.  It has the slight advantage of making it explicit by the
caller, and, as for other tunables, this is disabled for setuid binaries.
A tunable also allows us to eventually remove it, but from previous
experiences, it would require some time.

Checked on aarch64-linux-gnu, x86_64-linux-gnu, and i686-linux-gnu.

[1] https://sourceware.org/bugzilla/show_bug.cgi?id=32653
[2] conda-forge/ctng-compiler-activation-feedstock#143
Reviewed-by: Sam James <sam@gentoo.org>
kraj pushed a commit to kraj/glibc that referenced this issue Apr 8, 2025
…Z 32653)

From the bug report [1], multiple programs still require to dlopen
shared libraries with either missing PT_GNU_STACK or with the executable
bit set.  Although, in some cases, it seems to be a hard-craft assembly
source without the required .note.GNU-stack marking (so the static linker
is forced to set the stack executable if the ABI requires it), other
cases seem that the library uses trampolines [2].

Unfortunately, READ_IMPLIES_EXEC is not an option since on some ABIs
(x86_64), the kernel clears the bit, making it unsupported.  To avoid
reinstating the broken code that changes stack permission on dlopen
(0ca8785), this patch extends the glibc.rtld.execstack tunable to
allow an option to force an executable stack at the program startup.

The tunable is a security issue because it defeats the PT_GNU_STACK
hardening.  It has the slight advantage of making it explicit by the
caller, and, as for other tunables, this is disabled for setuid binaries.
A tunable also allows us to eventually remove it, but from previous
experiences, it would require some time.

Checked on aarch64-linux-gnu, x86_64-linux-gnu, and i686-linux-gnu.

[1] https://sourceware.org/bugzilla/show_bug.cgi?id=32653
[2] conda-forge/ctng-compiler-activation-feedstock#143
Reviewed-by: Sam James <sam@gentoo.org>
saagarjha pushed a commit to ahjragaas/glibc that referenced this issue Apr 9, 2025
…Z 32653)

From the bug report [1], multiple programs still require to dlopen
shared libraries with either missing PT_GNU_STACK or with the executable
bit set.  Although, in some cases, it seems to be a hard-craft assembly
source without the required .note.GNU-stack marking (so the static linker
is forced to set the stack executable if the ABI requires it), other
cases seem that the library uses trampolines [2].

Unfortunately, READ_IMPLIES_EXEC is not an option since on some ABIs
(x86_64), the kernel clears the bit, making it unsupported.  To avoid
reinstating the broken code that changes stack permission on dlopen
(0ca8785), this patch extends the glibc.rtld.execstack tunable to
allow an option to force an executable stack at the program startup.

The tunable is a security issue because it defeats the PT_GNU_STACK
hardening.  It has the slight advantage of making it explicit by the
caller, and, as for other tunables, this is disabled for setuid binaries.
A tunable also allows us to eventually remove it, but from previous
experiences, it would require some time.

Checked on aarch64-linux-gnu, x86_64-linux-gnu, and i686-linux-gnu.

[1] https://sourceware.org/bugzilla/show_bug.cgi?id=32653
[2] conda-forge/ctng-compiler-activation-feedstock#143
Reviewed-by: Sam James <sam@gentoo.org>

(cherry picked from commit 12a497c)
gentoo-bot pushed a commit to gentoo/glibc that referenced this issue May 5, 2025
…Z 32653)

From the bug report [1], multiple programs still require to dlopen
shared libraries with either missing PT_GNU_STACK or with the executable
bit set.  Although, in some cases, it seems to be a hard-craft assembly
source without the required .note.GNU-stack marking (so the static linker
is forced to set the stack executable if the ABI requires it), other
cases seem that the library uses trampolines [2].

Unfortunately, READ_IMPLIES_EXEC is not an option since on some ABIs
(x86_64), the kernel clears the bit, making it unsupported.  To avoid
reinstating the broken code that changes stack permission on dlopen
(0ca8785), this patch extends the glibc.rtld.execstack tunable to
allow an option to force an executable stack at the program startup.

The tunable is a security issue because it defeats the PT_GNU_STACK
hardening.  It has the slight advantage of making it explicit by the
caller, and, as for other tunables, this is disabled for setuid binaries.
A tunable also allows us to eventually remove it, but from previous
experiences, it would require some time.

Checked on aarch64-linux-gnu, x86_64-linux-gnu, and i686-linux-gnu.

[1] https://sourceware.org/bugzilla/show_bug.cgi?id=32653
[2] conda-forge/ctng-compiler-activation-feedstock#143
Reviewed-by: Sam James <sam@gentoo.org>

(cherry picked from commit 12a497c716f0a06be5946cabb8c3ec22a079771e)
(cherry picked from commit b861755a84eeccdd9183989ca71b3b1251c83a74)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant