Bug 479699 - Add support for stack-clash-protection on 32bit Arm
Summary: Add support for stack-clash-protection on 32bit Arm
Status: REPORTED
Alias: None
Product: valgrind
Classification: Developer tools
Component: memcheck (show other bugs)
Version: 3.20.0
Platform: Debian unstable Linux
: NOR normal
Target Milestone: ---
Assignee: Julian Seward
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2024-01-12 16:39 UTC by Emanuele Rocca
Modified: 2024-01-12 16:39 UTC (History)
0 users

See Also:
Latest Commit:
Version Fixed In:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Emanuele Rocca 2024-01-12 16:39:43 UTC
Hi,

The ARM Architecture Procedure Call Standard relaxed the limitations on memory
accesses below the stack pointer in 2018Q4:

| 6.2.1.3 Stack probing
| In order to ensure stack integrity a process may emit stack probes immediately
| prior to allocating additional stack space (moving SP from SP_old to SP_new).
| Stack probes must be in the region of [SP_new, SP_old - 1] and may be either
| read or write operations. The minimum interval for stack probing is defined by
| the target platform but must be a minimum of 4KBytes. No recoverable data can
| be saved below the currently allocated stack region.

See https://github.com/ARM-software/abi-aa/blob/2a70c42d62e9c3eb5887fa50b71257f20daca6f9/aapcs32/aapcs32.rst#6213stack-probing

Currently, valgrind considers all memory accesses below SP as errors, see for
example: https://lists.debian.org/debian-arm/2023/12/msg00002.html

GCC implements the AAPCS rules when using stack-clash protection, so please
consider updating valgrind accordingly.

Additionally, valgrind may segfault when debugging programs built
with stack-clash-protection turned on. For example:

 valgrind --track-origins=yes --leak-check=full apt-get update
 [...]
 ==3102620== Process terminating with default action of signal 11 (SIGSEGV)
 ==3102620==  Access not within mapped region at address 0xFEDCBDAC
 ==3102620==    at 0x49476E8: ReadMessages(int, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >&) (strutl.cc:888)

See https://people.debian.org/~ema/valgrind-segfault-apt-get-update.log for
full output.

Disassembled code at https://people.debian.org/~ema/apt-scp-armhf.log. The
memory location pointed at by r12 is out of the stack.

Another example of valgrind segfaulting when checking programs built with
stack-clash-protection on 32bit arm is at
https://bugzilla.redhat.com/show_bug.cgi?id=1522678