Back

Introduction to AddressSanitizer

by WANGWANG


 

1. About AddressSanitizer

1.1 Introduction

Perhaps many people have heard a story like this: a company's server will crash without warning every three months, how can you not find the reason, in order to avoid the problems that may be caused by the crash, only every 2 Manually restart the server once a month. Behind this kind of somewhat eccentric event, a series of memory errors represented by memory leaks are often behind the scenes.

 

In computer science, a memory leak is a condition in which a program fails to release memory that is no longer in use due to negligence or error. Memory leak does not mean that the memory disappears physically. Instead, after the application allocates a certain amount of memory, it loses control of the memory due to design errors, thus causing memory waste.


Memory leaks can result in a reduction in the amount of available memory, which can degrade the performance of your computer. Excessive free memory is allocated, causing all or part of the device to stop working properly or the application to crash.


Other memory errors include buffer overflows, out-of-bounds access, etc. These errors can cause program calculation errors and cause program crashes. This is especially fatal in embedded systems with tight memory. Google's open source tool, AddressSanitizer, can help us. Detect such errors.


AddressSanitizer (ASan) is a fast memory error detection tool. It's very fast, just dragging the program around twice. It includes a compiler instrumentation module and a runtime library that provides a malloc()/free() alternative. Starting with gcc 4.8, AddressSanitizer became part of gcc.


Learn more about AddressSanitizer information to access its github project address:
https://github.com/google/sanitizers/wiki/AddressSanitizer

 

1.2 Introduction to AddressSanitizer Principle


AddressSanitizer mainly consists of two parts: Instrumentation and Run-time library. The instrumentation is mainly for the operation of accessing memory (store, load, alloca, etc.) at the llvm compiler level, and processing them. The dynamic runtime library mainly provides some complex functions at runtime (such as poison/unpoison shadow memory) and hooks the system call function of malloc, free, etc. The idea of the algorithm is: if you want to prevent the Buffer Overflow vulnerability, you only need to add a region (RedZone) to the right end (or both ends of each memory area) to make the shadow memory of the RedZone area (Shadow Memory). ) set to be unwritable. The specific schematic diagram is shown below.

 

 

Memory mapping


The main principle of AddressSanitizer protection is to provide coarse-grained shadow memory for virtual memory in the program (one byte of memory corresponding to one byte of memory). In order to reduce overhead, a direct memory mapping strategy is adopted. The strategy is as follows: Shadow=(Mem >> 3) + offset. Each 8 bytes of memory corresponds to one byte of shadow memory, and each byte in the shadow memory accesses a number k. If k=0, it means that the corresponding 8 bytes of memory of the shadow memory can be accessed. If 0 < k < 7, it means that the first k bytes can be accessed. If k is a negative number, different numbers indicate different stack errors (Heap buffer overflow).

 

Insert


In order to prevent buffer overflow, you need to allocate additional memory Redzone on both sides of the originally allocated memory, and lock the memory on both sides to be inaccessible. This can effectively prevent buffer overflow (but not buffer overflow). The following is an example of instrumentation in the stack.

 

Unplugged code:

 

Post-instrument code:

 

Post-instrument code:

The malloc/free function was replaced in the dynamic runtime. In the malloc function, the memory of the Redzone area is additionally allocated, and the shadow memory corresponding to the Redzone area is locked, and the shadow memory corresponding to the main memory area is not locked.
The free function locks all allocated memory areas and puts them in the queue of the isolated area (guarantee that they will not be allocated by the malloc function for a certain period of time), which can detect the problem of Use after free.
Learn more about the principles of the ASan algorithm and access the following addresses:
https://github.com/google/sanitizers/wiki/AddressSanitizerAlgorithm

 

2, how to use

Environment: Ubuntu 16.04 gcc 4.8 or higher
Compile and link your program with the -fsanitize=address option;
Compile with -fno-omit-frame-pointer to add a better stack trace to the error message.
Increase -O1 for better performance.
Let's take the simple test code leaktest.c as an example.

 

 

Compile leavetest.c by entering the following command in the terminal.

 

 

Running leaktest will print the following error message:

 

 

The first part (ERROR) indicates the error type detected memory leaks;
The second part gives detailed error information: Direct leak of 80 byte(s) in 1 object(s), and the name of the object/source file location/row number where the error occurred;
The third part is a summary of the above information (SUMMARY).

 

3, set the detection whitelist

ASan detection whitelist can be set according to the following requirements
Ignore a function that determines the correct function to speed up the application;
Ignore a function of a specific function (for example: bypassing the frame boundary through the thread's stack);
Ignore known issues.

Use the no_sanitize_address attribute (supported by Clang3.3 and GCC4.8 and above) to define the following macro commands:

 

4, the type of error that AddressSanitizer can detect (subject to the official wiki)

Please submit your email address to access support documents.