如何基于ASAN/libfuzzer正确分离编译两个LLVM IR文件?
如何在ASAN/LibFuzzer指导下正确分离编译LLVM IR文件
问题背景
- 无分离编译的可行示例:
代码包含sanitize_cookie_path函数和LLVMFuzzerTestOneInput模糊测试入口,执行以下命令编译后,可正常检测出heap-buffer-overflow漏洞:clang++ -O0 -g -fno-omit-frame-pointer -fsanitize=address,fuzzer -fsanitize-coverage=trace-cmp,trace-gep,trace-div sanitize_cookie_path.c -o fuzzer - 拆分编译后的异常情况:
将代码拆分为两部分分别生成IR文件后,调整IR(解决C++名称修饰、删除多余main函数),再用链接命令编译运行,仅能检测到内存泄漏,无法触发预期的heap-buffer-overflow漏洞。拆分生成IR的命令如下:- 编译C业务代码:
clang -O0 -emit-llvm sanitize_cookie_path.c -S -o sanitize_cookie_path.ll - 编译C++模糊测试入口:
clang -O0 -emit-llvm fuzz_sanitize_cookie_path.cc -S -o fuzz_sanitize_cookie_path.ll
- 编译C业务代码:
- 尝试过的无效方案:
- 生成IR时添加ASAN和覆盖参数,链接时加ASAN与fuzzer参数 → 运行触发段错误
- 仅在C业务代码生成IR时加ASAN参数,链接时加完整参数 → 运行仍触发段错误
- 链接时仅加fuzzer参数 → 出现链接错误
正确的分离编译步骤
要实现和无分离编译完全一致的漏洞检测效果,核心是在IR生成阶段就完成ASAN插桩和覆盖率插桩,链接阶段正确关联LibFuzzer与ASAN运行时库,具体步骤如下:
1. 生成带插桩的IR文件
编译C业务代码(sanitize_cookie_path.c):
clang -O0 -g -fno-omit-frame-pointer \ -fsanitize=address \ -fsanitize-coverage=trace-cmp,trace-gep,trace-div \ -emit-llvm sanitize_cookie_path.c -S -o sanitize_cookie_path.ll
编译C++模糊测试入口(fuzz_sanitize_cookie_path.cc):
clang++ -O0 -g -fno-omit-frame-pointer \ -fsanitize=address,fuzzer \ -fsanitize-coverage=trace-cmp,trace-gep,trace-div \ -emit-llvm fuzz_sanitize_cookie_path.cc -S -o fuzz_sanitize_cookie_path.ll
注意:模糊测试入口文件必须同时指定
-fsanitize=address,fuzzer,因为LibFuzzer的入口逻辑需要和ASAN插桩代码关联。
2. IR文件调整(必要操作)
- 确认
fuzz_sanitize_cookie_path.ll中无多余的main函数(LibFuzzer会自动提供程序入口) - 处理函数名称一致性:如果业务代码是C编写,模糊测试入口中调用
sanitize_cookie_path时需加extern "C",或直接在IR中确保函数名未被C++名称修饰,避免链接时找不到函数。
3. 链接生成可执行文件
clang++ -O0 -g -fno-omit-frame-pointer \ -fsanitize=address,fuzzer \ sanitize_cookie_path.ll fuzz_sanitize_cookie_path.ll -o fuzzer
链接阶段无需重复添加
-fsanitize-coverage参数,因为IR文件中已经包含了覆盖率插桩的代码;只需指定ASAN和LibFuzzer的运行时库即可。
关键注意事项
- ASAN和覆盖率插桩必须在IR生成阶段完成,这类插桩是编译时修改IR代码实现的,仅在链接阶段加参数无法对已生成的IR进行插桩。
- 避免重复插桩:如果生成IR时已经添加了插桩参数,链接阶段不要再次添加覆盖率相关参数,否则会导致代码冲突引发段错误。
- 模糊测试入口必须同时关联ASAN和LibFuzzer,否则会出现链接错误或运行时逻辑不兼容。
内容的提问来源于stack exchange,提问作者ruslanbyku
相关产品推荐
相关产品推荐

