AddressSanitizer


AddressSanitizer is an open source programming tool by Google that detects memory corruption bugs such as buffer overflows or accesses to a dangling pointer. AddressSanitizer is based on compiler instrumentation and directly-mapped shadow memory.
AddressSanitizer is currently implemented in Clang , GCC and Xcode . On average, the instrumentation increases processing time by about 73% and memory usage by 240%.

Users

and Firefox developers are active users of AddressSanitizer; the tool has found hundreds of bugs in these web browsers.
A number of bugs were found in FFmpeg
and FreeType. The Linux kernel has enabled the AddressSanitizer for the x86-64 architecture as of Linux version 4.0.

KernelAddressSanitizer

The KernelAddressSanitizer detects dynamic memory errors in the Linux kernel. Kernel instrumentation requires a special feature in the compiler supplying the -fsanitize=kernel-address command line option, since kernels do not use the same address space as normal programs.

Examples

Heap-use-after-free


// To compile: g++ -O -g -fsanitize=address heap-use-after-free.cc
int main


$./a.out

5587

READ of size 4 at 0x61400000fe44 thread T0
#0 0x47b55e in main /home/test/example_UseAfterFree.cc:7
#1 0x7f15cfe71b14 in __libc_start_main
#2 0x47b44c in _start
0x61400000fe44 is located 4 bytes inside of 400-byte region
#1 0x47b529 in main /home/test/example_UseAfterFree.cc:6
previously allocated by thread T0 here:
#0 0x465aa9 in operator new
#1 0x47b51e in main /home/test/example_UseAfterFree.cc:5
SUMMARY: AddressSanitizer: heap-use-after-free /home/test/example_UseAfterFree.cc:7 main
Shadow bytes around the buggy address:
0x0c287fff9f70: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c287fff9f80: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c287fff9f90: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c287fff9fa0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c287fff9fb0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
=>0x0c287fff9fc0: fa fa fa fa fa fa fa fafd fd fd fd fd fd fd
0x0c287fff9fd0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x0c287fff9fe0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x0c287fff9ff0: fd fd fd fd fd fd fd fd fd fd fa fa fa fa fa fa
0x0c287fffa000: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c287fffa010: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend :
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
ASan internal: fe

5587

Heap-buffer-overflow


// RUN: clang++ -O -g -fsanitize=address %t &&./a.out
int main

25372

READ of size 4 at 0x61400000ffd4 thread T0
#0 0x46bfee in main /tmp/main.cpp:4:13
0x61400000ffd4 is located 4 bytes to the right of 400-byte region
#1 0x46bfb9 in main /tmp/main.cpp:2:16

Stack-buffer-overflow


// RUN: clang -O -g -fsanitize=address %t &&./a.out
int main

7405

READ of size 4 at 0x7fff64740634 thread T0
#0 0x46c102 in main /tmp/example_StackOutOfBounds.cc:5
Address 0x7fff64740634 is located in stack of thread T0 at offset 436 in frame
#0 0x46bfaf in main /tmp/example_StackOutOfBounds.cc:2
This frame has 1 object:
32, 432) 'stack_array' < Memory access at offset 436 overflows this variable

Global-buffer-overflow


// RUN: clang -O -g -fsanitize=address %t &&./a.out
int global_array = ;
int main

7455

READ of size 4 at 0x000000689b54 thread T0
#0 0x46bfd7 in main /tmp/example_GlobalOutOfBounds.cc:4
0x000000689b54 is located 4 bytes to the right of
[global variable
'global_array' from 'example_GlobalOutOfBounds.cc' of size 400

Limitations

AddressSanitizer does not detect any uninitialized memory reads, and only detects some use-after-return bugs. It is also not capable of detecting all arbitrary memory corruption bugs, nor all arbitrary write bugs due to integer underflow/overflows. Adjacent buffers in structs and classes are not protected from overflow, in part to prevent breaking backwards compatibility.