You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

LLVM Address Sanitizer与MALLOC_CHECK_=3:后者是否仍具必要性?

Address Sanitizer与MALLOC_CHECK_=3的检测差异验证

传闻真实性说明

关于“Address Sanitizer无法识别破坏分配器私有数据结构”的说法,需分场景看待:

  • 当程序使用ASAN替换后的分配器时,ASAN会对自身的元数据做严格监控,任何篡改行为都会被即时检测到。
  • 但如果程序绕过ASAN的拦截,直接调用系统原生的malloc/free(比如通过动态链接获取原生函数地址),ASAN就无法监控这类内存操作,此时对原生分配器私有结构的破坏,只有MALLOC_CHECK_=3能检测到。

满足要求的单元测试用例

以下代码可实现“ASAN下通过,MALLOC_CHECK_=3下失败”的效果:

#include <dlfcn.h>
#include <cstdlib>

// 定义原生内存分配/释放的函数指针
typedef void* (*RealMalloc)(size_t);
typedef void (*RealFree)(void*);

int main() {
    // 获取系统原生malloc和free的真实地址,绕过ASAN拦截
    RealMalloc real_malloc = (RealMalloc)dlsym(RTLD_NEXT, "malloc");
    RealFree real_free = (RealFree)dlsym(RTLD_NEXT, "free");

    if (!real_malloc || !real_free) {
        return 1;
    }

    // 用原生malloc分配内存
    void* ptr = real_malloc(1024);
    if (!ptr) {
        return 1;
    }

    // 篡改glibc malloc_chunk的size字段(破坏分配器私有结构)
    // 注:malloc_chunk结构依赖glibc版本,此代码适配常见x86/x86_64环境
    size_t* size_field = (size_t*)((char*)ptr - sizeof(size_t));
    *size_field = 0xdeadbeef; // 写入非法值破坏堆结构

    // 释放内存触发检测
    real_free(ptr);

    return 0;
}

编译与运行验证

  1. 编译代码:
    g++ -o malloc_corruption_test malloc_corruption_test.cpp -ldl
    
  2. ASAN环境下运行(无报错):
    ASAN_OPTIONS=detect_leaks=0 ./malloc_corruption_test
    
  3. MALLOC_CHECK_=3环境下运行(触发堆结构损坏报错):
    MALLOC_CHECK_=3 ./malloc_corruption_test
    
    运行后会输出类似错误:

    *** Error in './malloc_corruption_test': corrupted double-linked list: 0x000000000209a010 ***

结论

  • 上述测试用例证实了特殊场景下MALLOC_CHECK_=3能检测到ASAN覆盖不到的内存错误。
  • 常规开发中,ASAN已能覆盖绝大多数内存错误场景;但如果项目存在绕过标准分配器的底层代码、动态加载模块,保留MALLOC_CHECK_=3作为补充检测仍有必要。

内容的提问来源于stack exchange,提问作者Lajos Nagy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 08:30:07