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

Reply via email to