-
-
Notifications
You must be signed in to change notification settings - Fork 14.6k
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
libressl: build libcrypto with noexecstack #66454
Conversation
For some reasons, libcrypto would be built with the executable stack flag set. I found out about this when Nginx failed to load the shared library, because I was running it with MemoryDenyWriteExecute=true, which does not permit executable stacks. I am not sure why the stack ends up executable; the other shared libraries which are part of LibreSSL do not have this flag set. You can verify this with 'execstack -q'. Non-executable stacks should be the default, and from checking some other files, that does appear to be the case. The LibreSSL sources do not contain the string "execstack", so I am not sure what causes the default to be overridden. Adding '-z noexecstack' to the linker flags makes the linker unset the flag. Now my Nginx can load the library, and so far I have not run into other issues.
The libcrypto in
The |
@GrahamcOfBorg build libressl |
This doesn't work on darwin:
|
Does Darwin have the concept of an executable stack, or should the flag it be omitted entirely there? Edit: also, the flag is called Edit 2: I've changed the flag for Darwin, could you check if this works @risicle? |
The flags to disable executable stacks are different for Clang and GCC, and Clang is used on Darwin.
I don't believe this is necessary on Darwin. There is a MH_ALLOW_STACK_EXECUTION flag but it is only valid on executables (via |
It is not needed on Darwin. [1] Thanks Matthew for explaining this. [1]: NixOS#66454 (comment)
Thanks for clarifying that, I've removed the flags entirely for Darwin. |
@GrahamcOfBorg build libressl |
FWIW, my best guess for the reason this happens is that there is some object file that the linker is bringing in which is, for some reason, NOT marked to include the section Some initial guesswork inside the source code didn't reveal anything on that note, unfortunately. Probably the best way to verify this theory is to simply run the (In the mean time I am tentatively approving these changes, since they seem to be correct anyway, and work around a clear deficiency.) |
Thanks for the elaborate reply, that clarifies a lot. Your suspicion is spot on, there are a number of List of those
The
Edit: while inspecting the
So perhaps we can get it working without |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good for now. Ideally we can find the root cause, but for now this change along with the comments are okay.
It turns out that libcrypto had an exectuable stack, because it linked some objects without a .note.GNU-stack section. Compilers add this section by default, but the objects produced from .S files did not contain it. The .S files do include a directive to add the section, but guarded behind an #ifdef HAVE_GNU_STACK. So define HAVE_GNU_STACK, to ensure that all objects have a .note.GNU-stack section.
I’ve added a new commit that uses |
@GrahamcOfBorg build libressl |
For some reason, libcrypto would be built with the executable stack flag set. I found out about this when Nginx failed to load the shared library, because I was running it with
MemoryDenyWriteExecute=true
which does not permit executable stacks.I am not sure why the stack ends up executable; the other shared libraries which are part of LibreSSL do not have this flag set. You can verify this with
execstack -q
. Non-executable stacks should be thedefault, and from checking some other files, that does appear to be the case. The LibreSSL sources do not contain the string "execstack", so I am not sure what causes the default to be overridden.
Adding
-z noexecstack
to the linker flags makes the linker unset the flag. Now my Nginx can load the library, and so far I have not run into other issues.I would like to understand where the shared stack requirement came from though. Without knowing where it originates from, it is hard to say what the impact of disabling it is. I did find these threads, which suggest that it is safe to use
noexecstack
:Motivation for this change
Nginx built against LibreSSL cannot use
MemoryDenyWriteExecute=true
at the moment, becauselibcrypto.so.45
requires an executable stack. This is a weird requirement, especially for a crypto library.Still, I would like to understand where the requirement came from before merging this.
Things done
sandbox
innix.conf
on non-NixOS)nix-shell -p nix-review --run "nix-review wip"
./result/bin/
). Also tested Nginx built against this LibreSSL.nix path-info -S
before and after)Notify maintainers
cc @thoughtpolice @fpletz @globin