1. 看一下下面的代码,是否存在bug?
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
typedef struct {
int a;
int b;
int c;
int d;
} s_t;
typedef struct {
int m;
s_t *pt;
} z_t;
int main()
{
z_t z;
z.pt = malloc(sizeof(z.pt));
z.pt->a = 1;
z.pt->b = 2;
z.pt->c = 3;
z.pt->d = 4;
printf("%d-%d-%d-%d\n", z.pt->a, z.pt->b, z.pt->c, z.pt->d);
free(z.pt);
return 0;
};
.....
编译运行结果如下,打印结果完全正确。
2. 进一步分析
修改makefile, 打开address sanitizer:
gcc -g -O0 -fsanitize=address -fno-omit-frame-pointer main.c
再次运行,结果如下:
AddressSanitizer 报错:堆缓冲区溢出,看来代码中存在bug.
下面进一步分析错误信息
1.==386018==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x602000000018 at pc 0x55d40cf43391 bp 0x7ffe2a11bbc0 sp 0x7ffe2a11bbb0
WRITE of size 4 at 0x602000000018 thread T0
#0 0x55d40cf43390 in main /home/ricky/project/malloc/main.c:24
#1 0x7f7c0e31dd8f in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
#2 0x7f7c0e31de3f in __libc_start_main_impl ../csu/libc-start.c:392
#3 0x55d40cf43184 in _start (/home/ricky/project/malloc/a.out+0x1184)
堆缓冲区溢出:main.c:24 写地址 0x602000000018,大小4bytes
2.0x602000000018 is located 0 bytes to the right of 8-byte region [0x602000000010,0x602000000018)
allocated by thread T0 here:
#0 0x7f7c0e5d1887 in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:145
#1 0x55d40cf432c8 in main /home/ricky/project/malloc/main.c:20
#2 0x7f7c0e31dd8f in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
0x602000000018 位于buffer [0x602000000010,0x602000000018) 右侧0bytes.
buffer [0x602000000010,0x602000000018) 是main.c:20分配的。
根据上述分析可以,第20行分配了8个bytes[0x602000000010,0x602000000018) 的buffer, 而第24行越界访问(写: [0x602000000018,0x60200000001B))。
所以第20行的代码应该修改为:z.pt = malloc(sizeof(*z.pt));
我的另一篇博客描述了同样的一个问题,可以参考: