syzkaller 在 FreeBSD 上的内核模糊测试:主机准备、KCOV 内核构建与 bhyve/QEMU/GCE 部署全解
测试操作系统网络安全【免费下载链接】syzkallersyzkaller is an unsupervised coverage-guided kernel fuzzer项目地址https://gitcode.com/gh_mirrors/syz/syzkaller点击查看免费下载本文围绕 syzkaller 官方的 FreeBSD 文档展开完整覆盖在 FreeBSD 或 Linux 主机上搭建模糊测试环境的全部步骤安装依赖、构建syz-manager与syz-executor、下载并扩容快照镜像、编译启用 KCOV 的定制内核、配置 bhyve 的 ZFS 快照与桥接网络最后给出freebsd.cfg的完整配置模板。读完本文你可以独立把一台 amd64 FreeBSD 内核 VM 纳入 syzkaller 的覆盖率引导模糊测试流程并从源码层面理解每个配置项背后的实现。1. syzkaller 对 FreeBSD 的支持现状syz-manager是 syzkaller 中负责管理目标 VM 的组件它运行在主机系统上自动创建、启动和销毁共享同一镜像文件的 VM。针对 FreeBSD 目标当前支持三种虚拟化后端bhyveFreeBSD 原生 Hypervisor、QEMU和GCEGoogle Compute Engine三种模式下都有一些必须遵循的通用步骤。从源码结构看FreeBSD 已被纳入 syzkaller 的一等目标体系sys/targets/targets.go 中为 FreeBSD 定义了 amd64、arm64、i386、riscv64 四种架构交叉编译时统一使用--targetxxx-unknown-freebsd14.0的 clang 目标Makefile 中targets目标同样列出了TARGETOSfreebsd的四种架构组合sys/freebsd/init.go 通过targets.MakeUnixNeutralizer与MakePosixMmap为 FreeBSD 注册了 Unix 风格的程序中立化器neutralizer用于在执行出错的程序时将其“中和”为可继续运行的形式sys/freebsd/ 目录下共有 18 份系统调用描述文件.txt 对应的.txt.const常量文件覆盖socket、socket_inet、socket_inet6、socket_inet_tcp、socket_inet_udp、socket_inet_sctp、kqueue、pf、vnet、capsicum等子系统。其中 SCTP 的描述尤为完整sys/freebsd/socket_inet_sctp.txt 定义了sendmsg$inet_sctp以及cmsghdr_sctp_init、cmsghdr_sctp_sndrcv、cmsghdr_sctp_sndinfo等全部 SCTP socket 控制消息结构共 548 行——这与后文提到的漏洞发现分布高度吻合。2. 设置主机2.1 使用 FreeBSD 作为主机若希望开箱即用地构建 syzkaller主机应使用较新的 FreeBSD 13.0-CURRENT或更新版本旧版本可用但需要手动调整。通过 pkg 安装所需依赖# pkg install bash gcc git gmake go golangci-lint llvm当使用 bhyve 作为 VM 后端时还需安装 DHCP 服务器# pkg install dnsmasq检出 syzkaller 源码后本仓库即可在仓库根目录执行$ cd syzkaller $ gmake构建完成后syz-manager可执行文件位于bin/目录下。2.2 使用 Linux 作为主机在 Linux 主机上构建 Go 侧二进制时指定TARGETOSfreebsd即可交叉编译make manager fuzzer execprog TARGETOSfreebsd而 C 语言编写的syz-executor无法在 Linux 上交叉编译出可直接运行的成品需要把executor/*目录拷贝到一台 FreeBSD 机器上构建c executor/executor.cc -o syz-executor -O1 -lpthread -DGOOS_freebsd1 -DGOARCH_amd641 -DGIT_REVISION\CURRENT_GIT_REVISION\然后将编译出的二进制拷回 Linux 主机的bin/freebsd_amd64/目录。-DGOOS_/-DGOARCH_宏与 Makefile 中自动构建 executor 时使用的参数一致它们决定 executor 中按 OS/架构条件编译的代码路径。3. 设置 FreeBSD VM3.1 获取并扩容快照镜像最简单的起点是 FreeBSD 官方快照站点提供的 VM 镜像VM-IMAGES/14.0-CURRENT/amd64目录QEMU 使用 QCOW2 格式镜像GCE 或 bhyve 使用 raw 格式镜像。同时需要一份 FreeBSD 内核源码放在 VM 的/usr/src下。由于 VM 原始镜像磁盘偏小需要在启动前扩容到 15G# truncate -s 15G $IMAGEFILE3.2 编译启用 KCOV 的定制内核要在 FreeBSD 上启用 KCOV 覆盖率采集必须编译定制内核。这一步最方便在主机上完成因为要操作的是 VM 的磁盘镜像文件。启动 VM 之前先在主机上为镜像文件创建内存设备并挂载其数据分区# mdconfig -a -f $IMAGEFILE # mount /dev/md0p4 /mnt这会为主机创建一个指向 VM 镜像文件的内存设备从而可以把定制内核安装进 VM 的分区。获取当前 FreeBSD 开发源码# pkg install git # git clone --depth1 --branchmain https://github.com/freebsd/freebsd-src /usr/src创建 syzkaller 专用的内核配置文件并构建新内核# cd /usr/src/sys/amd64/conf # cat __EOF__ SYZKALLER include ./GENERIC ident SYZKALLER options COVERAGE options KCOV __EOF__ # cd /usr/src # make -j $(sysctl -n hw.ncpu) KERNCONFSYZKALLER buildkernel # make KERNCONFSYZKALLER installkernel DESTDIR/mnt两个options是模糊测试能否工作的关键COVERAGE让编译器为每条基本块插入计数KCOV则启用内核中的/dev/kcov设备与KCOV_REMOTE_*远端采集接口。这一点可以从 executor 的源码得到印证——executor/executor_bsd.h 中 executor 通过open(/dev/kcov, O_RDWR)打开设备再用KCOV_IOC_REMOTE_ATTACH附加到KCOV_REMOTE_COMMON子系统最后以KCOV_MODE_TRACE_CMP或KCOV_MODE_TRACE_PC模式调用KIOENABLE开启 traceKCOV_REMOTE_COMMON正是 FreeBSD 内核为 syzkaller 定制的内核侧覆盖率通道没有上面两个内核选项/dev/kcov根本不存在syz-manager的machine check输出里kcovtrue也就不可能出现。启动 VM 前别忘了卸载# umount /mntmd 设备可以保留供后续复用否则用# mdconfig -d -u 0销毁它。3.3 首次引导与网络配置先用 QEMU 手工启动一次 VM$ qemu-system-x86_64 -hda $IMAGEFILE -nographic -net user,host10.0.2.10,hostfwdtcp::10022-:22 -net nic,modele1000引导菜单出现后进入 loader 提示符执行set consolecomconsole和boot让内核控制台输出走串口后面 syzkaller 需要通过串口捕获 panic 信息。登录 root 后写入/boot/loader.conf# cat __EOF__ /boot/loader.conf autoboot_delay-1 consolecomconsole __EOF__autoboot_delay-1使引导不再停在菜单这是 VM 自动化必需的配置——对照 vm/bhyve/bhyve.go 可以看到bhyve 后端在bhyveload参数中同样传入-e autoboot_delay0原理相同。VM 启动后/etc/rc.d/growfs应已自动扩展文件系统否则手动执行# /etc/rc.d/growfs onestart用uname -i确认输出SYZKALLER验证新编译的内核已生效。然后配置网络与 SSH允许从主机远程访问 VM# sysrc sshd_enableYES # sysrc ifconfig_DEFAULTDHCP如果计划以 root 运行 syscall executor需要在/etc/ssh/sshd_config中加入PermitRootLogin without-password否则用adduser创建一个普通用户并安装 ssh key。无论哪种方式都要验证可以从主机 SSH 进入 VM。注意bhyve 后端目前要求必须使用 root 用户。4. bhyve 后端的额外准备使用 bhyve 时主机还需要以下额外步骤。4.1 ZFS 数据集提供快照能力bhyve 目前不支持磁盘镜像快照必须借助 ZFS 实现等价功能。创建一个 ZFS 数据集并拷贝 VM 镜像该数据集同时也可以存放 syzkaller 的 workdir。例如对于挂载在/data的 zpooldata# zfs create data/syzkaller # cp FreeBSD-13.3-CURRENT-amd64.raw /data/syzkaller源码印证了这一点vm/bhyve/bhyve.go 中Create()首先通过zfs get -H -o value mountpoint查询数据集挂载点然后依次执行zfs snapshot和zfs clone——每个 bhyve VM 实例都运行在基础镜像快照的一次克隆上VM 重启时快照会被重新创建从而保证每次启动都从“干净”的镜像状态开始Close()时再zfs destroy -R清理快照。4.2 桥接网络与 DHCP配置 VM 实例的桥接网络和 DHCP。需要说明的是在 FreeBSD 14.1 及 15.0-CURRENT 上这一步已不再必要因为 bhyve 现在支持基于 libslirp 的用户态网络与 QEMU 后端类似。对应地vm/bhyve/bhyve.go 中当未配置 bridge 时bhyve 的 virtio-net 设备直接使用slirp,hostfwdtcp:127.0.0.1:port-:22并在启动后通过 vmimpl.WaitForSSH 在 localhost 的转发端口上等待 SSH 就绪配置了 bridge 时才改为在hostip上直连 VM 的 22 端口。旧版本主机上配置桥接的步骤如下# ifconfig bridge create bridge0 # ifconfig bridge0 inet 169.254.0.1 # echo dhcp-range169.254.0.2,169.254.0.254,255.255.255.0 /usr/local/etc/dnsmasq.conf # echo interfacebridge0 /usr/local/etc/dnsmasq.conf # sysrc dnsmasq_enableYES # service dnsmasq start # echo net.link.tap.up_on_open1 /etc/sysctl.conf # sysctl net.link.tap.up_on_open1要让桥接网络在每次系统启动时自动配置向/etc/rc.conf追加# cloned_interfacesbridge0 tap0 # ifconfig_bridge0inet 169.254.0.1 addm tap0 up # ifconfig_tap0up最后确认 bhyve 内核模块已加载# kldload vmm4.3 bhyve 后端如何启动 VM从 vm/bhyve/bhyve.go 的Boot()实现可以看到完整的启动链路bhyveload -c stdio -m mem -d image -e autoboot_delay0 vmName加载内核与 loaderbhyve -H -A -P -c cpu -m mem启动 VM设备拓扑为0:0,hostbridge、1:0,lpc、2:0,virtio-net,netdev、3:0,virtio-blk,image串口用-l com1,stdio接出后台 goroutine 持续读取合并后的控制台输出用正则bound to (([0-9]\.){3}[0-9])解析 dnsmasq 打印的 DHCP 租约 IPparseIP10 分钟内拿不到 IP 即报no IP found启动错误拿到 IP 后进入 SSH 等待阶段超时 10 分钟。该后端的配置结构定义在 vm/bhyve/bhyve.go字段JSON 键含义默认值Bridgebridge网络桥设备名可选空CountcountVM 数量范围 1–128debug 模式强制为 11CPUcpu每个 VM 的 vCPU 数1HostIPhostip桥接网段中的主机 IP空Memmem每个 VM 的内存512MDatasetdataset存放 VM 镜像的 ZFS 数据集必填一个隐含约束是image路径必须位于dataset的挂载点之内否则Create()会直接报image file not contained in dataset错误vm/bhyve/bhyve.go。5. 汇总编写 freebsd.cfg 配置如果前面所有步骤都成功了创建一份freebsd.cfg配置文件按需修改路径{ name: freebsd, target: freebsd/amd64, http: :10000, workdir: /workdir, syzkaller: /gopath/src/github.com/google/syzkaller, sshkey: /freebsd_id_rsa, sandbox: none, procs: 8, }各字段含义name为任务名target指定目标 OS/架构必须与构建产物所在bin/target/目录一致http是 manager 对外暴露 HTTP 接口的监听地址workdir是存放 corpus、crash 等状态的工作目录bhyve 下建议放在 ZFS 数据集里以便快照syzkaller是仓库根路径sshkey指向用于登录 VM 的私钥sandbox设为none表示 VM 内不做沙箱procs是每个 VM 上并行运行的 executor 进程数。按后端追加不同字段。QEMU 后端image: /FreeBSD-13.0-CURRENT-amd64.qcow2, type: qemu, vm: { count: 10, cpu: 4, mem: 2048 }GCE 后端按需修改存储桶路径image: /FreeBSD-13.0-CURRENT-amd64.raw, type: gce, vm: { count: 10, instance_type: n1-standard-4, gcs_path: syzkaller }bhyve 后端按需修改数据集名与路径image: /data/syzkaller/FreeBSD-13.0-CURRENT-amd64.raw, type: bhyve, vm: { count: 10, hostip: 169.254.0.1, dataset: data/syzkaller }若使用桥接网络需在vm块中补上桥接口名vm: { count: 10, hostip: 169.254.0.1, dataset: data/syzkaller, bridge: bridge0 }6. 启动与验证用以下命令启动syz-manager$ bin/syz-manager -config freebsd.cfg一切正常时应看到类似输出booting test machines... wait for the connection from test machine... machine check: 253 calls enabled, kcovtrue, kleakcheckfalse, faultinjectionfalse, compsfalse executed 3622, cover 1219, crashes 0, repro 0 executed 7921, cover 1239, crashes 0, repro 0 executed 32807, cover 1244, crashes 0, repro 0 executed 35803, cover 1248, crashes 0, repro 0其中machine check一行是环境自检结论kcovtrue说明定制内核的 KCOV 通道已打通compsfalse表示比较值覆盖率未启用随后的executed/cover/crashes/repro行则分别反映累计执行数、累计覆盖基本块数、崩溃数与已最小化复现数。遇到问题时给syz-manager加上-debug标志可以看到完整日志。两个与 FreeBSD 直接相关的实现细节值得一提VM 崩溃进入内核 debugger 时vm/vmimpl/freebsd.go 的DiagnoseFreeBSD会向串口依次写入show registers、show proc、ps、show all locks、show malloc、show uma等 ddb 命令用于把 panic 现场信息采集进报告它同时处理“内核挂死但控制台仍显示登录提示”的情形如果要把 syzkaller 的持续集成组件syz-ci部署在 FreeBSD 主机上开机自启可以直接使用仓库提供的 rc.d 服务脚本 dashboard/config/freebsd/syz-ci-service.sh将其放入/usr/local/etc/rc.d/syz_ci并加执行权限再在/etc/rc.conf中设置syz_ci_enableYES、syz_ci_chdir、syz_ci_flags-config config-freebsd.ci等变量即可脚本通过daemon -f拉起进程、用kill -INT优雅停止。7. 已知局限与后续方向官方文档在 “Missing things” 一节中列出了当前 FreeBSD 支持的缺口值得如实了解系统调用描述质量最初的 FreeBSD 系统调用列表是从 Linux 拷贝而来虽经持续清理但仍需更细致的审计且目前仍缺少不少系统调用描述Linux 兼容层linuxulator尚不支持对 FreeBSD 上的 Linux 兼容子系统做模糊测试ZFS 上的模糊测试缺少在 ZFS 文件系统上运行 FreeBSD 系统的说明主机侧探测pkg/host还未实现自动探测目标支持哪些系统调用/设备内存错误检测器FreeBSD 版的 KASAN/KCSAN 尚缺Linux 侧已有对应能力外部网络/USB 流量注入Linux 上可通过 tun/gadgetfs 向内核注入外部网络与 USB 流量FreeBSD 上实现类似能力有望再挖出一批高影响力漏洞。从成果侧看docs/freebsd/found_bugs.md 记录了 syzkaller 在 FreeBSD 内核上发现并已由 FreeBSD 上游修复的一批真实漏洞集中在网络协议栈SCTP 关联双释放与加锁问题、TCP/UDP 输出路径、IP_HDRINCL原始套接字输入校验、socket option 内存限制、虚拟内存vm_fault_copy_entry对 wired 映射后备文件截断的处理、禁止提前创建 wired superpage 映射以及时钟接口clock_settime过远未来时间导致 panic等方向——这也解释了为什么sys/freebsd/下 SCTP、socket 系列的描述文件最为详尽覆盖率引导的 fuzzer 会在哪里发现漏洞很大程度上取决于描述文件覆盖了哪些接口。赞分享测试操作系统网络安全【免费下载链接】syzkallersyzkaller is an unsupervised coverage-guided kernel fuzzer项目地址https://gitcode.com/gh_mirrors/syz/syzkaller点击查看免费下载相关推荐syzkaller 在 FreeBSD 上的搭建与运行从宿主机配置、内核 KCOV 编译到 bhyve/QEMU/GCE 三后端实战syzkaller 在 FreeBSD 上的搭建与运行从宿主机配置、内核 KCOV 编译到 bhyve/QEMU/GCE 三后端实战 本指南以 docs/fr网络安全开发工具质量保障syzkaller RISC-V64 内核模糊测试搭建指南Debian/Ubuntu 主机 QEMU 虚拟机全流程syzkaller RISC V64 内核模糊测试搭建指南Debian/Ubuntu 主机 QEMU 虚拟机全流程 本文档围绕 syzkaller 官方网络安全开发工具质量保障syzkaller Windows 内核模糊测试支持指南系统调用描述、二进制构建与 GCE 部署syzkaller Windows 内核模糊测试支持指南系统调用描述、二进制构建与 GCE 部署 syzkaller 是一个无监督的、基于覆盖率引导的内核模糊网络安全开发工具质量保障上一篇Foundry单元测试终极指南从基础断言到高级调试技巧下一篇从理论到实战黑马程序员120天区块链开发课程全攻略创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考