Case 49: Executable Stack (GNU_STACK RWX)¶
| Field | Value |
|---|---|
| Verdict | ๐ข COMPATIBLE |
| Category | Quality (Compatible) |
| Platforms | Linux |
| Flags | Bad practice |
Detected ChangeKinds |
โ |
| Source files | browse on GitHub |
Category: ELF / Security | Verdict: BAD PRACTICE
What this case is about¶
Both libraries export identical symbols with identical signatures. The
difference is in the PT_GNU_STACK program header: v1 has flags RWE
(read-write-execute), while v2 has RW (read-write, non-executable).
An executable stack is a security bad practice: it disables NX (No-eXecute) protection for the entire process, making stack-based buffer overflow exploits trivially exploitable.
How executable stacks sneak in¶
The most common cause is linking a single .o file compiled from assembly
that has .section .note.GNU-stack,"x",@progbits. The GNU linker takes the
union of all stack permissions โ if any input object requests an executable
stack, the entire shared library (and any process loading it) gets one.
This happens frequently with:
- Hand-written assembly without the proper .note.GNU-stack annotation
- Old assembly files generated by compilers that defaulted to executable stacks
- Third-party object files or static archives
What abicheck detects¶
EXECUTABLE_STACK: The library hasPT_GNU_STACKwith execute permission. This is classified as a security metadata issue. Because the actual symbols and types are identical, the functional ABI is compatible.
Overall verdict: COMPATIBLE (same ABI surface; executable stack is security concern).
How to reproduce¶
# Build bad version (with executable stack via linker flag)
gcc -shared -fPIC -g bad.c -o libbad.so -Wl,-z,execstack
# Build good version (non-executable stack)
gcc -shared -fPIC -g good.c -o libgood.so -Wl,-z,noexecstack
# Verify GNU_STACK flags
readelf -l libbad.so | grep -A1 GNU_STACK
# โ GNU_STACK 0x000000 ... RWE โ executable!
readelf -l libgood.so | grep -A1 GNU_STACK
# โ GNU_STACK 0x000000 ... RW โ correct
# Run abicheck
python3 -m abicheck.cli dump libbad.so -o /tmp/v1.json
python3 -m abicheck.cli dump libgood.so -o /tmp/v2.json
python3 -m abicheck.cli compare /tmp/v1.json /tmp/v2.json
# โ COMPATIBLE + EXECUTABLE_STACK warning
How to fix¶
Ensure all assembly files include a non-executable stack annotation:
Or use the linker flag to force a non-executable stack:
In CMake:
Real-world example¶
The Linux kernel, glibc, and all major distributions flag executable stack
as a security defect. Fedora and Debian both have policies requiring
-Wl,-z,noexecstack and lintian/rpmlint checks that reject packages with
executable stacks.
References¶
Source files¶
See also: Examples overview ยท All COMPATIBLE cases ยท Category: Quality (Compatible).