Sanitize检测的几种常见问题

目录

一、malloc leak/new leak(heap leak)

二、use after free

三、double free

四、heap overflow

五、stack overflow

六、global value overflow

七、use after scope

八、use after return

九、init order bugs


一、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

要在Python中实现图文成片,您需要使用适当的库来处理图像和文本。 以下是一些库,您可以使用它们来实现图文成片: 1. Pillow:Pillow是Python Imaging Library的分支,它提供了创建、编辑和处理图像的方法。 2. Matplotlib:Matplotlib是一个绘图库,用于创建各种类型的图表,包括条形图、散点图、线图等。 3. OpenCV:OpenCV是一个针对计算机视觉的库,它提供了处理图像和视频的方法。 4. Pygame:Pygame是一个游戏开发库,它可以用于创建图形用户界面和处理图像。 5. NLTK:NLTK是一个自然语言处理库,它提供了处理文本的方法,包括分词、词性标注、命名实体识别等。 您可以使用这些库中的任何一个或多个来实现图文成片。下面是一个简单的示例,演示如何使用Pillow和Matplotlib库来创建图文成片: ```python from PIL import Image import matplotlib.pyplot as plt # 加载图像 img = Image.open('image.jpg') # 显示图像 plt.imshow(img) # 添加标题 plt.title('My Image') # 显示图像和标题 plt.show() # 添加文本 plt.text(100, 100, 'Hello World!', fontsize=12, color='red') # 保存图像和文本 plt.savefig('output.jpg') ``` 这个示例加载名为“image.jpg”的图像,并在其上添加一个标题和一些文本。然后,它将图像和文本保存到名为“output.jpg”的文件中。 您可以根据需要修改示例代码,使用其他库来添加更多的图像和文本效果。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值