https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88277
Bug ID: 88277 Summary: ASAN stack poisoning is using unaligned stores on e.g. x86_64 Product: gcc Version: 9.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: sanitizer Assignee: unassigned at gcc dot gnu.org Reporter: marxin at gcc dot gnu.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: --- Considering x86_64 and following example: $ cat asan.c void bar (void *a) { int *p = a; *(p-1) = 123; } int baz (void) { char e2[56]; bar (&e2[0]); return 0; } int *p; int main() { int a; p = &a; baz(); } I see: $ gcc asan.c -fsanitize=address && ASAN_OPTIONS=detect_stack_use_after_return=1 ./a.out ================================================================= ==21996==ERROR: AddressSanitizer: stack-buffer-underflow on address 0x7ffff2d0009c at pc 0x000000401195 bp 0x7fffffffda80 sp 0x7fffffffda78 WRITE of size 4 at 0x7ffff2d0009c thread T0 #0 0x401194 in bar (/home/marxin/Programming/testcases/a.out+0x401194) #1 0x401227 in baz (/home/marxin/Programming/testcases/a.out+0x401227) #2 0x401309 in main (/home/marxin/Programming/testcases/a.out+0x401309) #3 0x7ffff6c71fea in __libc_start_main ../csu/libc-start.c:308 #4 0x401099 in _start (/home/marxin/Programming/testcases/a.out+0x401099) Address 0x7ffff2d0009c is located in stack of thread T0 at offset 28 in frame #0 0x4011ad in baz (/home/marxin/Programming/testcases/a.out+0x4011ad) This frame has 1 object(s): [32, 88) 'e2' <== Memory access at offset 28 underflows this variable HINT: this may be a false positive if your program uses some custom stack unwind mechanism or swapcontext (longjmp and C++ exceptions *are* supported) SUMMARY: AddressSanitizer: stack-buffer-underflow (/home/marxin/Programming/testcases/a.out+0x401194) in bar Shadow bytes around the buggy address: 0x10007e597fc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x10007e597fd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x10007e597fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x10007e597ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x10007e598000: f1 f1 f1 f1 04 f2 f2 f2 f3 f3 f3 f3 00 00 00 00 =>0x10007e598010: f1 f1 f1[f1]00 00 00 00 00 00 00 f2 f3 f3 f3 f3 0x10007e598020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x10007e598030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x10007e598040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x10007e598050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x10007e598060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 This is fine starting f3 at 0x10007e598010 line is aligned to 32B. However: $ gcc asan.c -fsanitize=address && ASAN_OPTIONS=detect_stack_use_after_return=0 ./a.out ================================================================= ==22038==ERROR: AddressSanitizer: stack-buffer-underflow on address 0x7fffffffdadc at pc 0x000000401195 bp 0x7fffffffda80 sp 0x7fffffffda78 WRITE of size 4 at 0x7fffffffdadc thread T0 #0 0x401194 in bar (/home/marxin/Programming/testcases/a.out+0x401194) #1 0x401227 in baz (/home/marxin/Programming/testcases/a.out+0x401227) #2 0x401309 in main (/home/marxin/Programming/testcases/a.out+0x401309) #3 0x7ffff6c71fea in __libc_start_main ../csu/libc-start.c:308 #4 0x401099 in _start (/home/marxin/Programming/testcases/a.out+0x401099) Address 0x7fffffffdadc is located in stack of thread T0 at offset 28 in frame #0 0x4011ad in baz (/home/marxin/Programming/testcases/a.out+0x4011ad) This frame has 1 object(s): [32, 88) 'e2' <== Memory access at offset 28 underflows this variable HINT: this may be a false positive if your program uses some custom stack unwind mechanism or swapcontext (longjmp and C++ exceptions *are* supported) SUMMARY: AddressSanitizer: stack-buffer-underflow (/home/marxin/Programming/testcases/a.out+0x401194) in bar Shadow bytes around the buggy address: 0x10007fff7b00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x10007fff7b10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x10007fff7b20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x10007fff7b30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x10007fff7b40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 =>0x10007fff7b50: 00 00 00 00 00 00 00 00 f1 f1 f1[f1]00 00 00 00 0x10007fff7b60: 00 00 00 f2 f3 f3 f3 f3 00 00 00 00 00 00 f1 f1 0x10007fff7b70: f1 f1 04 f2 f2 f2 f3 f3 f3 f3 00 00 00 00 00 00 0x10007fff7b80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x10007fff7b90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x10007fff7ba0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 The first f3 byte is only aligned to 2B in shadow memory. And as we use movl instructions, it's unaligned store: movl $-202116109, 2147450888(%r12) (gdb) p /x -202116109 $1 = 0xf3f3f3f3