Stacks run even with `noexecstack`

I am trying to protect my application from buffer overflow exploits. Among other things, I use unused stacks and link my binaries with the noexecstack flag (passing -Wl,-z,noexecstack to gcc).

Everything seems fine - readelf confirms that PT_GNU_STACK indicates the correct permissions:

 $ readelf -l target | grep -A1 GNU_STACK GNU_STACK 0x0000000000000000 0x0000000000000000 0x0000000000000000 0x0000000000000000 0x0000000000000000 RW 10 

So execstack :

 $ execstack -q target - target 

There is only one problem. All my stacks are actually executable:

 root@170ubuntu16p04-64smp-1 :~# cat /proc/12878/task/*/maps | grep stack 7ffcac654000-7ffcac675000 rwxp 00000000 00:00 0 [stack] 7fe540e66000-7fe541666000 rwxp 00000000 00:00 0 [stack] 7fe540665000-7fe540e65000 rwxp 00000000 00:00 0 [stack] 7fe53b800000-7fe53c000000 rwxp 00000000 00:00 0 [stack] 

I grabbed allocate_stack and looked at the protection flags. In theory, they should be initialized according to PT_GNU_STACK . But in my case, it seems that PT_GNU_STACK was ignored, and _dl_stack_flags was initialized with default permissions.

Does anyone know what could cause this? Everything seems to be correct, but the stacks are still executing.

I am using gcc 4.8.3 / glibc 2.11.

+7
c gcc linux linker glibc
source share
2 answers

Olaf and a busy Russian pushed me in the right direction. A third-party shared object was poisoning my stacks.

But it was not directly related to my main executable. Both ldd and lddtree did not show libraries with RWE stacks, so I decided to go deeper and wrote a script that checked all the shared objects that are currently mapped to the process memory:

 #!/bin/bash if [ -z "$1" ]; then echo "Usage: $0 <target>" exit 1; fi kav_pid=`pidof $1` for so in `cat /proc/$kav_pid/task/*/maps | awk '/.so$/ {print $6}' | sort | uniq`; do stack_perms=`readelf -Wl $so | awk '/GNU_STACK/ {print $7}'` if [ -z "$stack_perms" ]; then echo "$so doesn't have PT_GNU_STACK" elif [ "$stack_perms" != "RW" ]; then echo "$so has unexpected permissions: $stack_perms" fi done 

And it worked! I found a library with RWE permissions:

 $ ./find_execstack.sh target /target/dir/lib64/lib3rdparty.so has unexpected permissions: RWE 

To make sure that it was this library that poisoned my stacks, I opened my application with gdb and set a breakpoint in dlopen . And bingo! Here are the permissions before dlopen ing lib3rdparty.so:

 7ffffffde000-7ffffffff000 rw-p 00000000 00:00 0 [stack] 

And here they are right after dlopen :

 7ffffffde000-7ffffffff000 rwxp 00000000 00:00 0 [stack] 

As it turned out, lib3rdparty.so was built using a different lib3rdparty.so and is now lib3rdparty.so .

Olaf, Russian, thanks!

0
source share

what could cause this?

In addition to the main PT_GNU_STACK executable file that has the correct permissions, you also need to have the PT_GNU_STACK with the correct permissions in each directly linked shared library.

If any of these libraries does not have PT_GNU_STACK at all or has one with executable permissions, it will β€œpoison” all your stacks with a resolvable permission.

So run

 for j in $(ldd target | grep -o '=> .* ' | sed -e 's/=> //' -e '/^ *$/d' ); do out=$(readelf -Wl $j | grep STACK) [[ -z "$out" ]] && echo "missing GNU_STACK in $j" echo $out | grep -q RWE && echo "executable GNU_STACK in $j" done 

and you will most likely see at least one library with a missing or executable stack.

PS I see that Olaf has already (partially) proposed this.

+1
source share

All Articles