- 测试
- 操作系统
- 网络安全
【免费下载链接】syzkaller
syzkaller is an unsupervised coverage-guided kernel fuzzer
syzkaller 是一款无监督的、基于覆盖率引导的内核模糊测试工具。在 Linux 之外,它同样被用于持续 fuzzing 其他操作系统内核,OpenBSD 就是其中的代表性目标。本文以仓库中 docs/openbsd/found_bugs.md 收录的 118 条已修复缺陷清单为核心骨架,结合 syzkaller 的 OpenBSD 部署文档、崩溃报告解析源码、CI 内核配置与系统调用描述文件,系统讲解这些漏洞的分布规律、缺陷模式、从崩溃现场到上游修复的完整链路,以及如何在自己的环境中复现并跟进此类缺陷。
一、syzkaller 如何覆盖 OpenBSD:一条从部署到持续 fuzzing 的链路
在分析缺陷清单之前,先理解 syzkaller 在 OpenBSD 上是如何跑起来的。仓库中的 docs/openbsd/setup.md 给出了完整的 OpenBSD host + OpenBSD VM + amd64 内核的部署指南,其核心要点如下。
1. 构建与依赖
OpenBSD 上运行 syzkaller 要求 host 运行-current版本,并安装以下依赖:
# pkg_add git gmake go为了能够让 reproducer(复现程序)正常工作,还需要从 ports 安装 GCC:
# pkg_add gcc随后克隆仓库并编译:
$ git clone https://github.com/google/syzkaller $ cd syzkaller $ gmake all2. 编译带 kcov 的内核
OpenBSD 的 fuzzing 依赖内核中的 kcov(4) 伪设备来提供覆盖率反馈。文档给出的做法是在GENERIC内核配置基础上叠加一个名为SYZKALLER的定制配置:
$ cd /sys/arch/amd64 $ cat <<EOF >conf/SYZKALLER include "arch/amd64/conf/GENERIC" pseudo-device kcov 1 EOF $ cp -R compile/GENERIC compile/SYZKALLER $ make -C compile/SYZKALLER obj $ make -C compile/SYZKALLER config $ make -C compile/SYZKALLER这一手工流程与仓库中的自动化构建实现完全对应:在 pkg/build/openbsd.go 中,build()会以SYZKALLER作为内核配置名,把params.Config写入sys/arch/<arch>/conf/目录,随后依次执行clean、obj、config、all四个 make 目标,最后把obj/bsd复制为kernel、obj/bsd.gdb复制为符号文件,并把userspace目录下的image与key一并拷入输出目录。从源码结构看,bsd.gdb正是后续崩溃报告符号化所依赖的内核对象文件(见 sys/targets/targets.go 中 OpenBSD 目标的KernelObject: "bsd.gdb")。
3. 创建 VM
为了避免以 root 运行 syzkaller,文档建议通过 vmd(8) 允许非 root 用户创建 VM,/etc/vm.conf示例如下:
vm "syzkaller" { disable disk "/dev/null" local interface owner $USER allow instance { boot, disk, memory } }随后用vmctl创建磁盘镜像并安装系统:
$ vmctl create -s 4G "qcow2:$VMIMG" $ vmctl start -c -t syzkaller -b /bsd.rd -d "$VMIMG" syzkaller-1安装过程中偏离默认值的回答只有两项:root 密码、是否允许 root SSH 登录(填yes)。之后重启 VM、拷贝 SSH 公钥,并可选择性关闭库 ASLR 以加快启动:
$ vmctl stop -w syzkaller-1 $ vmctl start -c -t syzkaller -d "$VMIMG" syzkaller-1 $ ssh "root@100.64.${VMID}.3" 'cat >~/.ssh/authorized_keys' <$SSHKEY.pub $ ssh "root@100.64.${VMID}.3" 'echo library_aslr=NO >>/etc/rc.conf.local'4. syz-manager 配置
最终通过syz-manager拉起整个 fuzz 实例,配置openbsd.cfg完整示例如下:
$ cat openbsd.cfg { "name": "openbsd", "target": "openbsd/amd64", "http": ":10000", "workdir": "$HOME/go/src/github.com/google/syzkaller/workdir", "kernel_obj": "/sys/arch/amd64/compile/SYZKALLER/obj", "kernel_src": "/", "syzkaller": "$HOME/go/src/github.com/google/syzkaller", "image": "$VMIMG", "sshkey": "$SSHKEY", "sandbox": "none", "procs": 2, "type": "vmm", "vm": { "count": 4, "mem": 512, "kernel": "$KERNEL", "template": "syzkaller" } } $ ./bin/syz-manager -config openbsd.cfg其中type: "vmm"表示使用 OpenBSD 自带的 vmm 虚拟化后端(对应 vm/vmm/vmm.go),target: "openbsd/amd64"对应 sys/targets/targets.go 中定义的 OpenBSD amd64 目标:指针宽度 8、页大小 4K、编译参数-m64 -static -lutil。源码注释特别指出 OpenBSD 默认已启用 PIE,因此无需-static-pie;同时通过NeedSyscallDefine为__tfork、__thrsleep、__semctl、__thrwakeup、__threxit、__thrsigdivert、__getcwd、__set_tcb、__get_tcb等 OpenBSD 私有系统调用显式生成__NR_*定义,这是 OpenBSD 与 Linux 在系统调用接口上的关键差异之一。
5. 目标系统调用面
OpenBSD 目标被 fuzz 的系统调用面由 sys/openbsd 目录下的描述文件定义,覆盖 40 余个文件:sys.txt(通用系统调用)、fs.txt、mm.txt、ipc.txt、kqueue.txt、sysctl.txt、socket.txt、socket_inet.txt、socket_inet6.txt、vnet.txt(pf 防火墙接口),以及dev_bpf.txt、dev_vmm.txt、dev_vnd.txt、dev_pf.txt、wscons.txt、tty.txt等设备接口。以 sys/openbsd/dev_vmm.txt 为例,它定义了针对/dev/vmm的openat$vmm以及VMM_IOC_CREATE、VMM_IOC_RUN、VMM_IOC_INTR、VMM_IOC_READREGS、VMM_IOC_RESETCPU、VMM_IOC_TERM、VMM_IOC_WRITEREGS等一整套 ioctl 及其参数结构;sys/openbsd/dev_vnd.txt 则定义了openat$vnd与VNDIOCGET/VNDIOCSET/VNDIOCCLR等磁盘设备控制接口。这些描述文件与下文漏洞清单中的 vmm(4)、vnd(4) 缺陷高度对应——正是这些接口被持续 fuzzing,才暴露出相应问题。
二、报告链路:从崩溃现场到上游修复
found_bugs.md开头明确说明:最新发现的缺陷由 syzbot 报告到syzkaller-openbsd-bugs邮件列表,并展示在 syzkaller 公共 dashboard 的 OpenBSD 页面上;清单按"新在前、旧在后"排序。这是 syzkaller 在 OpenBSD 上的完整报告闭环,其中三个环节可以在仓库源码中得到直接印证。
1. 崩溃现场提取:ddb 诊断命令
当内核 panic 或挂起时,syzkaller 的 VM 层会向串口控制台发送一组 ddb(内核调试器)命令,见 vm/vmimpl/openbsd.go:
set $lines = 0 # 关闭分页 set $maxwidth = 0 # 关闭行续接 show panic trace show registers show proc ps show all locks show malloc show all pools machine ddbcpu 0 # 逐个 CPU 抓取 trace trace machine ddbcpu 1 trace这些命令的输出(如show panic的 panic 消息、trace的调用栈、show all locks的锁状态、show all pools的池分配器状态)正是后续崩溃报告解析的原始输入。可以看到,诊断命令与found_bugs.md中缺陷标题所反映的问题类型(锁问题、内存破坏、池/分配器完整性)一一对应。
2. 报告解析与归类:pkg/report/openbsd.go
崩溃输出会被 pkg/report/openbsd.go 中的 oops 模式库解析并提取出规范的标题。这套模式与清单中的缺陷标题存在大量对应关系:
| 解析模式(源码正则) | 对应缺陷类型(found_bugs.md 实例) |
|---|---|
panic: ...+ddb{}> show panic | 各类 panic 型缺陷,如 wsmux(4) 的 use-after-free |
panic: kernel diagnostic assertion (.+) failed | kqueue: too strict assertion、dt(4): too strict assertion、VOP_LOCK(9): too strict lockcount assertion |
panic: attempt to execute user address | poll: execution of address 0x0(内核态执行用户地址) |
panic: unhandled af | pf(4): unhandled address families |
panic: (kqueue|knote)... | 全部 kqueue 相关缺陷(missing locking、interrupt race、use-after-free、NULL deref) |
panic: receive ([0-9][a-z]*): | recvmsg/recv系列缺陷 |
lock order reversal: | vmm(4): lock ordering problem、socketpair: lock ordering problem、setrlimit: lock ordering problem in mi_switch() |
witness: thread ... exiting with locks held/witness: userret: returning with ... locks held | pf(4): sleeping with locks held、各类 missing locking |
uvm_fault( | 空指针解引用类缺陷(uvm(9): NULL pointer dereference等) |
kernel: page fault trap | 空指针解引用类缺陷 |
panic: Data modified on freelist/pool_do_put: double pool_put | use-after-free / double free 类缺陷(malloc/pool 完整性校验触发点) |
值得一提的细节:kernel:模式下的ignores列表里包含了reorder_kernel正则——这是因为 syzkaller 的 OpenBSD 镜像构建脚本 tools/create-openbsd-vmm-worker.sh 会删除/usr/libexec/reorder_kernel并用true占位,避免启动时的内核重排(reorder)干扰覆盖率与符号化。此外,符号化部分使用at func+0x...与 witness 风格#N func+0x...两种正则定位内核符号,再借助bsd.gdb与 addr2line 补齐文件名与行号(含内联帧标记),对应的单元测试见 pkg/report/openbsd_test.go,覆盖了普通帧、内联帧、缺失符号与 witness 格式等场景。
3. syzbot 交互与修复闭环
found_bugs.md指向的 dashboard 与邮件列表,其运行机制由 docs/syzbot.md 说明:syzbot 会持续 fuzz 各内核分支,自动把带 reproducer 的缺陷报告到内核邮件列表;开发者修复时应在提交中加入Reported-by标签,或通过回复邮件中的#syz fix: commit-title命令把修复提交关联到缺陷;#syz dup/#syz undup用于合并/拆分相似报告,#syz invalid用于标记一次性误报,#syz test: repo branch可以请求 syzbot 在指定分支上测试补丁。只有当修复提交到达所有被跟踪的内核构建时,缺陷才会被关闭。
三、缺陷清单全景:118 条已修复缺陷
found_bugs.md共收录 118 条缺陷(含 4 个关联的 OpenBSD errata 补丁),从链接中的邮件时间戳看,跨度覆盖 2018 年年中到 2021 年年底,按时间倒序排列。按标题文本归类(一条可能涉及多个方面,以下统计仅供参考):
| 缺陷模式 | 代表性条目 |
|---|---|
| 空指针解引用(NULL pointer dereference,约 14 条) | pf(4)、uvm(9)、multicast(4)、inet6(4)、route(4)、pflog(4)、wsmux(4)、unveil、open/fchown/ftruncate(cloned device)、kqueue、poll(执行地址 0x0)、ioctl(mrt_ioctl) |
| use-after-free(约 12 条) | pf(4)、wsmux(4)×4、shmctl×2、ip6(4) multicast route、semop、fcntl(lf_findoverlap)、kqueue(kqueue_close) |
| double free(6 条) | wscons(4)、mlock、if_addgroup(9)、recvmsg×2、flock |
| 越界访问(3 条) | vmm(4) out-of-bounds read、rtable(4) rtable_satoplen()、wsmux_do_ioctl() |
| 锁问题(missing locking / lock ordering / wrong lock flags,约 18 条) | vmm(4)×4、vnd(4)、kqueue、socketpair、sosplice(9)、pf(4)(NET_UNLOCK、pfsync_state_import)、VOP_LOCK(9)、wsmux(4)、read、setrlimit(mi_switch)、unveil(VOP_UNLOCK)、kernel(page fault) |
| 竞态(约 5 条) | pppx(4)(部分初始化 softc 并发访问)、kcov(4)(remote section 移除竞态)、kqueue(interrupt race)、tun(4)(接口创建竞态)、acct(vn_close race) |
| 睡眠与状态(约 5 条) | sysctl、vnd(4)(state changed after sleeping)、pf(4)(sleeping with locks held)、tty(4)(close 时无限睡眠)、recv(睡眠中 mbuf 队列异常增长) |
| 输入校验(lenient validation / negative input / bounds,约 19 条) | pf(4)×3、inet6(4)×2、sysctl×3、mmap、ioctl×3、sendto×4、bpf(4)×2、write、wsmux_do_ioctl、mprotect(uvm_map_protect) |
| 整数溢出/回绕(4 条) | vmm(4) VM 计数溢出、bpf(4) 无符号回绕、setsockopt(ip_pcbopts)、shutdown(unp_internalize) |
| 栈溢出/递归(3 条) | sosplice(9)×2(stack overflow、unbound recursion)、rtable_walk(9)(递归耗尽栈) |
| 断言过严(3 条) | dt(4)、kqueue、VOP_LOCK(9) |
| 错误路径副作用(3 条) | shmat(分配失败应传播错误而非 panic)、diskmap(4)、ftruncate |
| 逻辑/状态/结构(约 12 条) | pppx(4) variable confusion、vnd(4) 设备意外嵌套、pf(4) 重叠分片处理、pty(4) vnode 回归、inet6(4) 修改静态路由、pf(4) unhandled af、uvm_share 偏移计算、vmm(4) 错误 VM 内存结构、unveil 计数、ip6 ECN、setsockopt mbuf padding、getsockopt switch fall-through |
| 资源/引用/其他(约 9 条) | tun(4) 泄漏设备引用、bpf(4) 缺引用计数、wsmux(4) 限制设备数量、pflog(4) 构造损坏 mbuf、mbuf(9) 修改只读 mbuf、switch(4) mbuf 损坏波及多个系统调用、pckbc(4) 命令队列损坏、vmm(4) IPI 上下文调用 printf |
四、高发子系统剖析:为什么是它们
清单呈现了非常集中的子系统分布,这直接反映了 syzkaller 持续 fuzzing 的接口范围(与 sys/openbsd 描述文件一一对应)。
1. pf(4)/pflog(4):数据包过滤栈(12 条)
pf 家族是清单中单子系统缺陷数量最多的,覆盖 NULL deref、除零、use-after-free、重叠分片处理错误、pfsync_state_import()持锁调用、缺失NET_UNLOCK()、持锁睡眠、端口范围与pf_rulecopyin()校验宽松、未处理的地址族、pflog 构造损坏 mbuf、pflog NULL deref 等 12 条。其中pf(4): incorrect handling of overlapping fragments还关联了 ERRATA-68-014 与 sys/openbsd/dev_pf.txt 中。
2. vmm(4):虚拟化 ioctl 面(10 条)
vmm 相关缺陷共 10 条,以锁问题为主:4 次 missing locking、1 次 lock ordering problem,另有 out-of-bounds read、错误的虚拟内存结构类型、VM 数量计数溢出、IPI 上下文调用printf()。其 fuzz 入口正是 sys/openbsd/dev_vmm.txt 定义的那组VMM_IOC_*ioctl——从VMM_IOC_CREATE到VMM_IOC_RUN、VMM_IOC_READREGS的一整套参数结构都被反复构造与调用,vmm 作为较新的虚拟化子系统,其锁层次与状态机成为天然的缺陷富矿。
3. wsmux(4):窗口系统多路复用设备(11 条)
wsmux 系列 11 条缺陷中,use-after-free 出现 5 次(含 3 次wsmux_do_ioctl()内 UAF/OOB),另有缺失锁、错误锁标志、NULL deref 竞态、限制允许设备数量、拒绝不当命令等。wsmux_do_ioctl()是典型的"复用同一个 ioctl 处理函数 + 可变设备状态"模式,生命周期管理稍有不慎就会产生 UAF,是面向设备复用逻辑的高频缺陷点。
4. 网络栈:inet6/ip6/route/rtable/multicast(11 条)
IPv6 与路由相关缺陷集中在地址配置与扩展头处理:in6_ioctl_change_ifaddr()与ip6_pullexthdr()的宽松校验、修改静态路由、多播路由 use-after-free、multicast NULL deref、route NULL deref、rtable_satoplen()越界读、rtable_walk(9)递归耗尽栈等。这类"从用户态可控输入到内核数据结构"的路径,正是 syzkaller 描述语言(如 sys/openbsd/socket_inet6.txt)着重建模的对象。
5. sysctl 与终端/显示设备
sysctl出现 3 条宽松校验缺陷(整数值、net.inet.tcp.synbucketlimit等),其 fuzz 入口在 sys/openbsd/sysctl.txt——该文件为ddb、fs、hw、kern、machdep、net_inet_*、net_mpls等每个 MIB 分支都定义了独立变体;终端/显示类(wscons、pty、tty、pckbc)共 6 条,涵盖 double free、vnode 回归、昂贵 retyping 导致的机器锁死、close 时无限睡眠、命令队列损坏、console 重定向导致的地址 0x0 执行。
五、调试内核配置如何放大缺陷
found_bugs.md中大量"lock ordering / missing locking / too strict assertion / double free"类缺陷能被稳定捕获,离不开 syzkaller CI 为 OpenBSD 内核叠加的调试选项。仓库中 dashboard/config/openbsd 目录保存了这些配置:
- 单核配置
sp(dashboard/config/openbsd/sp)在GENERIC基础上启用kcov伪设备,并打开KQUEUE_DEBUG、SPLASSERT_WATCH、VFSLCKDEBUG——前者专门校验 kqueue 内部状态(对应清单中 5 条 kqueue 缺陷),后两者把 spl 断言与 VFS 锁断言变为可见的 panic; - 多核配置
mp(dashboard/config/openbsd/mp)基于GENERIC.MP,进一步启用WITNESS、WITNESS_LOCKTRACE、WITNESS_WATCH。WITNESS 是 OpenBSD 的锁顺序验证器,正是它把lock order reversal这类报告变成了可解析的稳定输出——与 pkg/report/openbsd.go 中lock order reversal:的解析模式一一对应; - CI 编排
config.ci(dashboard/config/openbsd/config.ci)运行三个实例:main(8 procs、10 台 e2-small GCE VM)、multicore(e2-highcpu-2,多核镜像)、setuid(sandbox: "setuid",即用 setuid 沙箱运行非 root 实例),均开启覆盖率(cover: true)。镜像构建细节见 tools/create-openbsd-vmm-worker.sh:它生成最小安装镜像、设置串口启动、关闭 SSH 密码认证、删除reorder_kernel,并用 pkg/build/openbsd.go 中的脚本通过vnconfig/mount把内核与 overlay 文件写入 FFS 镜像。
可以推断:SP 与 MP 两套配置分别对应 OpenBSD 单核与多核两条内核路径,WITNESS 系列选项在 MP 配置中的启用,直接解释了清单中大量锁顺序与锁缺失缺陷为何主要反映在多核场景。
六、复现与跟进:把 118 条缺陷变成自己的实战样本
对于想要深入研究的读者,found_bugs.md提供了一条完整的实践路径:
- 本地搭建并复现:按 docs/openbsd/setup.md 在
-currentOpenBSD 主机上编译带 kcov 的SYZKALLER内核、配置 vmd、创建 VM,并用syz-manager拉起实例;随后可用syz-execprog运行 syzkaller 程序,用syz-prog2c把 syzkaller 程序转换为 C 源码(参见 docs/executing_syzkaller_programs.md)。 - 阅读修复提交:清单中每条缺陷都对应 OpenBSD CVS 邮件列表中的修复提交存档(如
pppx(4): variable confusion、wscons(4): double free),按标题即可检索到具体的 diff,观察 OpenBSD 维护者如何加锁、补校验或修正状态机。 - 核对 errata 补丁:4 条缺陷被同步为已发布版本的 errata,包括
pf(4)重叠分片(ERRATA-68-014)、setsockopt/ip_pcbopts()整数溢出(ERRATA-64-010)、recv睡眠中 mbuf 队列异常增长(ERRATA-64-009)、shutdown/unp_internalize()整数溢出(ERRATA-64-006)。这些补丁可从 OpenBSD 官方补丁仓库获取,是研究"fuzz 发现的缺陷如何回流到稳定分支"的最佳样本。 - 接入 syzbot 流程:通过 dashboard 查看缺陷状态,在修复提交中携带
Reported-by标签,或按 docs/syzbot.md 使用#syz fix/#syz dup/#syz invalid/#syz test与 syzbot 交互,验证修复并闭环缺陷。
七、结语
从found_bugs.md的 118 条缺陷可以看出,syzkaller 在 OpenBSD 上的持续 fuzzing 并非只产出零散的崩溃报告,而是形成了一条可复用的质量反馈链路:带调试选项(WITNESS、KQUEUE_DEBUG、SPLASSERT_WATCH)的内核配置放大缺陷、vmm/kcov 提供可扩展的 fuzz 基础设施、ddb 诊断命令 + 报告解析器把崩溃现场提炼为规范标题、syzbot 把缺陷推送到邮件列表与 dashboard 并跟踪修复直至闭环。缺陷分布(pf、vmm、wsmux、IPv6 栈的高占比)同时也为 OpenBSD 开发者划出了最需要加固的代码区域。对于任何希望在自己维护的内核上建立同类 fuzz 体系、或通过历史缺陷清单学习内核漏洞模式的读者,这份清单连同仓库中的部署、解析与 CI 配置,都是一份可直接对照研读的实战材料。
- 测试
- 操作系统
- 网络安全
【免费下载链接】syzkaller
syzkaller is an unsupervised coverage-guided kernel fuzzer
相关推荐
syzkaller 发现的 OpenBSD 内核缺陷全清单:从模糊测试报告到内核修复
syzkaller 发现的 OpenBSD 内核缺陷全清单:从模糊测试报告到内核修复 导读 :本文完整解析 syzkaller 仓库中 docs/openbsd
网络安全开发工具质量保障syzkaller Linux 内核缺陷台账全解析:从 found_bugs.md 看 510 个已发现漏洞的类型分布与工具链支撑
syzkaller Linux 内核缺陷台账全解析:从 found_bugs.md 看 510 个已发现漏洞的类型分布与工具链支撑 本指南以仓库中 docs/l
测试操作系统网络安全syzkaller 在 FreeBSD 上发现的内核漏洞全记录:40 个修复提交、覆盖引导机制与 SCTP 网络栈缺陷模式分析
syzkaller 在 FreeBSD 上发现的内核漏洞全记录:40 个修复提交、覆盖引导机制与 SCTP 网络栈缺陷模式分析 本文基于 syzkaller 仓
测试操作系统网络安全
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考