https://gcc.gnu.org/bugzilla/show_bug.cgi?id=128282
Bug ID: 128282
Summary: cfgexpand: expand_stack_vars omits ASan redzone and
shadow poisoning for over-aligned fixed-size locals
Product: gcc
Version: 16.2.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: sanitizer
Assignee: unassigned at gcc dot gnu.org
Reporter: 220245569 at seu dot edu.cn
CC: 220255623 at seu dot edu.cn, dodji at gcc dot gnu.org,
dvyukov at gcc dot gnu.org, jakub at gcc dot gnu.org,
jianhao.xu at seu dot edu.cn, kcc at gcc dot gnu.org
Target Milestone: ---
Target: aarch64-*-*, riscv64-*-*, loongarch64-*-*
Summary
-------
Under `-fsanitize=address`, fixed-size local variables whose alignment exceeds
`MAX_SUPPORTED_STACK_ALIGNMENT` (16 bytes on AArch64, RISC-V, and LoongArch)
receive no ASan redzone padding and no shadow-memory poisoning.
In `gcc/cfgexpand.cc:1525-1648` (`expand_stack_vars`), when
`alignb * BITS_PER_UNIT > MAX_SUPPORTED_STACK_ALIGNMENT`, the variable is
allocated via the `large_alloc` arm (`allocate_dynamic_stack_space`). While
HWASan explicitly hooks this arm (`hwasan_record_stack_var` at line 1626),
ASan has no hook in this branch: the variable is never pushed onto
`data->asan_vec` or `data->asan_decl_vec`.
Consequently, any local buffer declared with `alignas(32)` or
`__attribute__((aligned(64)))` on AArch64, RISC-V, or LoongArch has all of its
stack shadow bytes left at `0` (addressable), and stack buffer overflows out of
that buffer are silently missed at runtime.
Reproducer
----------
$ cat trigger.c
__attribute__((noinline)) void over_aligned(int i) {
volatile char buf[64] __attribute__((aligned(64)));
buf[i] = 0x41;
}
__attribute__((noinline)) void normal(int i) {
volatile char buf[64];
buf[i] = 0x41;
}
Compile flag: aarch64-linux-gnu-gcc -O1 -fsanitize=address -S trigger.c
$ cat trigger.s
over_aligned:
stp x29, x30, [sp, -16]!
mov x29, sp
sub sp, sp, #128
add x1, sp, 63
and x1, x1, -64 # dynamically aligned in frame, ZERO
shadow poisoning!
...
strb w2, [x1]
mov sp, x29
ldp x29, x30, [sp], 16
ret
normal:
...
mov w4, -235802127 # 0xf1f1f1f1 left redzone poisoned
mov w3, -202116109 # 0xf3f3f3f3 right redzone poisoned
Suggested Fix
-------------
Record over-aligned fixed-size locals for ASan redzone allocation and shadow
poisoning in the `alignb * BITS_PER_UNIT > MAX_SUPPORTED_STACK_ALIGNMENT` arm
of `expand_stack_vars` (`gcc/cfgexpand.cc:1602-1648`), mirroring
`hwasan_record_stack_var`.