I recently updated my Linux kernel and was presented with the following cryptic error when trying to launch a not too old version of Code Composer Studio (CCS) by Texas Instruments:
/home/user/ti/ccs1271/ccs/eclipse/../ccs_base/common/bin/libMiniDump.so: cannot enable executable stack as shared object requires: Invalid argument
What’s going on here?
Much like files themselves, sections in an executable binary can be marked as readable, writeable, executable etc. In addtion to the program sections, the stack may be marked as executable, allowing this sort of thing:
void executeTheStack()
{
uint8_t array[64] {/* my code */};
void (*fn)() = (void (*)())array;
fn();
}
Allowing this is typically frowned upon from a security perspective and is not allowed by default in most operating systems. It’s a subset of the Data Execution Protection (DEP) feature.
In the CCS erorr, libMiniDump.so
is requesting stack execution, but is being denied. The “request” can be seen in the file’s program header:
$ readelf -l /home/user/ti/ccs1271/ccs/eclipse/../ccs_base/common/bin/libMiniDump.so
Elf file type is DYN (Shared object file)
Entry point 0xc910
There are 6 program headers, starting at offset 64
Program Headers:
Type Offset VirtAddr PhysAddr
FileSiz MemSiz Flags Align
LOAD 0x0000000000000000 0x0000000000000000 0x0000000000000000
0x0000000000070b60 0x0000000000070b60 R E 0x200000
LOAD 0x0000000000071480 0x0000000000271480 0x0000000000271480
0x0000000000002978 0x0000000000003a80 RW 0x200000
DYNAMIC 0x0000000000072be8 0x0000000000272be8 0x0000000000272be8
0x0000000000000270 0x0000000000000270 RW 0x8
GNU_EH_FRAME 0x0000000000062c58 0x0000000000062c58 0x0000000000062c58
0x0000000000001884 0x0000000000001884 R 0x4
GNU_STACK 0x0000000000000000 0x0000000000000000 0x0000000000000000
0x0000000000000000 0x0000000000000000 RWE 0x10
GNU_RELRO 0x0000000000071480 0x0000000000271480 0x0000000000271480
0x0000000000001b80 0x0000000000001b80 R 0x1
GNU_STACK
has an executable (E
) flag.
As to why the flag is set, it may have been linked with -z execstack
, or the compiler may have determined that it’s needed and added itself. Hopefully it’s the former and isn’t needed, becase we’re going to remove it.
Execstack
to the rescue
execstack
is a small program that views, sets and clears this bit:
execstack is a program which sets, clears, or queries executable stack flag of ELF binaries and shared libraries. Linux has in the past allowed execution of instructions on the stack and there are lots of binaries and shared libraries assuming this behaviour. Furthermore, GCC trampoline code for e.g. nested functions requires executable stack on many architectures. To avoid breaking binaries and shared libraries which need executable stack, ELF binaries and shared libraries now can be marked as requiring executable stack or not requiring it.
Linux man page for execstack
So we can install execstack
and clear the executable stack bit. execstack
is in the AUR for arch. Refer to your Linux distribution to details on where find it:
$ execstack -c /home/user/ti/ccs1271/ccs/eclipse/../ccs_base/common/bin/libMiniDump.so
$ readelf -l /home/user/ti/ccs1271/ccs/eclipse/../ccs_base/common/bin/libMiniDump.so
Elf file type is DYN (Shared object file)
Entry point 0xc910
There are 6 program headers, starting at offset 64
Program Headers:
Type Offset VirtAddr PhysAddr
FileSiz MemSiz Flags Align
LOAD 0x0000000000000000 0x0000000000000000 0x0000000000000000
0x0000000000070b60 0x0000000000070b60 R E 0x200000
LOAD 0x0000000000071480 0x0000000000271480 0x0000000000271480
0x0000000000002978 0x0000000000003a80 RW 0x200000
DYNAMIC 0x0000000000072be8 0x0000000000272be8 0x0000000000272be8
0x0000000000000270 0x0000000000000270 RW 0x8
GNU_EH_FRAME 0x0000000000062c58 0x0000000000062c58 0x0000000000062c58
0x0000000000001884 0x0000000000001884 R 0x4
GNU_STACK 0x0000000000000000 0x0000000000000000 0x0000000000000000
0x0000000000000000 0x0000000000000000 RW 0x10
GNU_RELRO 0x0000000000071480 0x0000000000271480 0x0000000000271480
0x0000000000001b80 0x0000000000001b80 R 0x1
This resolves the error, but…..did the library really require executable stack?
Let’s hope not 🤞🙏.