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.

Reply via email to