This is an archive of the discontinued LLVM Phabricator instance.

[asan] fix false dynamic-stack-buffer-overflow report with constantly-sized dynamic allocas
ClosedPublic

Authored by kubamracek on Jun 19 2016, 1:02 PM.

Diff Detail

Event Timeline

kubamracek updated this revision to Diff 61221.Jun 19 2016, 1:02 PM
kubamracek retitled this revision from to [asan] fix false dynamic-stack-buffer-overflow report with constantly-sized dynamic allocas.
kubamracek updated this object.
kubamracek added a project: Restricted Project.
kubamracek added subscribers: llvm-commits, zaks.anna.
m.ostapenko edited edge metadata.Jun 20 2016, 2:54 AM

Hm, with this patch I got such a strange error:

$ cat test.c

#include <alloca.h>
#include <stdio.h>
#include <string.h>

void f1() {
  char *dynamic_buffer = (char *)alloca(200);
  fprintf(stderr, "dynamic_buffer = %p, dynamic_buffer_end = %p\n", dynamic_buffer, dynamic_buffer + 200);
  dynamic_buffer[2] = 1;
  return;
}

void f2() {
  char buf[1024];
  fprintf(stderr, "buf = %p, buf_end = %p\n", buf, buf + 1024);
  memset(buf, 'x', 1024);
}

int main(int argc, const char *argv[]) {
  f1();
  f2();
  fprintf(stderr, "Done.\n");
  return 0;
}

$ clang -fsanitize=address test.c && ./a.out

dynamic_buffer = 0x7ffed7c98a80, dynamic_buffer_end = 0x7ffed7c98b48
=================================================================
==15867==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffed7c98a82 at pc 0x0000004dbaaa bp 0x7ffed7c98a50 sp 0x7ffed7c98a48
WRITE of size 1 at 0x7ffed7c98a82 thread T0
    #0 0x4dbaa9 in f1 (/home/max/build/llvm/a.out+0x4dbaa9)
    #1 0x4dbcda in main (/home/max/build/llvm/a.out+0x4dbcda)
    #2 0x7f1a18464ec4 in __libc_start_main /build/eglibc-3GlaMS/eglibc-2.19/csu/libc-start.c:287
    #3 0x418b95 in _start (/home/max/build/llvm/a.out+0x418b95)

Address 0x7ffed7c98a82 is located in stack of thread T0 at offset 34 in frame
    #0 0x4db95f in f1 (/home/max/build/llvm/a.out+0x4db95f)

  This frame has 1 object(s):
    [32, 33) '' <== Memory access at offset 34 overflows 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-overflow (/home/max/build/llvm/a.out+0x4dbaa9) in f1
Shadow bytes around the buggy address:
  0x10005af8b100: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10005af8b110: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10005af8b120: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10005af8b130: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10005af8b140: 00 00 00 00 00 00 00 00 00 00 00 00 f1 f1 f1 f1
=>0x10005af8b150:[01]f3 f3 f3 00 00 00 00 00 00 00 00 00 00 00 00
  0x10005af8b160: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10005af8b170: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10005af8b180: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10005af8b190: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10005af8b1a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Heap right redzone:      fb
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack partial redzone:   f4
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb

It seems that dynamic_buffer wasn't even allocated here.

kubamracek updated this revision to Diff 61248.Jun 20 2016, 4:30 AM
kubamracek edited edge metadata.

Update patch to correctly calculate the size of the dynamic alloca. Added -fstack-protector to the test cases.

The change looks sane to me (not sure I can push LGTM button though), just a little nit below.

projects/compiler-rt/test/asan/TestCases/alloca_constant_size.cc
4

Do we need to check if the target supports "-fprotector" ?

kubamracek added inline comments.Jun 20 2016, 11:19 AM
projects/compiler-rt/test/asan/TestCases/alloca_constant_size.cc
4

AFAIK it should be available in all ASan-supported targets.

Since this is an IR-pass change, could you add a regression test checking the changes made by the -asan pass.

lib/Transforms/Instrumentation/AddressSanitizer.cpp
462

You probably can get rid of the helper function now.

900

Why is this needed?

kubamracek added inline comments.Jun 20 2016, 2:32 PM
lib/Transforms/Instrumentation/AddressSanitizer.cpp
900

The change above makes getAllocaSizeInBytes valid only for static allocas (otherwise it asserts). This avoids calling getAllocaSizeInBytes for dynamic allocas.

zaks.anna added inline comments.Jun 20 2016, 2:54 PM
lib/Transforms/Instrumentation/AddressSanitizer.cpp
462

I was trying to figure out why we have the check for AI.isArrayAllocation() here and I cannot.. Looks like it was added here:

http://reviews.llvm.org/D6055

900

Ok, Maybe we could get rid of the helper and place this check next to the getAllocaSizeInBytes to make it clear why we call this.

I think you don't need two test files, could you combine them to one source file (you'll probably want use ifdefs)?

lib/Transforms/Instrumentation/AddressSanitizer.cpp
462

I was trying to figure out why we have the check for AI.isArrayAllocation() here and I cannot.. Looks like it was added here:

http://reviews.llvm.org/D6055

Yeah, this is a artifact from initial implementation. I don't remember exact reason why I placed this check here, but this probably was a mistake.

kubamracek updated this revision to Diff 61905.Jun 26 2016, 1:45 AM

Updating patch.

m.ostapenko accepted this revision.Jun 27 2016, 1:00 AM
m.ostapenko edited edge metadata.

Ok, thank you for fixing this!

This revision is now accepted and ready to land.Jun 27 2016, 1:00 AM
This revision was automatically updated to reflect the committed changes.

Landed:
LLVM part: r273888
compiler-rt part: r273889