目录
一、malloc leak/new leak(heap leak)
一、malloc leak/new leak(heap leak)
malloc leak/new leak其实都是堆内存申请的泄露问题,只不过malloc通常是c语言使用的方式,new是c++内存分配常用方式,它们的泄露其实很简单就是申请内存后没有释放。
代码:
//sanitize.cpp文件
1 #include <iostream>
2
3 using namespace std;
4
5 /***
6 执行编译:
7 g++ sanitize.c -o sanitize -ggdb -fsanitize=address
8 ASAN_OPTIONS=detect_stack_use_after_return=1 ./sanitize =》just for use after return
9 ***/
22 int malloc_leak(void)
23 {
24 cout << "malloc leak test start" << endl;
25 int *p;
26 p =(int*)malloc(7); //=》这里申请了7个字节的内存
27 cout << "malloc leak test end" << endl;
28 //free(p); //=》这里面没有释放
29 return 0;
30 }
127 int main()
128 {
132 //memory leak test
133 malloc_leak();
158 return 0;
159 }
检测结果:
user2@buildsrv-190:~/sf_user2/test$ g++ sanitize.cpp sanitize_order.cpp -o sanitize -ggdb -fsanitize=address
user2@buildsrv-190:~/sf_user2/test$ ./sanitize
malloc leak test start
malloc leak test end
=================================================================
==67068==ERROR: LeakSanitizer: detected memory leaks
Direct leak of 7 byte(s) in 1 object(s) allocated from:
#0 0x7f45f9366b40 in __interceptor_malloc (/usr/lib/x86_64-linux-gnu/libasan.so.4+0xdeb40)
#1 0x55a62a162a6c in malloc_leak() /home/user2/sf_user2/test/sanitize.cpp:26 =》异常的申请点
#2 0x55a62a163382 in main /home/user2/sf_user2/test/sanitize.cpp:133
#3 0x7f45f8b2fb96 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)
SUMMARY: AddressSanitizer: 7 byte(s) leaked in 1 allocation(s).
代码:
//sanitize.cpp文件
1 #include <iostream>
2
3 using namespace std;
4
5 /***
6 执行编译:
7 g++ sanitize.c -o sanitize -ggdb -fsanitize=address
8 ASAN_OPTIONS=detect_stack_use_after_return=1 ./sanitize =》just for use after return
9 ***/
32 int new_leak()
33 {
34 cout << "new leak test start" << endl;
35 int *q = new int[100]; //=>这里申请了内存
36 cout << "new leak test end" << endl;
37 //delete []q; //=>这里没有释放
38 return 0;
39 }
127 int main()
128 {
135 //new leak test
136 new_leak();
158 return 0;
159 }
检测结果:
user2@buildsrv-190:~/sf_user2/test$ g++ sanitize.cpp sanitize_order.cpp -o sanitize -ggdb -fsanitize=address
user2@buildsrv-190:~/sf_user2/test$ ./sanitize
new leak test start
new leak test end
=================================================================
==67487==ERROR: LeakSanitizer: detected memory leaks
Direct leak of 400 byte(s) in 1 object(s) allocated from:
#0 0x7f8a5db0a608 in operator new[](unsigned long) (/usr/lib/x86_64-linux-gnu/libasan.so.4+0xe0608)
#1 0x5613d6bfdad9 in new_leak() /home/user2/sf_user2/test/sanitize.cpp:35
#2 0x5613d6bfe382 in main /home/user2/sf_user2/test/sanitize.cpp:136
#3 0x7f8a5d2d1b96 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)
SUMMARY: AddressSanitizer: 400 byte(s) leaked in 1 allocation(s).
二、use after free
顾名思义就是使用那些已经释放的内存
代码:
//sanitize.cpp文件
1 #include <iostream>
2
3 using namespace std;
4
5 /***
6 执行编译:
7 g++ sanitize.c -o sanitize -ggdb -fsanitize=address
8 ASAN_OPTIONS=detect_stack_use_after_return=1 ./sanitize =》just for use after return
9 ***/
41 int use_after_free(void)
42 {
43 cout << "use after free test start" << endl;
44 int *p = new int[100];
45 p[1] = 2;
46 delete []p; //=>这里已经释放
47 p[2] = 3; //=>这里又重新使用
48 cout << "use after free test end" << endl;
49 return 0;
50 }
127 int main()
128 {
138 //use after test
139 use_after_free();
158 return 0;
159 }
检测结果:
user2@buildsrv-190:~/sf_user2/test$ g++ sanitize.cpp sanitize_order.cpp -o sanitize -ggdb -fsanitize=address
user2@buildsrv-190:~/sf_user2/test$ ./sanitize
use after free test start
=================================================================
==67843==ERROR: AddressSanitizer: heap-use-after-free on address 0x614000000048 at pc 0x55c5ede63be2 bp 0x7ffdc8d331f0 sp 0x7ffdc8d331e0
WRITE of size 4 at 0x614000000048 thread T0
#0 0x55c5ede63be1 in use_after_free() /home/user2/sf_user2/test/sanitize.cpp:47
#1 0x55c5ede64382 in main /home/user2/sf_user2/test/sanitize.cpp:139
#2 0x7f55aa5c4b96 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)
#3 0x55c5ede637c9 in _start (/data/sf_user2/test/sanitize+0x17c9)
0x614000000048 is located 8 bytes inside of 400-byte region [0x614000000040,0x6140000001d0)
freed by thread T0 here:
#0 0x7f55aadfe480 in operator delete[](void*) (/usr/lib/x86_64-linux-gnu/libasan.so.4+0xe1480)
#1 0x55c5ede63ba2 in use_after_free() /home/user2/sf_user2/test/sanitize.cpp:46
#2 0x55c5ede64382 in main /home/user2/sf_user2/test/sanitize.cpp:139
#3 0x7f55aa5c4b96 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)
previously allocated by thread T0 here:
#0 0x7f55aadfd608 in operator new[](unsigned long) (/usr/lib/x86_64-linux-gnu/libasan.so.4+0xe0608)
#1 0x55c5ede63b46 in use_after_free() /home/user2/sf_user2/test/sanitize.cpp:44
#2 0x55c5ede64382 in main /home/user2/sf_user2/test/sanitize.cpp:139
#3 0x7f55aa5c4b96 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)
SUMMARY: AddressSanitizer: heap-use-after-free /home/user2/sf_user2/test/sanitize.cpp:47 in use_after_free()
Shadow bytes around the buggy address:
0x0c287fff7fb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c287fff7fc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c287fff7fd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c287fff7fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c287fff7ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c287fff8000: fa fa fa fa fa fa fa fa fd[fd]fd fd fd fd fd fd
0x0c287fff8010: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x0c287fff8020: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x0c287fff8030: fd fd fd fd fd fd fd fd fd fd fa fa fa fa fa fa
0x0c287fff8040: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c287fff8050: 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
==67843==ABORTING
三、double free
顾名思义就是重复释放已经释放过的内存
代码:
//sanitize.cpp文件
1 #include <iostream>
2
3 using namespace std;
4
5 /***
6 执行编译:
7 g++ sanitize.c -o sanitize -ggdb -fsanitize=address
8 ASAN_OPTIONS=detect_stack_use_after_return=1 ./sanitize =》just for use after return
9 ***/
52 int double_free(void)
53 {
54 cout << "double free test start" << endl;
55 int *p = new int[100];
56 p[0] = 2;
57 delete []p; //=>第一次释放
58 delete []p; //=>第二次释放
59 cout << "double free test end" << endl;
60 return 0;
61 }
127 int main()
128 {
141 //double free test
142 double_free();
158 return 0;
159 }
检测结果:
user2@buildsrv-190:~/sf_user2/test$ g++ sanitize.cpp sanitize_order.cpp -o sanitize -ggdb -fsanitize=address
user2@buildsrv-190:~/sf_user2/test$ ./sanitize
double free test start
=================================================================
==67962==ERROR: AddressSanitizer: attempting double-free on 0x614000000040 in thread T0:
#0 0x7fa7f0fe9480 in operator delete[](void*) (/usr/lib/x86_64-linux-gnu/libasan.so.4+0xe1480)
#1 0x55b506095cbb in double_free() /home/user2/sf_user2/test/sanitize.cpp:58
#2 0x55b506096382 in main /home/user2/sf_user2/test/sanitize.cpp:142
#3 0x7fa7f07afb96 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)
#4 0x55b5060957c9 in _start (/data/sf_user2/test/sanitize+0x17c9)
0x614000000040 is located 0 bytes inside of 400-byte region [0x614000000040,0x6140000001d0)
freed by thread T0 here:
#0 0x7fa7f0fe9480 in operator delete[](void*) (/usr/lib/x86_64-linux-gnu/libasan.so.4+0xe1480)
#1 0x55b506095ca8 in double_free() /home/user2/sf_user2/test/sanitize.cpp:57
#2 0x55b506096382 in main /home/user2/sf_user2/test/sanitize.cpp:142
#3 0x7fa7f07afb96 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)
previously allocated by thread T0 here:
#0 0x7fa7f0fe8608 in operator new[](unsigned long) (/usr/lib/x86_64-linux-gnu/libasan.so.4+0xe0608)
#1 0x55b506095c50 in double_free() /home/user2/sf_user2/test/sanitize.cpp:55
#2 0x55b506096382 in main /home/user2/sf_user2/test/sanitize.cpp:142
#3 0x7fa7f07afb96 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)
SUMMARY: AddressSanitizer: double-free (/usr/lib/x86_64-linux-gnu/libasan.so.4+0xe1480) in operator delete[](void*)
==67962==ABORTING
四、heap overflow
顾名思义就是申请的堆内存本来是一个固定的大小,结果使用的时候超出了申请的范围
代码:
//sanitize.cpp文件
1 #include <iostream>
2
3 using namespace std;
4
5 /***
6 执行编译:
7 g++ sanitize.c -o sanitize -ggdb -fsanitize=address
8 ASAN_OPTIONS=detect_stack_use_after_return=1 ./sanitize =》just for use after return
9 ***/
63 int out_of_heap(void)
64 {
65 cout << "out of heap test start" << endl;
66 int *p = new int[100];
67 p[0] = 1;
68 p[100] = 100; //=>此处越界
69 delete []p;
70 cout << "out of heap test end" << endl;
71 return 0;
72 }
127 int main()
128 {
144 //out of heap test
145 out_of_heap();
158 return 0;
159 }
检测结果:
user2@buildsrv-190:~/sf_user2/test$ g++ sanitize.cpp sanitize_order.cpp -o sanitize -ggdb -fsanitize=address
user2@buildsrv-190:~/sf_user2/test$ ./sanitize
out of heap test start
=================================================================
==68588==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x6140000001d0 at pc 0x55ed46f3adac bp 0x7ffd76172b30 sp 0x7ffd76172b20
WRITE of size 4 at 0x6140000001d0 thread T0
#0 0x55ed46f3adab in out_of_heap() /home/user2/sf_user2/test/sanitize.cpp:68
#1 0x55ed46f3b382 in main /home/user2/sf_user2/test/sanitize.cpp:145
#2 0x7f3eb47c3b96 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)
#3 0x55ed46f3a7c9 in _start (/data/sf_user2/test/sanitize+0x17c9)
0x6140000001d0 is located 0 bytes to the right of 400-byte region [0x614000000040,0x6140000001d0)
allocated by thread T0 here:
#0 0x7f3eb4ffc608 in operator new[](unsigned long) (/usr/lib/x86_64-linux-gnu/libasan.so.4+0xe0608)
#1 0x55ed46f3ad24 in out_of_heap() /home/user2/sf_user2/test/sanitize.cpp:66
#2 0x55ed46f3b382 in main /home/user2/sf_user2/test/sanitize.cpp:145
#3 0x7f3eb47c3b96 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)
SUMMARY: AddressSanitizer: heap-buffer-overflow /home/user2/sf_user2/test/sanitize.cpp:68 in out_of_heap()
Shadow bytes around the buggy address:
0x0c287fff7fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c287fff7ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c287fff8000: fa fa fa fa fa fa fa fa 00 00 00 00 00 00 00 00
0x0c287fff8010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c287fff8020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c287fff8030: 00 00 00 00 00 00 00 00 00 00[fa]fa fa fa fa fa
0x0c287fff8040: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c287fff8050: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c287fff8060: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c287fff8070: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c287fff8080: 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
==68588==ABORTING
五、stack overflow
顾名思义就是使用超过了栈的大小,通常的局部变量或者形参都是存放在栈里面,一般常用的是数组越界或者递归过多导致的越界
代码:
//sanitize.cpp文件
1 #include <iostream>
2
3 using namespace std;
4
5 /***
6 执行编译:
7 g++ sanitize.c -o sanitize -ggdb -fsanitize=address
8 ASAN_OPTIONS=detect_stack_use_after_return=1 ./sanitize =》just for use after return
9 ***/
74 int out_of_stack(void)
75 {
76 cout << "out of stack test start" << endl;
77 int p[10];
78 p[0] = 1;
79 p[10] = 11; //=》越界
80 cout << "out of stack test end" << endl;
81 return 0;
82 }
127 int main()
128 {
147 //out of stack test
148 out_of_stack();
158 return 0;
159 }
检测结果:
user2@buildsrv-190:~/sf_user2/test$ ./sanitize
out of stack test start
=================================================================
==68817==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffccc8b4e98 at pc 0x55f0b793cf0f bp 0x7ffccc8b4e40 sp 0x7ffccc8b4e30
WRITE of size 4 at 0x7ffccc8b4e98 thread T0
#0 0x55f0b793cf0e in out_of_stack() /home/user2/sf_user2/test/sanitize.cpp:79
#1 0x55f0b793d382 in main /home/user2/sf_user2/test/sanitize.cpp:148
#2 0x7f39aa19fb96 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)
#3 0x55f0b793c7c9 in _start (/data/sf_user2/test/sanitize+0x17c9)
Address 0x7ffccc8b4e98 is located in stack of thread T0 at offset 72 in frame
#0 0x55f0b793ce03 in out_of_stack() /home/user2/sf_user2/test/sanitize.cpp:75
This frame has 1 object(s):
[32, 72) 'p' <== Memory access at offset 72 overflows this variable
HINT: this may be a false positive if your program uses some custom stack unwind mechanism or swapcontext
(longjmp and C++ exceptions *are* supported)
SUMMARY: AddressSanitizer: stack-buffer-overflow /home/user2/sf_user2/test/sanitize.cpp:79 in out_of_stack()
Shadow bytes around the buggy address:
0x10001990e980: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x10001990e990: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x10001990e9a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x10001990e9b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x10001990e9c0: 00 00 00 00 00 00 00 00 00 00 f1 f1 f1 f1 00 00
=>0x10001990e9d0: 00 00 00[f2]f2 f2 00 00 00 00 00 00 00 00 00 00
0x10001990e9e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x10001990e9f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x10001990ea00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x10001990ea10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x10001990ea20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
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
==68817==ABORTING
六、global value overflow
顾名思义是全局变量区的越界,也是访问了不该访问的内存
代码:
//sanitize.cpp文件
1 #include <iostream>
2
3 using namespace std;
4
5 /***
6 执行编译:
7 g++ sanitize.c -o sanitize -ggdb -fsanitize=address
8 ASAN_OPTIONS=detect_stack_use_after_return=1 ./sanitize =》just for use after return
9 ***/
84 int g_value[10];
85
86 int global_var_overflow(void)
87 {
88 cout << "global var overflow test start" << endl;
89 g_value[0] = 1;
90 g_value[11] = 11; //=>越界
91 cout << "global var overflow test end" << endl;
92 return 0;
93 }
127 int main()
128 {
150 //global var overflow test
151 global_var_overflow();
158 return 0;
159 }
检测结果:
user2@buildsrv-190:~/sf_user2/test$ g++ sanitize.cpp sanitize_order.cpp -o sanitize -ggdb -fsanitize=address
user2@buildsrv-190:~/sf_user2/test$ ./sanitize
global var overflow test start
=================================================================
==68920==ERROR: AddressSanitizer: global-buffer-overflow on address 0x55cd7207e90c at pc 0x55cd71e7c019 bp 0x7ffc8eb8ce90 sp 0x7ffc8eb8ce80
WRITE of size 4 at 0x55cd7207e90c thread T0
#0 0x55cd71e7c018 in global_var_overflow() /home/user2/sf_user2/test/sanitize.cpp:90
#1 0x55cd71e7c382 in main /home/user2/sf_user2/test/sanitize.cpp:151
#2 0x7f5071447b96 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)
#3 0x55cd71e7b7c9 in _start (/data/sf_user2/test/sanitize+0x17c9)
0x55cd7207e90c is located 4 bytes to the right of global variable 'g_value' defined in 'sanitize.cpp:84:5' (0x55cd7207e8e0) of size 40
0x55cd7207e90c is located 52 bytes to the left of global variable 'ptr' defined in 'sanitize.cpp:95:6' (0x55cd7207e940) of size 8
SUMMARY: AddressSanitizer: global-buffer-overflow /home/user2/sf_user2/test/sanitize.cpp:90 in global_var_overflow()
Shadow bytes around the buggy address:
0x0aba2e407cd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0aba2e407ce0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0aba2e407cf0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0aba2e407d00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0aba2e407d10: 00 00 00 00 01 f9 f9 f9 f9 f9 f9 f9 00 00 00 00
=>0x0aba2e407d20: 00[f9]f9 f9 f9 f9 f9 f9 00 f9 f9 f9 f9 f9 f9 f9
0x0aba2e407d30: 04 f9 f9 f9 f9 f9 f9 f9 00 00 00 00 04 f9 f9 f9
0x0aba2e407d40: f9 f9 f9 f9 00 00 00 00 00 00 00 00 00 00 00 00
0x0aba2e407d50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0aba2e407d60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0aba2e407d70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
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
==68920==ABORTING
七、use after scope
use after scope有点不太常见,大概的含义是使用了已经超过范围的局部变量,通常一个局部变量在函数外基本上就已经释放了,如果函数外再去访问其实是一种异常
代码:
//sanitize.cpp文件
1 #include <iostream>
2
3 using namespace std;
4
5 /***
6 执行编译:
7 g++ sanitize.c -o sanitize -ggdb -fsanitize=address
8 ASAN_OPTIONS=detect_stack_use_after_return=1 ./sanitize =》just for use after return
9 ***/
10
11 int use_after_scope(void)
12 {
13 int *p; //=>定义一个指针
14 {
15 int x = 1;
16 p = &x; //=>指向一个局部变量
17 }
18 cout << *p << endl; //=>在作用域之外其实那个x里面的内存已经释放掉了
19 return 0;
20 }
127 int main()
128 {
129 //use after scope test
130 //use_after_scope();
158 return 0;
159 }
检测结果:
user2@buildsrv-190:~/sf_user2/test$ g++ sanitize.cpp sanitize_order.cpp -o sanitize -ggdb -fsanitize=address
user2@buildsrv-190:~/sf_user2/test$ ./sanitize
=================================================================
==69443==ERROR: AddressSanitizer: stack-use-after-scope on address 0x7ffcc4071f90 at pc 0x55bf3ada39b7 bp 0x7ffcc4071f50 sp 0x7ffcc4071f40
READ of size 4 at 0x7ffcc4071f90 thread T0
#0 0x55bf3ada39b6 in use_after_scope() /home/user2/sf_user2/test/sanitize.cpp:18
#1 0x55bf3ada4382 in main /home/user2/sf_user2/test/sanitize.cpp:130
#2 0x7f4bd096fb96 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)
#3 0x55bf3ada37c9 in _start (/data/sf_user2/test/sanitize+0x17c9)
Address 0x7ffcc4071f90 is located in stack of thread T0 at offset 32 in frame
#0 0x55bf3ada38b9 in use_after_scope() /home/user2/sf_user2/test/sanitize.cpp:12
This frame has 1 object(s):
[32, 36) 'x' <== Memory access at offset 32 is inside this variable
HINT: this may be a false positive if your program uses some custom stack unwind mechanism or swapcontext
(longjmp and C++ exceptions *are* supported)
SUMMARY: AddressSanitizer: stack-use-after-scope /home/user2/sf_user2/test/sanitize.cpp:18 in use_after_scope()
Shadow bytes around the buggy address:
0x1000188063a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x1000188063b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x1000188063c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x1000188063d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x1000188063e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 f1 f1
=>0x1000188063f0: f1 f1[f8]f2 f2 f2 00 00 00 00 00 00 00 00 00 00
0x100018806400: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x100018806410: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x100018806420: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x100018806430: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x100018806440: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
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
==69443==ABORTING
八、use after return
跟上面的比较类似,甚至可以说是一个包含的关系,只不过一个是作用域之外的访问,一个是函数执行完后访问的局部变量
代码:
//sanitize.cpp文件
1 #include <iostream>
2
3 using namespace std;
4
5 /***
6 执行编译:
7 g++ sanitize.c -o sanitize -ggdb -fsanitize=address
8 ASAN_OPTIONS=detect_stack_use_after_return=1 ./sanitize =》just for use after return
9 ***/
10
95 int *ptr; //=>全局的指针
96 void getoflocal(void)
97 {
98 int i[100];
99 ptr = &i[0]; //=>指向一个函数内的局部数据首地址
100 }
101 int use_after_return(void)
102 {
103 cout << "use after return test start" << endl;
104 getoflocal(); //函数执行完毕
105 cout << "ptr is: " << *ptr; //访问全局指针指向的内存内容,其实内容在函数外已经return了
106 cout << "use after return test end" << endl;
107 return 0;
108 }
127 int main()
128 {
153 //use after return test
154 use_after_return();
158 return 0;
159 }
检测结果:
第一次执行:没有检测出异常
user2@buildsrv-190:~/sf_user2/test$ g++ sanitize.cpp sanitize_order.cpp -o sanitize -ggdb -fsanitize=address
user2@buildsrv-190:~/sf_user2/test$ ./sanitize
use after return test start
ptr is: 832835699use after return test end
第二次执行:成功检测到,但是需要带上ASAN的一个参数
user2@buildsrv-190:~/sf_user2/test$ ASAN_OPTIONS=detect_stack_use_after_return=1 ./sanitize
use after return test start
=================================================================
==69546==ERROR: AddressSanitizer: stack-use-after-return on address 0x7f9ec6e00020 at pc 0x558669fad234 bp 0x7ffca2384280 sp 0x7ffca2384270
READ of size 4 at 0x7f9ec6e00020 thread T0
#0 0x558669fad233 in use_after_return() /home/user2/sf_user2/test/sanitize.cpp:105
#1 0x558669fad382 in main /home/user2/sf_user2/test/sanitize.cpp:154
#2 0x7f9ecac93b96 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)
#3 0x558669fac7c9 in _start (/data/sf_user2/test/sanitize+0x17c9)
Address 0x7f9ec6e00020 is located in stack of thread T0 at offset 32 in frame
#0 0x558669fad061 in getoflocal() /home/user2/sf_user2/test/sanitize.cpp:97
This frame has 1 object(s):
[32, 432) 'i' <== Memory access at offset 32 is inside this variable
HINT: this may be a false positive if your program uses some custom stack unwind mechanism or swapcontext
(longjmp and C++ exceptions *are* supported)
SUMMARY: AddressSanitizer: stack-use-after-return /home/user2/sf_user2/test/sanitize.cpp:105 in use_after_return()
Shadow bytes around the buggy address:
0x0ff458db7fb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0ff458db7fc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0ff458db7fd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0ff458db7fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0ff458db7ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0ff458db8000: f5 f5 f5 f5[f5]f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5
0x0ff458db8010: f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5
0x0ff458db8020: f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5
0x0ff458db8030: f5 f5 f5 f5 f5 f5 f5 f5 00 00 00 00 00 00 00 00
0x0ff458db8040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0ff458db8050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
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
==69546==ABORTING
九、init order bugs
顾名思义,就是初始化顺序不一样导致的结果不一致问题。
代码:
//sanitize_order.cpp文件
int test(void)
{
return 5;
}
int extern_global = test();
//sanitize.cpp文件
1 #include <iostream>
2
3 using namespace std;
4
5 /***
6 执行编译:
7 g++ sanitize.c -o sanitize -ggdb -fsanitize=address
8 ASAN_OPTIONS=detect_stack_use_after_return=1 ./sanitize =》just for use after return
9 ASAN_OPTIONS=check_initialization_order=true ./sanitize =》just for init order bugs
10 ***/
110 extern int extern_global;
111
112 int __attribute__((noinline)) read_extern_global(void)
113 {
114 return extern_global;
115 }
116
117 int x = read_extern_global(); // =>此处读取的会因为init的不同导致结果的不同
118
119 int init_order_bug(void)
120 {
121 cout << "init order bug test start" << endl;
122 cout << "extern global: " << x << endl;
123 cout << "init order bug test end" << endl;
124 return 0;
125 }
127 int main()
128 {
156 //init order bug
157 init_order_bug();
158 return 0;
159 }
编译情况:
user2@buildsrv-190:~/sf_user2/test$ g++ sanitize.cpp sanitize_order.cpp -o sanitize1 -ggdb -fsanitize=address
user2@buildsrv-190:~/sf_user2/test$ ./sanitize1
init order bug test start
extern global: 0 =》这里返回值是0
init order bug test end
user2@buildsrv-190:~/sf_user2/test$ g++ sanitize_order.cpp sanitize.cpp -o sanitize -ggdb -fsanitize=address
user2@buildsrv-190:~/sf_user2/test$ ./sanitize
init order bug test start
extern global: 5 =》这里返回值却是5
init order bug test end
检测结果:
user2@buildsrv-190:~/sf_user2/test$ ASAN_OPTIONS=check_initialization_order=true ./sanitize1
=================================================================
==66446==ERROR: AddressSanitizer: initialization-order-fiasco on address 0x5601dd2829e0 at pc 0x5601dd0802ad bp 0x7ffd40b576a0 sp 0x7ffd40b57690
READ of size 4 at 0x5601dd2829e0 thread T0
#0 0x5601dd0802ac in read_extern_global() /home/user2/sf_user2/test/sanitize.cpp:114
#1 0x5601dd0803e4 in __static_initialization_and_destruction_0 /home/user2/sf_user2/test/sanitize.cpp:117
#2 0x5601dd08043a in _GLOBAL__sub_I__Z15use_after_scopev /home/user2/sf_user2/test/sanitize.cpp:159
#3 0x5601dd08058c in __libc_csu_init (/data/sf_user2/test/sanitize1+0x258c)
#4 0x7f80326e5b27 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b27)
#5 0x5601dd07f7c9 in _start (/data/sf_user2/test/sanitize1+0x17c9)
0x5601dd2829e0 is located 0 bytes inside of global variable 'extern_global' defined in 'sanitize_order.cpp:6:5' (0x5601dd2829e0) of size 4
registered at:
#0 0x7f8032e744a8 (/usr/lib/x86_64-linux-gnu/libasan.so.4+0x364a8)
#1 0x5601dd08053b in _GLOBAL__sub_I_00099_1__Z4testv (/data/sf_user2/test/sanitize1+0x253b)
#2 0x5601dd08058c in __libc_csu_init (/data/sf_user2/test/sanitize1+0x258c)
SUMMARY: AddressSanitizer: initialization-order-fiasco /home/user2/sf_user2/test/sanitize.cpp:114 in read_extern_global()
Shadow bytes around the buggy address:
0x0ac0bba484e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0ac0bba484f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0ac0bba48500: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0ac0bba48510: 00 00 00 00 01 f9 f9 f9 f9 f9 f9 f9 00 00 00 00
0x0ac0bba48520: 00 f9 f9 f9 f9 f9 f9 f9 00 f9 f9 f9 f9 f9 f9 f9
=>0x0ac0bba48530: 04 f9 f9 f9 f9 f9 f9 f9 00 00 00 00[f6]f6 f6 f6
0x0ac0bba48540: f6 f6 f6 f6 00 00 00 00 00 00 00 00 00 00 00 00
0x0ac0bba48550: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0ac0bba48560: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0ac0bba48570: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0ac0bba48580: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
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
==66446==ABORTING