Linux ELF binaries store a flag to indicate whether they want their stack to be executable or not. The Linux loader will check that flag and adjust appropriately the stack via an mprotect system call. But who decides about setting or resetting this flag when generating a binary? The answer is the linker. The linker checks all object files and decides based on them if it should make the stack executable or not.
The decision is based on the following algorithm:
- If one of the object files does not contain a section named .note.GNU-stack, then the stack of the generated ELF binary will be executable to maintain backward compatibility.
- If one of the object files contains a section named .note.GNU-stack which is marked as containing code, then the stack will be marked as executable.
- Otherwise (if all object files contain a section named .note.GNU-stack which is marked as not containing code) the stack will be marked as non executable.