The Linux Foundation Projects
Skip to main content
Blog

Stack-Clash security checker for RISC-V

By July 17, 2024July 19th, 2024No Comments

by Alexey Merzlyakov, Samsung Research

Introduction

Security – is a very important factor of everyday computing. Vulnerabilities are becoming increasingly common in today’s digital world, propagating significant threats to organizations or individual users who adopt the given software. One of these threats – is a stack-clash vulnerability, which might allow a potential attacker to remotely execute any code on your platform with root privileges. That is why it is very crucial to find any probable place in the final software product where this vulnerability could arise.

Background

To understand how we could detect the stack-clash vulnerability, it is necessary to dive a little
deeper into what it is. Initially, this security threat was found and described in a blog published by Qurlys. The idea behind this vulnerability is that each running program uses the stack – a memory region where the operating system typically stores local variables and register states during function calls. The size increase of the stack could lead to an overlap with other memory regions where an application stores its data. This overlapping is called the stack-clash and illustrated in Fig. 1.

Fig. 1. Stack-clash.

The stack-clash could trigger unexpected and abnormal program operation, leading to several flaws and allowing attackers to potentially execute arbitrary codes with elevated privileges. The list of reported exploits includes the following items:

CVEs Description Affected platforms
CVE-2017-1000366 + CVE-2017-1000379 Glibc contains a vulnerability that allows specially crafted LD_LIBRARY_PATH values to manipulate the heap/stack, causing them to alias, potentially resulting in arbitrary code execution. Debian/Ubuntu/Fedora/CentOS on amd64
CVE-2017-1000369 + CVE-2017-1000376 Exim message transfer agent supports the use of multiple “-p” command line arguments which are malloc()‘ed and never free()‘ed, used in conjunction with other issues allows attackers to cause arbitrary code execution. Debian on i386
CVE-2017-1000367 Sudo is vulnerable to an input validation (embedded spaces) in the get_process_ttyname() function resulting in information disclosure and command execution. Any SELinux-enabled distribution
CVE-2017-1085 An application which calls setrlimit() may turn a read-only memory region below the stack into a read-write region. A specially crafted executable could be exploited to execute arbitrary code in the user context. FreeBSD

and much more…

That is why controlling the increase of stack size is crucial for security. This handling is done by a compiler. For example, in GCC, this vulnerability is addressed by adding stack-clash protection option, introduced by Jeff Law.

However, it might be not enough when uncontrollable changes to the stack size in programs, such as examples mentioned earlier, are being handled on compiler-level only. Consequently, it is good to have a means to check the stack-clash independently from the compiler. This should be done at the final produced binaries (executables, static or dynamic libraries). It can be used to find the places potentially containing stack-clash vulnerability for any external security check-ups. The found places are also could be used to verify the effectiveness of the stack-clash protection option in the compiler. Let’s discuss the approach of such an independent binary analysis tool for finding potential vulnerable places.

Binary decomposition

Currently, there is an open source package that can analyze binaries, called Annobin. A part of Annobin, Annocheck – is the tool providing the necessary ecosystem for analyzing executables, libraries, and even RPM packages. It decomposes the binaries into separate sections and then into disassembled machine code instructions, as shown in Fig. 2. We will use these instructions for analysis in the new module – Stack-Clash checker:

Fig. 2. Overall approach scheme.

Stack-Clash checker

Stack-Clash checker is a module built as a plugin for Annocheck. It fully utilizes Annocheck’s ecosystem to conduct the necessary analysis. The working principle of the Stack-Clash checker is straightforward: to find the potential places where the stack size is growing more than 4 KB (one page) at a time, and report these instructions as potentially dangerous vulnerabilities.

Initially, the Stack-Clash checker was supported for x86/64 architecture where the given source code has a simple search using a string pattern to find stack pointer change instructions. As a member of RISE open source initiative, Samsung Research has proposed the Stack-Clash checker for RISC-V architecture by adding a “smarter” binary code analyzing concept on top of the existing mechanism above. 

In the proposed Stack-Clash checker, the binary analysis consists of two steps: (1) parsing of disassembled code into RISC-V instructions, and (2) simulation of these instructions to obtain the stack pointer growth value.

As the first step, the parser takes the disassembled strings from the Annocheck and then detects assembler instructions with their operands (registers or numbers) from the strings, as illustrated in Fig. 3:

Fig. 3. Assembler instruction parsing.

Then, the simulator tries to calculate the value of the stack pointer change (when possible) by simulating integer computational assembler instructions on linear parts of the code as illustrated in Fig. 4. Please note that the stack pointer grows backward, so its size increase will come with a negative sign.

Fig. 4. Instructions simulation.

If the stack size increase is higher than 4KB one-page size, the Stack-Clash checker reports this place as having a potential vulnerability back to the developer.

Conclusion

The Stack-Clash checker helps find places in the code of potential risks on stack-clash vulnerabilities and supports verifying GCC/LLVM compilers with enabled stack-clash protection options. It can be applied to executables, libraries, RPM packages, or entire OS distribution file systems.

Here comes a good news for you. The Stack-Clash checker for RISC-V has been contributed to the Annobin open source project, and now you can get it from the stack-clash-scanner-branch. It can be easily configured and built within Annobin, as described in the official documentation pages. You can simply use it as an Annocheck tool by calling the following command:

$ riscv-stack-clash-scanner --enable-stack-clash <binary_or_directory>

Have a luck in vulnerabilities finding!

Merzlyakov Alexey, May 2024
Samsung Research