Hi, I found a small reproducer for the segmentation fault mentioned in https://bugs.kde.org/show_bug.cgi?id=479699. Please note that the error can be reproduced with either -fstack-clash-protection or -fstack-check. This issue is similar to https://bugs.kde.org/show_bug.cgi?id=479996 - but you need a larger buffer on 64 bit. // example.c void a_function() { char buf[8192]; } int main() { a_function(); } gcc -fstack-clash-protection example.c -o example && valgrind ./example ==2743356== Memcheck, a memory error detector ==2743356== Copyright (C) 2002-2022, and GNU GPL'd, by Julian Seward et al. ==2743356== Using Valgrind-3.20.0 and LibVEX; rerun with -h for copyright info ==2743356== Command: ./example ==2743356== ==2743356== ==2743356== Process terminating with default action of signal 11 (SIGSEGV) ==2743356== Access not within mapped region at address 0xFEF0CB04 ==2743356== at 0x1084EA: a_function (in /tmp/example) ==2743356== If you believe this happened as a result of a stack ==2743356== overflow in your program's main thread (unlikely but ==2743356== possible), you can try to increase the size of the ==2743356== main thread stack using the --main-stacksize= flag. ==2743356== The main thread stack size used in this run was 8388608. ==2743356== ==2743356== HEAP SUMMARY: ==2743356== in use at exit: 0 bytes in 0 blocks ==2743356== total heap usage: 0 allocs, 0 frees, 0 bytes allocated ==2743356== ==2743356== All heap blocks were freed -- no leaks are possible ==2743356== ==2743356== For lists of detected and suppressed errors, rerun with: -s ==2743356== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 3 from 3) Segmentation fault
This is issue is similar to https://bugs.kde.org/show_bug.cgi?id=479996 , where gcc does not really support arm32 -fstack-clash-support. Its own testsuite defines: gcc/testsuite/lib/target-supports.exp --- 12587 # Return 1 if the target has support for stack probing designed 12588 # to avoid stack-clash style attacks. 12589 # 12590 # This is used to restrict the stack-clash mitigation tests to 12591 # just those targets that have been explicitly supported. 12592 # 12593 # In addition to the prologue work on those targets, each target's 12594 # properties should be described in the functions below so that 12595 # tests do not become a mess of unreadable target conditions. 12596 # 12597 proc check_effective_target_supports_stack_clash_protection { } { 12598 12599 if { [istarget x86_64-*-*] || [istarget i?86-*-*] 12600 || [istarget powerpc*-*-*] || [istarget rs6000*-*-*] 12601 || [istarget aarch64*-**] || [istarget s390*-*-*] 12602 || [istarget loongarch64*-**] } { 12603 return 1 12604 } 12605 return 0 12606 } ---- Although the option does not throw any frontend error, gcc uses the -fstack-check support by just changing the probing size from 8192 to 4096. Using the provided example: With -fstack-check: --- [...] main: push {r7, lr} mov ip, #8192 sub ip, sp, ip str r0, [ip, #4088] add r7, sp, #0 bl a_function movs r3, #0 mov r0, r3 pop {r7, pc} --- And with '-fstack-clash-protection': --- main: push {r7, lr} mov ip, #4096 sub ip, sp, ip str r0, [ip, #4088] add r7, sp, #0 bl a_function movs r3, #0 mov r0, r3 pop {r7, pc} --- So the stack pointer is not really updated while doing the probing, which generates an invalid memory access by valgrind. So one option to fix would be to either adjust arm32 code generation to always update and rollback SP, as x86_64; or proper implement -fstack-clash-protection.