Fuzz 介绍
Fuzz测试(Fuzzing)是一种自动化的、随机的测试方法,通过向系统输入大量随机数据,尝试引发程序错误、崩溃或未定义的行为。Fuzz测试的主要目标是找出软件中的未知错误。
Fuzz测试的基本流程如下:
-
输入生成:首先,Fuzz测试工具生成一些随机的或者半随机的输入。这些输入可能是完全随机的,也可能是基于一些规则或模板的。
-
输入执行:然后,Fuzz测试工具将这些输入送给被测试的软件或系统。这可能涉及到启动一个新的进程,或者调用一个函数,或者发送一个网络请求。
-
结果监控:Fuzz测试工具监控被测试的软件或系统的行为,看是否出现了错误、崩溃或未定义的行为。这可能涉及到检查返回值,或者监控进程状态,或者分析日志。
-
错误报告:如果Fuzz测试工具发现了问题,它会生成一个错误报告,包括输入数据和错误详情。
OpenHarmony Fuzz
开源鸿蒙项目采用LibFuzzer作为项目Fuzz测试框架(即生成随机输入)。
LibFuzzer是一个由LLVM项目提供的强大的fuzzing框架,它使用了一种称为覆盖引导的fuzzing技术。LibFuzzer通过将随机输入提供给程序,并监视程序的代码覆盖率来工作。如果新的输入导致了代码覆盖率的增加,那么这个输入就会被保存下来,用于生成未来的输入。
例如,你可以创建一个LLVMFuzzerTestOneInput函数,这个函数接受一个指向输入数据的指针和一个表示数据大小的参数。如下所示:
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
{
/* Run your code on data */
OHOS::NetManagerStandard::NetDiagGetSocketInfoFuzzTest(data, size);
OHOS::NetManagerStandard::NetDiagGetRouteTableFuzzTest(data, size);
OHOS::NetManagerStandard::NetDiagUpdateInterfaceConfigFuzzTest(data, size);
OHOS::NetManagerStandard::NetDiagSetInterfaceActiveFuzzTest(data, size);
OHOS::NetManagerStandard::NetDiagGetInterfaceConfigFuzzTest(data, size);
OHOS::NetManagerStandard::NetDiagPingFuzzTest(data, size);
return 0;
}
这样,当你运行LibFuzzer时,它会自动生成一些随机的输入,然后调用LLVMFuzzerTestOneInput函数,LLVMFuzzerTestOneInput函数再调用你的测试函数,这样就完成了一次fuzz测试。
extern “C” 是一个语言链接修饰符,用于指定函数按照 C 语言的链接规则进行编译和链接。在 C++ 中,函数默认使用 C++ 的链接规则,这意味着函数名称会经过名称修饰(name mangling)以支持函数重载和其他 C++ 特性。
在给定的代码中,extern “C” 修饰符用于声明 LLVMFuzzerTestOneInput 函数,以确保它按照 C语言的链接规则进行编译和链接。这是因为该函数是用于模糊测试的回调函数,通常由模糊测试框架调用。模糊测试框架通常使用 C 语言编写,因此需要确保回调函数按照 C 语言的链接规则进行处理。
通过使用 extern “C” 修饰符,可以确保函数名称不会经过名称修饰,从而使模糊测试框架能够正确地调用该函数。这样可以确保 C++代码与 C 代码进行正确的交互,并避免由于链接规则不匹配而导致的问题。