https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120950

            Bug ID: 120950
           Summary: Incorrect codegen for ASan when
                    -mpreferred-stack-boundary < 3
           Product: gcc
           Version: 15.1.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: sanitizer
          Assignee: unassigned at gcc dot gnu.org
          Reporter: yshuiv7 at gmail dot com
                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
  Target Milestone: ---

The generated ASan instrumentation always assume the stack pointer is aligned
to at least 8 bytes aligned, and shadow address calculation will be all wrong
if the stack is aligned to 4 bytes.

This is normally masked by the use of fake stacks, which because of how they
are allocated, has at least 64 bytes alignment. But this can be disabled with
ASAN_OPTIONS=detect_stack_use_after_return=0

Here is a repro:

#include <stdint.h>
struct T {
  uint16_t a;
  uint16_t b;
  uint32_t c;
};

int __attribute__((noinline)) g(struct T *__attribute__((unused)) value) {
  return 0;
}

int __attribute__((noinline)) f(int a) {
  struct T value = {a, a * 2, sizeof(a)};
  return g(&value);
}
int main() {
        volatile char pad[4]; // for me this pushes sp off 8 bytes alignment,
                              // but this can be tricky. maybe i can switch
                              // this to a little bit of inline assembly if
                              // this has trouble repro-ing
        f(10);
}

-- Build with:

i686-unknown-linux-gnu-gcc -mpreferred-stack-boundary=2 -fsanitize=address a.c 

-- Run with:

ASAN_OPTIONS=detect_stack_use_after_return=0 ./a.out

-- Expected behavior:

Program runs fine.

-- Actual behavior:

Initialization of `struct T value` trips ASan, and it calls
__asan_report_store4, which should not be called at all. Additionally, the
stack frame magic is stored at address misaligned with the shadow, so the asan
runtime can't find it and aborts.

-- Additional information:

Tried similar setup on clang. Looks like clang will always realign the stack
pointer to 32 bytes alignment in prologue.

Reply via email to