为什么 AddressSanitizer 没有在 nginx 中显示堆 use-after-free 错误

我有如下的测试代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>

struct Info {
    char *p;
    int num;
};

int main()
{
    struct Info *pInfo = (struct Info*)malloc(sizeof(struct Info));
    free(pInfo);
    printf("%d\n", pInfo->num);
    return 0;
}

我使用以下命令编译和执行它:

gcc -O1 -g -fsanitize=address test.c -o t

AddressSanitizer 可以打印错误信息,例如 heap-use-after-free,如下所示:

==15552==ERROR: AddressSanitizer: heap-use-after-free on address 0x60200000eff8 at pc 0x47b4a1 bp 0x7fff17684ed0 sp 0x7fff17684ec8
READ of size 4 at 0x60200000eff8 thread T0
    #0 0x47b4a0 in main /home/xiabaichuan/test_tmp/test.c:18
    #1 0x7f318a01a554 in __libc_start_main (/lib64/libc.so.6+0x22554)
    #2 0x47b38c in _start (/home/xiabaichuan/test_tmp/t+0x47b38c)

0x60200000eff8 is located 8 bytes inside of 16-byte region [0x60200000eff0,0x60200000f000)
freed by thread T0 here:
    #0 0x465129 in free (/home/xiabaichuan/test_tmp/t+0x465129)
    #1 0x47b465 in main /home/xiabaichuan/test_tmp/test.c:17

previously allocated by thread T0 here:
    #0 0x4652a9 in __interceptor_malloc (/home/xiabaichuan/test_tmp/t+0x4652a9)
    #1 0x47b45a in main /home/xiabaichuan/test_tmp/test.c:16

SUMMARY: AddressSanitizer: heap-use-after-free /home/xiabaichuan/test_tmp/test.c:18 main
Shadow bytes around the buggy address:

然而,当我将相同的测试代码复制到 nginx http 模块中,编译并运行后,发送 HTTP 请求来触发代码后,AddressSanitizer 没有输出任何堆 use-after-free 错误信息;编译 NGINX 的命令如下:

gcc -o objs/nginx -L/home/xiabaichuan/master/cluster_live/TOOL/openresty-1.15.8.1/build/luajit-root/usr/local/openresty/luajit/lib -L/home/xiabaichuan/master/cluster_live/TOOL/openresty-1.15.8.1/build/luajit-root/usr/local/openresty/luajit/lib -Wl,-rpath,/usr/local/openresty/luajit/lib -fsanitize=address -fno-omit-frame-pointer -fsanitize-recover=address -Wl,-E -Wl,-E -ldl -lcrypt -L/home/xiabaichuan/master/cluster_live/TOOL/openresty-1.15.8.1/build/luajit-root/usr/local/openresty/luajit/lib -lluajit-5.1 -lm -ldl -L/home/xiabaichuan/master/cluster_live/TOOL/openresty-1.15.8.1/build/luajit-root/usr/local/openresty/luajit/lib -lluajit-5.1 -lm -ldl -lpcre -lssl -lcrypto -ldl -lz \
-Wl,-E

当我发送 HTTP 请求到 nginx 时,printf 打印出一个随机数,但是 AddressSanitizer 没有输出任何错误信息;nginx 打印如下内容:

[root@osboxes sbin]# ./nginx
788529154 (提示:这个数字是一个随机错误数字)

nginx 测试代码如下:

struct Info
{
    int num;
};

static void
ngx_http_flv_live_cleanup(void *data)
{
    ngx_rtmp_session_t *s;

    s = data;

    ngx_log_error(NGX_LOG_INFO, s->connection->log, 0,
            "live:\"flv close connection\"");


    struct Info *pInfo = (struct Info *)malloc(sizeof(struct Info));
    pInfo->num = 2;
    free(pInfo);

    ngx_http_flv_live_close_session_handler(s);
    ngx_log_error(NGX_LOG_INFO, s->connection->log, 0,
            "live:\"flv close connection:%d\"", pInfo->num);
    printf("%d\n", pInfo->num);
    ngx_http_flv_live_close_session_handler(s);
}

当我使用 curl 访问 flv-http URL 时,这段代码可能会被执行,但是这段代码:“printf("%d\n", pInfo->num);”不会显示堆 use-after-free,只会打印一个随机数。

点赞