Libfuzzer 支持源文件级别的检测。-fsanitize=fuzzer
一种选择是构建没有标志的第三方库。检查 CFLAGS 传递给这些库的配置,以删除此标志。
仅标头库通常包含模板,fmt 就是这种情况。它们必须在编译时实例化。我认为没有简单的方法来处理这些。您可以找到所有使用的模板参数,创建将它们与这些参数一起使用的 thunk 代码,从检测中排除此代码并修改您的调用代码以使用这些实例化的函数,但这非常困难。
当您不希望检测的代码仅执行日志记录或其他可以跳过而不修改应用程序行为的活动时,您可以使其有条件进行编译。Libfuzzer 文档建议使用FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
define 来标记您不想为模糊测试构建的代码。在 fmt 情况下,这将是:
bool fuzzingThisFunc() {
if(!checkSomething()) {
#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
fmt::printf("error log");
#endif
return false;
}
...
return true;
}
或修改库代码:
template <typename S, typename... Args,
FMT_ENABLE_IF(detail::is_string<S>::value)>
inline int printf(const S& format_str, const Args&... args) {
#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
using context = basic_printf_context_t<char_t<S>>;
return vprintf(to_string_view(format_str),
make_format_args<context>(args...));
#else
return 0; //C printf returns number of characters written, I assume same for fmt.
#endif
}
第二种情况更容易编码(每个排除的 func 一个修改),但是每次获得新的 fmt 版本时都必须添加此修改。在第一种情况下,您必须修改每个排除的 func 调用站点。
对于这两种情况,您都应该添加-DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
到配置的 CFLAGS 以进行模糊测试目标构建。