Mailing List Archive

Gentoo Hardened and Stack Clash
Executive summary

With Gentoo Hardened no ebuilds compiled with a hardened toolchain with
version 4.8 or higher should be affected by this issue as
-fstack-check=specific is enabled by default. The only known exceptions
are media-video/vlc and (on HPPA) dev-lang/tcl wich disable this feature.


Introduction

The Gentoo Hardened team has been made aware of a set of vulnerabilities
known as Stack Clash.

These vulnerabilities involve the process stack pointer jumping onto
other memory regions allowing the attacker to either modify the contents
of the stack itself or the memory region on which the stack overflows.
As a result, an attacker may be able to modify the data of affected
programs or their execution flow and trigger the execution of arbitrary
code.

The existence of such issues has been known since at least 2005 when
Gael Delalleau presented an example of such an issue affecting mod_php
in apache.


Requirements to perform the attack

* The attacker needs to be able to move the stack pointer onto an
adjacent memory region.
* The attacker needs to ensure this happens without accessing the gap
between the stack and the next region.
* The attacker needs to be able overwrite the area where the stack
overlaps with the other section in a meaningful way. For example,
overwriting the return address of a function to take control of the
execution flow.


Effect of Gentoo Hardened protections

As a way to make exploitation of such issues harder vanilla Linux
kernels introduced a 4kiB gap between the stack and the other regions
called guard page, on PaX based kernels like hardened-sources the size
of this gap defaults at 64kiB and can be modified using
/proc/sys/vm/heap_stack_gap. As shown by Qualys' advisory, such gap
isn't large enough for all allocations and can be jumped over in some cases.

It should be taken into account that this measure was never meant as a
final solution as this problem can only be addressed correctly during
code generation. Therefore, increasing the size of this gap will not
deter all exploitation attempts as large enough allocations may still be
able to jump over the gap. It will though affect the processes running
on the system and limit the amount of virtual memory space available to
them. Although this might not be a problem on 64 bit architectures where
the virtual memory space is quite large, on 32 bit architectures this
may still be problematic and should be taken into account before using a
large heap_stack_gap value.

The Gentoo Hardened toolchain also makes use of gcc's Stack Checking
feature using -fstack-check=specific since gcc 4.8. This makes gcc add
stack probing code when large allocations are made ensuring that the
guard page or the stack gap are accessed and preventing the attack by
killing the process.

To be fully effective -fstack-check=specific requires that all the
source files used by the process have been compiled making use of this
feature. This is because gcc may optimize away some of the checks that
are considered redundant.

An assesment over the portage tree hints that only two ebuilds disable
this feature. The ebuild for media-video/vlc disables it on all packages
to address Gentoo bug #499996. On the other hand, the ebuild for
dev-lang/tcl disables this feature on HPPA builds to address Gentoo bug
#280934.

It is possible to check the version of the compiler used on a specific
ELF binary by checking the value of the .comment section as long as it
was not stripped. For this the command "$ readelf -p .comment binary"
can be used, for example to check /usr/bin/whoami run "$ readelf -p
.comment /usr/bin/whoami". Users of the split-debug portage feature
should instead check on /usr/lib/debug/. For example the prior example
for /usr/bin/whoami would be "$ readelf -p .comment
/usr/lib/debug/usr/bin/whoami.debug".

Prior versions of the toolchain make use of -fstack-protector-all which,
although not preventing the issue, will make it harder for an attacker
to take control of the execution flow of the program as depending on how
the attack is performed the attacker may need to find out the value of
the canary in the stack.

In this case caution is advised because the amount of ebuilds disabling
SSP is much larger and, shall the frame of any function provided by the
binaries generated using these ebuilds end up on the overflowed into
memory section, the attacker will be able to overwrite
their return pointer.

Most of the binaries in Gentoo Hardened are also compiled as PIE
binaries, this allows using ASLR which both vanilla and PaX kernels
provide with the second being noticeably stronger. This will make it
harder for an attacker to figure out a valid address on which to return.

Additionally PaX can prevent RWX mappings including the stack itself,
this makes it more difficult for the attacker to introduce new code
forcing him to use executable code already present on the process at the
time of the attack. Keep in mind though that most programs making use of
JIT compilers will have this feature disabled.

Finally, hardened-sources allows enabling "Deter exploit bruteforcing".
This feature limits the number of attack attempts per second that can be
made against SUID binaries making exploitation noticeably harder.

As a result, on hardened-sources the increased entropy provided by ASLR
will require a large number of attack attempts before succeeding at
taking control of the program realiably. This, along with the slowdown
introduced by ''Deter exploit bruteforcing'', will make the attack
require a huge amount of time to succeed. Because of this, such attacks
will be unfeasible in the majority of situations.

Conclusion

With the exception of exploits able to make use of media-video/vlc to
jump over the thread gap and (on HPPA systems) dev-lang/tcl any users of
Gentoo Hardened who have recompiled their user spaces using gcc 4.8 or
higher are protected against such issues.

Users of prior versions of gcc have also partial protection against some
of the exploits thanks to ASLR, PIE, "Deter exploit bruteforcing" and
even SSP although they should reconsider rebuilding their userspace with
a more modern version of the hardened toolchain.


Further reading reading and sources

* The advisory by Qualys:
https://www.qualys.com/2017/06/19/stack-clash/stack-clash.txt
* Jeff Law on -fstack-check needing full coverage to be effective:
https://gcc.gnu.org/ml/gcc-patches/2017-06/msg01343.html
* Grsecurity's project comments on the issue:
https://grsecurity.net/an_ancient_kernel_hole_is_not_closed.php
* Gentoo's bug regarding CVE-2017-1000377:
https://bugs.gentoo.org/show_bug.cgi?id=CVE-2017-1000377
* GCC's Stack Checking:
https://gcc.gnu.org/onlinedocs/gccint/Stack-Checking.html
* Gentoo bug regarding stack checking being disabled on VLC:
https://bugs.gentoo.org/show_bug.cgi?id=499996
* Gentoo bug regarding stack checking being disabled on tcl:
https://bugs.gentoo.org/show_bug.cgi?id=280934

Thanks

The Gentoo Hardened team would like to thank the PaX Team for its
outstanding work and its support whilst writting this statement.

We'd also like to thank Zorry for his hard work introducing
-fstack-check=specific on the toolchain.

The latest version of this statement can be found on
https://wiki.gentoo.org/wiki/Hardened/Gentoo_Hardened_and_Stack_Clash
Re: Gentoo Hardened and Stack Clash [ In reply to ]
Hi,

I'm not claiming that I understand all the issues, but I wonder how
that all affects "normal" Gentoo.

Let me summarize my understanding:
* We currently enable -fstack-check=specific on hardened, but not on
normal Gentoo.
* -fstack-check provides protection against stack clashes, but it is
not ideal / can sometimes be circumvented. However it is expected /
hoped that future versions of gcc will improve on that and provide a
better implementation.
* According to gcc's man page I understand that -fstack-check=specific
is equivalent to -fstack-check and there is also
-fstack-check=generic, which is considered deprecated.

There's already work underway to push -pie via a new profile to default
gentoo. I wonder: Should -fstack-check be pushed as well?

Open questions I have:
* Are there measurements of the performance overhead of -fstack-check?
* Are there other downsides of -fstack-check? Is it expected that
enabling it breaks things?

--
Hanno Böck
https://hboeck.de/

mail/jabber: hanno@hboeck.de
GPG: FE73757FA60E4E21B937579FA5880072BBB51E42