https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81715
Bug ID: 81715 Summary: asan-stack=1 redzone allocation is too inflexible Product: gcc Version: 7.1.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: sanitizer Assignee: unassigned at gcc dot gnu.org Reporter: arnd at linaro dot org CC: dodji at gcc dot gnu.org, dvyukov at gcc dot gnu.org, jakub at gcc dot gnu.org, kcc at gcc dot gnu.org, marxin at gcc dot gnu.org Target Milestone: --- In the Linux kernel, we have several instances of code exceeding the permitted stack frame limit (usually 1kb or 2kb per function) when asan-stack=1 is used. A typical pattern is something like extern void f_multiple(unsigned char *arg, unsigned long count); static inline void f_single(unsigned char arg) { f_multiple(&arg, 1); } void g(void) { f_single(0); f_single(1); f_single(2); /* ... */ f_single(100); } gcc -Wall -c test.c -O2 -fsanitize=kernel-address --param asan-stack=1 -Wframe-larger-than=0 test.c: In function āgā: test.c:15:1: warning: the frame size of 288 bytes is larger than 0 bytes [-Wframe-larger-than=] Here, each call to f_single() allocates a new stack location for its argument, and adds a 32-byte redzone before and after each byte to catch out-of-bounds access on the pointer. In comparison, clang/llvm appears to to better in two ways here: 1. As of https://github.com/llvm-mirror/llvm/commit/daa1bf3b74054#diff-a6f91f41a097bdf01d36783f8bec4ed6R43, the redzone size is dynamically adapted to the object size, using only 16 bytes for variables up to four bytes, but also using much larger redzones for large stack objects. 2. In some cases, the stack for the temporary objects gets reused between calls, leading to the stack usage to no longer scale linearly with the number of calls to the inline helper. I have a workaround for the kernel that marks all inline functions as __attribute__((noinline)) when I found a code path that has an excessive stack usage with asan-stack using an affected gcc version (gcc-4.9 and higher, I have not tried versions higher than 7.1.1). It would be good to improve the stack frame allocation here in a future gcc release so we can turn off that workaround again in the kernel when using newer compilers.