SurrealDB 如何配置 cargo-fuzz 构建并运行 fuzz_executor 模糊测试
2026/9/17 14:41:55 网站建设 项目流程

SurrealDB 如何配置 cargo-fuzz 构建并运行 fuzz_executor 模糊测试

【免费下载链接】surrealdbA scalable, distributed, collaborative, document-graph database, for the realtime web项目地址: https://gitcode.com/GitHub_Trending/su/surrealdb

SurrealDB 仓库在 fuzz/ 目录下维护了一组由 cargo-fuzz 管理的模糊测试 harness。其中fuzz_executor是面向 SQL 执行器(executor)的 harness:它把一段随机生成、以;分隔的 SurrealQL 命令逐条投递给内存数据源(Datastore::new("memory"))执行,用模糊输入触发解析与执行链路上的崩溃。本文的目标是在本地完成这条链路:安装 nightly 与 cargo-fuzz,构建fuzz_executor,列出并运行它,以及按需启用多进程并行和字典文件加速。

准备条件:nightly 工具链与 cargo-fuzz

fuzz/README.md 明确列出两项前置要求:

  • 安装 nightly 编译器。原因是收集代码覆盖反馈(code-coverage feedback)是高性能 fuzzing 的关键需求,而当前 stable 版本的 rustc 无法对 fuzz harness 做覆盖插桩,因此必须使用 nightly。
  • 安装 cargo-fuzz。仓库给出的最简安装命令是:
cargo +nightly install cargo-fuzz

注意所有后续命令都通过cargo +nightly前缀调用,确保使用的是 nightly 而非 stable 工具链。

另外,仓库根目录的 rust-toolchain.toml 将稳定构建固定在 channel1.91,而rust-toolchain.nightly文件记录了nightly-2025-08-07。fuzz/README.md 只要求"安装 nightly",未强制某一具体 nightly 版本;如果cargo +nightly无法解析,说明本机 rustup 尚未安装过 nightly 通道,需要先执行rustup toolchain install nightly

理解 --fuzz-dir 参数:为什么所有命令都带它

fuzz 项目是独立于主 workspace 的:fuzz/Cargo.toml 中声明了

# Prevent this from interfering with workspaces [workspace] members = ["."]

即它是自带[workspace]的独立包,不在仓库根 Cargo.toml 的 workspace members 列表中。因此在仓库根目录下操作时,每条cargo fuzz命令都要用--fuzz-dir ./显式指定 fuzz 项目所在目录。fuzz 包自身依赖surrealdb-core(featurekv-memarbitrary)与surrealdb-types(featurearbitrary),均通过相对路径../surrealdb/core../surrealdb/types引用,所以必须在完整仓库内运行,不能只拷贝fuzz/目录。

构建 fuzz_executor

在仓库根目录执行(fuzz/README.md 给出的原始命令):

cargo +nightly fuzz build --fuzz-dir ./ fuzz_executor

默认构建会带调试信息并以-O3(最高优化级别)编译。README 同时说明这适合正式 fuzzing;优化级别直接影响运行速度。

如果只是想复现已找到的 crash,README 建议改用无优化构建,可以显著加快编译时间(fuzzing 运行约慢 10 倍,但复现单个 crash 仍然足够快)。在命令中加上-D

cargo +nightly fuzz build -D --fuzz-dir ./ fuzz_executor

fuzz_executor外,fuzz/Cargo.toml 还注册了fuzz_sql_parserfuzz_structured_executorfuzz_format三个 harness(见 fuzz/fuzz_targets/),构建命令形式相同,只需替换最后的 harness 名。

列出并运行 fuzzer

构建成功后,先列出可用的 fuzz harness 作为构建成功的验证方式:

cargo +nightly fuzz list --fuzz-dir ./

输出中应能看到fuzz_executor(以及其余已注册 harness),说明 harness 已正确构建。

然后运行:

cargo +nightly fuzz run --fuzz-dir ./ fuzz_executor

该命令以 libFuzzer 的默认模式运行,即单进程单线程。

加速:多进程并行与字典文件

README 给出了一个加速版本,利用全部 CPU 核心并加载 harness 专属的字典文件。README 原文保留了#FUZZ_TARGET#占位符,对本文场景它对应fuzz_executor;替换后命令为:

cargo +nightly fuzz run --fuzz-dir ./ \ fuzz_executor -- -fork=$(nproc) \ -dict=fuzz/fuzz_targets/fuzz_executor.dict
  • --之后的参数直接传给 libFuzzer。
  • -fork=$(nproc):并行 fork 出与本机处理器数量相同的独立 fuzzing 进程。
  • -dict=fuzz/fuzz_targets/fuzz_executor.dict:加载字典文件。该文件(见 fuzz/fuzz_targets/fuzz_executor.dict)内容是 SurrealQL 关键字(DEFINESELECTRELATEPERMISSIONS等)和大量内置函数名(array::add(string::is_uuid(vector::distance::euclidean(等),帮助生成器更快地产生接近合法 SurrealQL 的输入。字典文件中的注释也提到sleep(被刻意排除,因为它只会拖慢 fuzzer。

结果判断与 harness 行为限制

仓库没有给出固定的"成功输出"样例,判断标准以 fuzz/README.md 的流程为准:fuzz list能列出目标 harness 即构建成功;fuzz run进入持续 fuzzing 循环即运行正常,复现 crash 时按上面-D无优化构建的路径重建后再用该输入复现。

结合 harness 源码 fuzz/fuzz_targets/fuzz_executor.rs,有两点行为限制需要在解读结果时留意:

  • 输入按;切分(split_inclusive),单次输入超过 500 条命令会被直接丢弃(max_commands = 500)。
  • 包含sleep(区分大小写)的命令会被跳过;会话是Session::owner().with_ns("test").with_db("test"),数据源是纯内存的,不持久化任何状态。

fuzz 项目整体不属于仓库主 workspace,构建产物与 corpus 均生成在fuzz/目录内部,不会影响主 workspace 的常规构建。

【免费下载链接】surrealdbA scalable, distributed, collaborative, document-graph database, for the realtime web项目地址: https://gitcode.com/GitHub_Trending/su/surrealdb

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询