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>
<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:
- uninitialized free
- Read/Write after free
- buffer overrun
- Read/Write bad stack location (underrun)
- Memory Leak
- c++related test (ignore this)
- Overlapping memcpy
- double free
- pass unaddressable memory to system call
- Read/Write invalid stack location (overrun)
- 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/