Thursday, February 27, 2014

AddressSanitizer: Detect user space run-time memory errors


AddressSanitizer(ASAN) Overview

ASAN helps detect user space memory errors when compiled with ASAN gcc flag. To understand the type of memory errors, I used the same tests I used to explore Valgrind's memcheck. I will also provide details of errors MALLOC_CHECK_ catches in "Usage Example" section below.

ASN gcc flag is available in gcc version 4.8 and above.

ASAN Internals
https://code.google.com/p/address-sanitizer/wiki/AddressSanitizerAlgorithm

ASAN Usage
  • Step1: Recompile the program enabling gdb & turning off compiler optimizations:
gcc -g -fsanitize=address -O1 prog.c -o <prog_name>

  • Step2: Run the program:
<prog_name> <prog_args>


ASAN Usage Example

I used the code at https://github.com/babuneelam/valgrind_tests/blob/master/vg_tests.c to explore 10 of the 11 tests:
  1. uninitialized free
  2. Read/Write after free
  3. buffer overrun
  4. Read/Write bad stack location (underrun)
  5. Memory Leak
  6. c++related test (ignore this)
  7. Overlapping memcpy
  8. double free
  9. pass unaddressable memory to system call
  10. Read/Write invalid stack location (overrun)
  11. Read/Write invalid global data location (overrun) 

Here are the results:



root@babu-VirtualBox:~/tools/address_sanitizer_tests# gcc -g -fsanitize=address -O1 vg_tests.c -o as_tests
root@babu-VirtualBox:~/tools/address_sanitizer_tests# ./as_tests 1
0
*num = 0
root@babu-VirtualBox:~/tools/address_sanitizer_tests# ./as_tests 2
root@babu-VirtualBox:~/tools/address_sanitizer_tests# ./as_tests 3
=================================================================
==4110== ERROR: AddressSanitizer: heap-buffer-overflow on address 0xb5e00ff8 at pc 0x8048942 bp 0xbf943fd8 sp 0xbf943fcc
WRITE of size 4 at 0xb5e00ff8 thread T0
    #0 0x8048941 (/home/babu/tools/address_sanitizer_tests/as_tests+0x8048941)
    #1 0x8048c1b (/home/babu/tools/address_sanitizer_tests/as_tests+0x8048c1b)
    #2 0xb5fa0904 (/lib/i386-linux-gnu/libc-2.17.so+0x19904)
    #3 0x80487b0 (/home/babu/tools/address_sanitizer_tests/as_tests+0x80487b0)
0xb5e00ff8 is located 0 bytes to the right of 40-byte region [0xb5e00fd0,0xb5e00ff8)
allocated by thread T0 here:
    #0 0xb6151854 (/usr/lib/i386-linux-gnu/libasan.so.0.0.0+0x16854)
    #1 0x8048918 (/home/babu/tools/address_sanitizer_tests/as_tests+0x8048918)
    #2 0xb5fa0904 (/lib/i386-linux-gnu/libc-2.17.so+0x19904)
Shadow bytes around the buggy address:
  0x36bc01a0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x36bc01b0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x36bc01c0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x36bc01d0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x36bc01e0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
=>0x36bc01f0: fa fa fa fa fa fa fa fa fa fa 00 00 00 00 00[fa]
  0x36bc0200:fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x36bc0210: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x36bc0220: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x36bc0230: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x36bc0240: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
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 righ 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
  ASan internal:         fe
==4110== ABORTING
root@babu-VirtualBox:~/tools/address_sanitizer_tests# ./as_tests 4
root@babu-VirtualBox:~/tools/address_sanitizer_tests# ./as_tests 5
root@babu-VirtualBox:~/tools/address_sanitizer_tests# ./as_tests 6
root@babu-VirtualBox:~/tools/address_sanitizer_tests# ./as_tests 7
root@babu-VirtualBox:~/tools/address_sanitizer_tests# ./as_tests 8
ASAN:SIGSEGV
=================================================================
==4118== ERROR: AddressSanitizer: SEGV on unknown address 0xfffffff4 (pc 0xb6102d6e sp 0xbf8b6c40 bp 0xfffffff4 T0)
AddressSanitizer can not provide additional info.
    #0 0xb6102d6d (/usr/lib/i386-linux-gnu/libasan.so.0.0.0+0x6d6d)
    #1 0xb61127b3 (/usr/lib/i386-linux-gnu/libasan.so.0.0.0+0x167b3)
    #2 0x8048ae4 (/home/babu/tools/address_sanitizer_tests/as_tests+0x8048ae4)
    #3 0x8048c34 (/home/babu/tools/address_sanitizer_tests/as_tests+0x8048c34)
    #4 0xb5f61904 (/lib/i386-linux-gnu/libc-2.17.so+0x19904)
    #5 0x80487b0 (/home/babu/tools/address_sanitizer_tests/as_tests+0x80487b0)
==4118== ABORTING
root@babu-VirtualBox:~/tools/address_sanitizer_tests# ./as_tests 9
Please type a bunch of characters and hit enter.
wer
root@babu-VirtualBox:~/tools/address_sanitizer_tests#
root@babu-VirtualBox:~/tools/address_sanitizer_tests# ./as_tests 10
root@babu-VirtualBox:~/tools/address_sanitizer_tests#
root@babu-VirtualBox:~/tools/address_sanitizer_tests# ./as_tests 11
root@babu-VirtualBox:~/tools/address_sanitizer_tests#


As we can see, just like MALLOC_CHECK_ tool, ASAN caught only buffer overrun and double free. Considering that ASAN homepage mentioned that ASAN detects use after free, I am surprised that my use after free test(test number - 2) went undetected by ASAN!!

References:

https://code.google.com/p/address-sanitizer/

No comments:

UA-48797665-1