1 ASAN用法
GCC和CLANG都已经集成了功能,编译时加编译选项即可。主要是-fsanitize=address
,其他便于调试。
gcc ex1.c -o ex1 -g -fsanitize=address -fsanitize-recover=address -fno-omit-frame-pointer -fno-common
注意:ASAN是整合工具,包括了LSAN等其其他工具。
注意:增加编译选项后,执行时就可以检测了,也可以加一些环境变量控制执行时的检测行为。
asan会在运行时检测内存问题,运行时需要添加几个环境变量
代码语言:javascript复制ASAN_OPTIONS='detect_leaks=1:halt_on_error=0:alloc_dealloc_mismatch=0:log_path=/tmp/asan_pgsql.log'
LSAN_OPTIONS='exitcode=0:suppressions=/tmp/asan_supp'
LD_PRELOAD=/usr/local/lib64/libasan.so
./ex1
- ASAN_OPTIONS:配置ASAN。
- LSAN_OPTIONS:配置LSAN,有些LSAN特殊的配置加在这里,比如suppressions忽略一些文件。
- halt_on_error:出现问题不停止程序运行。
- alloc_dealloc_mismatch:不允许内存申请不配对的情况,例如malloc / delete。
- log_path:结果输出到文件中,不打印到标准输出。
- exitcode:LSAN的配置,遇到问题不退出。
- suppressions:LSAN支持不检查一些文件。
- LD_PRELOAD:二进制可以不link libasan.so,加环境变量LD_PRELOAD即可。或者编译时Link libasan.so,可以省略该配置。
ASAN_OPTIONS和编译选项:https://github.com/google/sanitizers/wiki/SanitizerCommonFlags
LSAN_OPTIONS:https://github.com/google/sanitizers/wiki/AddressSanitizerLeakSanitizer
实例一:detected memory leaks
ex1.c
代码语言:javascript复制#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
void *dst = malloc(8);
void *src = "1234567";
memcpy(dst, src, 8);
printf("%sn", (char *) dst);
return 0;
}
编译
代码语言:javascript复制gcc ex1.c -o ex1 -g -fsanitize=address -fsanitize-recover=address -fno-omit-frame-pointer -fno-common
执行
代码语言:javascript复制ASAN_OPTIONS='halt_on_error=0:alloc_dealloc_mismatch=0:log_path=/tmp/asan_pgsql.log'
LD_PRELOAD=/usr/local/lib64/libasan.so
./ex1
结果
代码语言:javascript复制$ cat /tmp/asan_pgsql_01.log.652
=================================================================
==652==ERROR: LeakSanitizer: detected memory leaks
Direct leak of 8 byte(s) in 1 object(s) allocated from:
#0 0x7f04db292f08 in __interceptor_malloc ../../../../libsanitizer/asan/asan_malloc_linux.cc:144
#1 0x400853 in main /data02/mingjie/pgroot99/pgsrc/test/ex1.c:7
#2 0x7f04dabdd554 in __libc_start_main (/lib64/libc.so.6 0x22554)
SUMMARY: AddressSanitizer: 8 byte(s) leaked in 1 allocation(s).
实例二:heap-use-after-free
ex1.c
代码语言:javascript复制#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
void *dst = malloc(8);
void *src = "1234567";
char *p = dst;
memcpy(dst, src, 8);
printf("%sn", (char *) dst);
free(dst);
printf("%sn", p);
return 0;
}
编译
代码语言:javascript复制gcc ex1.c -o ex1 -g -fsanitize=address -fsanitize-recover=address -fno-omit-frame-pointer -fno-common
执行
代码语言:javascript复制ASAN_OPTIONS='halt_on_error=0:alloc_dealloc_mismatch=0:log_path=/tmp/asan_pgsql.log'
LD_PRELOAD=/usr/local/lib64/libasan.so
./ex1
结果
代码语言:javascript复制$ cat /tmp/asan_pgsql.log.1522
=================================================================
==1522==ERROR: AddressSanitizer: heap-use-after-free on address 0x602000000010 at pc 0x7f10079519d4 bp 0x7ffd47fb3d10 sp 0x7ffd47fb34c0
READ of size 2 at 0x602000000010 thread T0
#0 0x7f10079519d3 in __interceptor_puts ../../../../libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:1226
#1 0x4009b1 in main /data02/mingjie/pgroot99/pgsrc/test/ex1.c:16
#2 0x7f1007356554 in __libc_start_main (/lib64/libc.so.6 0x22554)
#3 0x4007d8 (/data02/mingjie/pgroot99/pgsrc/test/ex1 0x4007d8)
0x602000000010 is located 0 bytes inside of 8-byte region [0x602000000010,0x602000000018)
freed by thread T0 here:
#0 0x7f1007a0bb57 in __interceptor_free ../../../../libsanitizer/asan/asan_malloc_linux.cc:122
#1 0x4009a5 in main /data02/mingjie/pgroot99/pgsrc/test/ex1.c:14
#2 0x7f1007356554 in __libc_start_main (/lib64/libc.so.6 0x22554)
previously allocated by thread T0 here:
#0 0x7f1007a0bf08 in __interceptor_malloc ../../../../libsanitizer/asan/asan_malloc_linux.cc:144
#1 0x400893 in main /data02/mingjie/pgroot99/pgsrc/test/ex1.c:7
#2 0x7f1007356554 in __libc_start_main (/lib64/libc.so.6 0x22554)
SUMMARY: AddressSanitizer: heap-use-after-free ../../../../libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:1226 in __interceptor_puts
Shadow bytes around the buggy address:
0x0c047fff7fb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c047fff7fc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c047fff7fd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c047fff7fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c047fff7ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c047fff8000: fa fa[fd]fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c047fff8010: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c047fff8020: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c047fff8030: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c047fff8040: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c047fff8050: 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
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
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
Shadow gap: cc
实例三:heap-buffer-overflow
ex1.c
代码语言:javascript复制#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
void *dst = malloc(8);
void *src = "123456789";
memcpy(dst, src, 10);
printf("%sn", (char *) dst);
free(dst);
return 0;
}
编译
代码语言:javascript复制gcc ex1.c -o ex1 -g -fsanitize=address -fsanitize-recover=address -fno-omit-frame-pointer -fno-common
执行
代码语言:javascript复制ASAN_OPTIONS='halt_on_error=0:alloc_dealloc_mismatch=0:log_path=/tmp/asan_pgsql.log'
LD_PRELOAD=/usr/local/lib64/libasan.so
./ex1
结果
代码语言:javascript复制$ cat /tmp/asan_pgsql.log.2239
=================================================================
==2239==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x602000000018 at pc 0x7f8601ff8af0 bp 0x7ffd7ada1200 sp 0x7ffd7ada09b0
WRITE of size 10 at 0x602000000018 thread T0
#0 0x7f8601ff8aef in __interceptor_memcpy ../../../../libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:790
#1 0x400857 in main /data02/mingjie/pgroot99/pgsrc/test/ex1.c:10
#2 0x7f86019b3554 in __libc_start_main (/lib64/libc.so.6 0x22554)
#3 0x400778 (/data02/mingjie/pgroot99/pgsrc/test/ex1 0x400778)
0x602000000018 is located 0 bytes to the right of 8-byte region [0x602000000010,0x602000000018)
allocated by thread T0 here:
#0 0x7f8602068f08 in __interceptor_malloc ../../../../libsanitizer/asan/asan_malloc_linux.cc:144
#1 0x400833 in main /data02/mingjie/pgroot99/pgsrc/test/ex1.c:7
#2 0x7f86019b3554 in __libc_start_main (/lib64/libc.so.6 0x22554)
SUMMARY: AddressSanitizer: heap-buffer-overflow ../../../../libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:790 in __interceptor_memcpy
Shadow bytes around the buggy address:
0x0c047fff7fb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c047fff7fc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c047fff7fd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c047fff7fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c047fff7ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c047fff8000: fa fa 00[fa]fa fa fa fa fa fa fa fa fa fa fa fa
0x0c047fff8010: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c047fff8020: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c047fff8030: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c047fff8040: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c047fff8050: 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
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
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
Shadow gap: cc
=================================================================
==2239==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x602000000018 at pc 0x7f8601fae9d4 bp 0x7ffd7ada1200 sp 0x7ffd7ada09b0
READ of size 10 at 0x602000000018 thread T0
#0 0x7f8601fae9d3 in __interceptor_puts ../../../../libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:1226
#1 0x400863 in main /data02/mingjie/pgroot99/pgsrc/test/ex1.c:12
#2 0x7f86019b3554 in __libc_start_main (/lib64/libc.so.6 0x22554)
#3 0x400778 (/data02/mingjie/pgroot99/pgsrc/test/ex1 0x400778)
0x602000000018 is located 0 bytes to the right of 8-byte region [0x602000000010,0x602000000018)
allocated by thread T0 here:
#0 0x7f8602068f08 in __interceptor_malloc ../../../../libsanitizer/asan/asan_malloc_linux.cc:144
#1 0x400833 in main /data02/mingjie/pgroot99/pgsrc/test/ex1.c:7
#2 0x7f86019b3554 in __libc_start_main (/lib64/libc.so.6 0x22554)
SUMMARY: AddressSanitizer: heap-buffer-overflow ../../../../libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:1226 in __interceptor_puts
Shadow bytes around the buggy address:
0x0c047fff7fb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c047fff7fc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c047fff7fd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c047fff7fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c047fff7ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c047fff8000: fa fa 00[fa]fa fa fa fa fa fa fa fa fa fa fa fa
0x0c047fff8010: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c047fff8020: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c047fff8030: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c047fff8040: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c047fff8050: 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
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
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
Shadow gap: cc
2 ASAN PostgreSQL
编译选项中增加asan,然后配置环境变量即可。
具体记录在notes中了。