github.com/google/syzkaller@v0.0.0-20251211124644-a066d2bc4b02/docs/translations/zh_CN/linux/external_fuzzing_network.md (about) 1 > [!WARNING] 2 > 3 > **请注意,这是社区驱动的官方 syzkaller 文档翻译。当前文档的最新版本(英文版)可在 [docs/linux/external_fuzzing_network.md](/docs/linux/external_fuzzing_network.md) 找到。** 4 5 Linux 内核的外部网络模糊测试 6 ========================================= 7 8 syzkaller 已支持对网络栈的外部模糊测试。 9 这是通过使用 [TUN/TAP](https://www.kernel.org/doc/Documentation/networking/tuntap.txt) 接口来实现的. 10 它允许设置一个虚拟网络接口,并将从外部网络接收到的数据包发送到内核。 11 这触发了真实数据包通过真实网络接口传递的相同路径(除了驱动层)。 12 13 您需要启用 `CONFIG_TUN` 内核配置来开启外部网络模糊测试。 14 关于如何设置虚拟接口,请参考 [executor/common_linux.h](/executor/common_linux.h) 中的 `initialize_tun()` 函数。 15 16 相关模板描述可在 [sys/linux/vnet.txt](/sys/linux/vnet.txt) 中找到。 17 目前有两个系统调用: `syz_emit_ethernet` 和 `syz_extract_tcp_res`。 18 第一个伪系统调用通过虚拟接口向外发送数据包。 19 第二个伪系统调用尝试从外部接收数据包,并从中解析 TCP 序列号,以便在后续的数据包中使用。 20 目前还有很多协议或协议扩展尚未描述,因此非常欢迎补充! 21 22 由于模糊测试可能在同一个虚拟机实例内的多个执行器进程中进行,我们需要一种方式来隔离不同执行器的虚拟网络。 23 目前,这是通过为每个执行器创建一个虚拟接口,并为这些接口分配不同的 MAC 地址、IPv4 地址和 IPv6 地址来实现。 24 然后,模板描述利用 `proc` 类型来为每个执行器生成适当的地址。 25 26 由于许多网络协议需要将校验和字段嵌入到数据包中,因此支持描述此类字段。 27 这里存在一个 `csum` 类型,目前支持两种不同类型的校验和计算: 28 Internet 校验和 [the Internet checksum](https://tools.ietf.org/html/rfc1071) : `csum[parent, inet, int16be]`, 29 以及类似于 TCP 的伪头部校验和: `csum[tcp_packet, pseudo, IPPROTO_TCP, int16be]`。 30 在通过虚拟接口发送数据包之前,这些校验和会被计算并嵌入其中。 31 这里还有一个很好的特性:当 syzkaller 生成 C 语言 reproducer 时,它也会生成代码并在运行时重新计算校验和。 32 33 通过使用 `syz_emit_ethernet` and `syz_extract_tcp_res`,以下 syzkaller 程序能够建立基于 IPv4 的 TCP 连接: 34 35 ``` 36 mmap(&(0x7f0000000000/0x10000)=nil, (0x10000), 0x3, 0x32, 0xffffffffffffffff, 0x0) 37 r0 = socket$inet_tcp(0x2, 0x1, 0x0) 38 bind$inet(r0, &(0x7f0000001000)={0x2, 0x0, @empty=0x0, [0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0]}, 0x10) 39 listen(r0, 0x5) 40 syz_emit_ethernet(0x36, &(0x7f0000002000)={@local={[0xaa, 0xaa, 0xaa, 0xaa, 0xaa], 0x0}, @random="4c6112cc15d8", [], {{0x800, @ipv4={{0x5, 0x4, 0x0, 0x0, 0x28, 0x0, 0x0, 0x0, 0x6, 0x0, @remote={0xac, 0x14, 0x0, 0xbb}, @local={0xac, 0x14, 0x0, 0xaa}, {[]}}, @tcp={{0x1, 0x0, 0x42424242, 0x42424242, 0x0, 0x0, 0x5, 0x2, 0x0, 0x0, 0x0, {[]}}, {""}}}}}}) 41 syz_extract_tcp_res(&(0x7f0000003000)={<r1=>0x42424242, <r2=>0x42424242}, 0x1, 0x0) 42 syz_emit_ethernet(0x38, &(0x7f0000004000)={@local={[0xaa, 0xaa, 0xaa, 0xaa, 0xaa], 0x0}, @remote={[0xbb, 0xbb, 0xbb, 0xbb, 0xbb], 0x0}, [], {{0x800, @ipv4={{0x5, 0x4, 0x0, 0x0, 0x2a, 0x0, 0x0, 0x0, 0x6, 0x0, @remote={0xac, 0x14, 0x0, 0xbb}, @local={0xac, 0x14, 0x0, 0xaa}, {[]}}, @tcp={{0x1, 0x0, r2, r1, 0x0, 0x0, 0x5, 0x10, 0x0, 0x0, 0x0, {[]}}, {"0c10"}}}}}}) 43 r3 = accept$inet(r0, &(0x7f0000005000)={0x0, 0x0, @multicast1=0x0, [0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0]}, &(0x7f0000006000)=0x10) 44 ``` 45 46 ``` 47 Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name 48 tcp 0 0 0.0.0.0:20000 0.0.0.0:* LISTEN 5477/a.out 49 tcp 2 0 172.20.0.170:20000 172.20.0.187:20001 ESTABLISHED 5477/a.out 50 ``` 51 52 对于 IPV6 来说也有类似的程序: 53 54 ``` 55 mmap(&(0x7f0000000000/0x10000)=nil, (0x10000), 0x3, 0x32, 0xffffffffffffffff, 0x0) 56 r0 = socket$inet6_tcp(0xa, 0x1, 0x0) 57 bind$inet6(r0, &(0x7f0000000000)={0xa, 0x1, 0x0, @empty={[0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0]}, 0x0}, 0x1c) 58 listen(r0, 0x5) 59 syz_emit_ethernet(0x4a, &(0x7f0000001000)={@local={[0xaa, 0xaa, 0xaa, 0xaa, 0xaa], 0x0}, @random="de895db1468d", [], {{0x86dd, @ipv6={0x0, 0x6, "a228af", 0x14, 0x6, 0x0, @remote={0xfe, 0x80, [0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0], 0x0, 0xbb}, @local={0xfe, 0x80, [0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0], 0x0, 0xaa}, {[], @tcp={{0x0, 0x1, 0x42424242, 0x42424242, 0x0, 0x0, 0x5, 0x2, 0x0, 0x0, 0x0, {[]}}, {""}}}}}}}) 60 syz_extract_tcp_res(&(0x7f0000002000)={<r1=>0x42424242, <r2=>0x42424242}, 0x1, 0x0) 61 syz_emit_ethernet(0x4a, &(0x7f0000003000)={@local={[0xaa, 0xaa, 0xaa, 0xaa, 0xaa], 0x0}, @random="de895db1468d", [], {{0x86dd, @ipv6={0x0, 0x6, "a228af", 0x14, 0x6, 0x0, @remote={0xfe, 0x80, [0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0], 0x0, 0xbb}, @local={0xfe, 0x80, [0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0], 0x0, 0xaa}, {[], @tcp={{0x0, 0x1, r2, r1, 0x0, 0x0, 0x5, 0x10, 0x0, 0x0, 0x0, {[]}}, {""}}}}}}}) 62 r3 = accept$inet6(r0, &(0x7f0000004000)={0x0, 0x0, 0x0, @empty={[0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0]}, 0x0}, &(0x7f0000005000)=0x1c) 63 ``` 64 65 ``` 66 Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name 67 tcp6 0 0 :::20001 :::* LISTEN 5527/a.out 68 tcp6 0 0 fe80::aa:20001 fe80::bb:20000 ESTABLISHED 5527/a.out 69 ```