fix(ax-net): avoid panic on malformed inbound packet in snoop_tcp_packet - #1436
fix(ax-net): avoid panic on malformed inbound packet in snoop_tcp_packet#1436luyanhexay wants to merge 1 commit into
Conversation
There was a problem hiding this comment.
审查总结
变更内容
本 PR 修复了 snoop_tcp_packet(net/ax-net/src/router.rs)中使用 unwrap/new_unchecked 解析攻击者可控字节导致的远程可达内核 panic。函数在 smoltcp 校验之前对每个收到的报文运行,用于探测被动 TCP 打开,但以太网层仅校验 L2 头,对任意 0x0800/0x86DD 帧载荷原样入队。修复后改为防御式解析:先挡空 buf,再用 IpVersion::of_packet().ok() 和 *::new_checked(),畸形/截断帧安全丢弃而非 panic。
实现逻辑
修复方案正确且与项目已有风格一致:
rx_meta.rs中使用Ipv4Packet::new_checked(packet).ok()?raw.rs中使用Ipv4Packet::new_checked(packet)/Ipv6Packet::new_checked(packet)dhcp_server.rs中使用Ipv4Packet::new_checked(packet).ok()?
变更仅影响畸形报文的处理路径(从 panic 改为静默丢弃),合法报文的被动 TCP 打开探测行为完全不变。注释清晰解释了为何需要防御式解析。
验证结果
| 检查项 | 结果 |
|---|---|
cargo fmt --check -p ax-net |
✅ 通过 |
cargo clippy -p ax-net -- -D warnings |
✅ 通过 |
cargo test -p ax-net |
✅ 34 passed(含新增 snoop_tcp_packet_tolerates_malformed_frames) |
| CI: Check formatting | ✅ success |
| CI: Run clippy | ✅ success |
| CI: Run sync-lint / spin-lint | ✅ success |
| CI: Test arceos (x86_64, riscv64, aarch64) | ✅ success |
| CI: Test starry aarch64 qemu | ✅ success |
| CI: Test axvisor (riscv64, loongarch64, x86_64, boards) | ✅ success |
| CI: Test starry loongarch64 qemu | ❌ failure(见下文分析) |
CI 失败分析
唯一失败的检查是 Test starry loongarch64 qemu / run_container(运行 target/debug/tg-xtask starry test qemu --arch loongarch64),失败在 Run command 步骤。该失败与本 PR 无关:
- 本 PR 仅修改
snoop_tcp_packet中的报文解析方式(从 panic 改为静默丢弃),不影响正常报文处理路径。 - 相同的 StarryOS QEMU 测试在 aarch64 上通过,说明变更的代码逻辑不会导致系统级测试失败。
- 当前 dev 分支有 PR #1435(
refactor(net): split IRQ handlers from NIC queues)正在进行 VirtIO IRQ handler 重构,其描述明确提到 loongarch64 QEMU 测试中存在 VirtIO IRQ 相关的间歇性问题(ack_interrupt丢失、queue_enable断言等)。该失败极大概率是 loongarch64 VirtIO IRQ 未完全稳定的已知问题。 - dev 分支最新 CI(#1430 merge)全通过,说明该问题是间歇性的。
测试覆盖
新增单元测试 snoop_tcp_packet_tolerates_malformed_frames 覆盖 7 个用例:
- 空 buf(
of_packet会越界buf[0]) - 版本 nibble 0 和 15(
of_packet返回Err) - 截断 IPv4 头(1 字节)
- IPv4 IHL=15 但只有 4 字节(
new_unchecked越界) - 截断 IPv6 头(1 字节)
- 合法 IPv4 头但 TCP payload 仅 2 字节(不足 20 字节 TCP 头)
测试验证每个用例在修复后不 panic。修复前每个用例确实会 panic(作者提供了具体的 panic 位置和错误信息)。
重复/重叠分析
- 搜索了当前 open PR:#1435(IRQ handler 重构)涉及
ax-net但范围不同,与本 PR 互补,无冲突。 - 本仓库内未发现修复同一问题的其他 PR。
- base 分支上
snoop_tcp_packet仍使用unwrap/new_unchecked,本 PR 尚未被覆盖。
结论
PR 质量高,修复了一个真实的安全问题(远程可达的内核 DoS),方案正确,代码风格与项目一致,测试覆盖充分,CI 失败与本变更无关。无阻塞问题。
Powered by mimo-v2.5-pro
ZR233
left a comment
There was a problem hiding this comment.
复审当前 head 99a8b041293ad014f2da6082854be50b50bbbf74,本轮同意合入。
这个 PR 只改 net/ax-net/src/router.rs,把 snoop_tcp_packet 中对收到包的 unwrap/new_unchecked 解析改成空 buffer 防护、IpVersion::of_packet 错误返回、IPv4/IPv6/TCP new_checked 失败即丢弃。该函数运行在 smoltcp 完整校验之前,输入来自外部帧载荷,当前做法符合 rx_meta、raw、dhcp_server 等路径已经使用 checked packet constructor 的项目风格;合法 TCP 包的 passive open 探测逻辑没有改变,畸形/截断包从 panic 变成安全忽略。
测试覆盖方面,新增 snoop_tcp_packet_tolerates_malformed_frames 覆盖空 buffer、非法 IP version、截断 IPv4/IPv6、IPv4 IHL 过长以及合法 IPv4 头但 TCP payload 过短等过去会走到 panic 的输入。该 PR 是 bug fix,回归测试放在修改函数同模块单测里,能直接覆盖修复点。
本地验证:cargo test -p ax-net 通过,结果为 34 passed,包含新增的 snoop_tcp_packet_tolerates_malformed_frames。
CI 状态:current-head CI 中格式、clippy、sync/spin lint、Test starry x86_64/aarch64 qemu、ArceOS/Axvisor 相关成功;Test starry riscv64 qemu / run_container 和 Test starry loongarch64 qemu / run_container 失败/取消在 qemu-smp4/system 的 bug-sched-affinity-pid 路径,日志分别停在 affinity case 的迭代和 loongarch64 queue_enable/1800s timeout,不涉及本 PR 修改的 ax-net malformed packet parser。我已把这次 unrelated 复现补充到既有 tracker #1106:https://github.com/rcore-os/tgoskits/issues/1106#issuecomment-4838971792。
重复/重叠检查:base 分支的 snoop_tcp_packet 仍使用 IpVersion::of_packet(buf).unwrap() 和 unchecked packet constructors;open PR 搜索中没有发现另一个修复同一 malformed inbound packet panic 的 PR。#1435 也涉及 net/IRQ 方向,但不是同一修复表面。未发现新的阻塞问题。
99a8b04 to
c9bd710
Compare
|
已本地确认该分支可以无冲突 rebase 到最新
当前账号对 fork 分支 git fetch upstream dev
git rebase upstream/dev
git push --force-with-lease如果本地还没有 git remote add upstream https://github.com/rcore-os/tgoskits.git |
There was a problem hiding this comment.
审查总结
变更内容
本 PR 修复了 snoop_tcp_packet(net/ax-net/src/router.rs)中对攻击者可控字节使用 unwrap/new_unchecked 解析导致的远程可达内核 DoS。该函数在 smoltcp 校验之前对每个收到的报文运行(用于探测被动 TCP 打开),但以太网层仅校验 L2 头,对 0x0800/0x86DD 帧载荷原样入队。修复后改为防御式解析:空 buf 直接返回,IpVersion::of_packet() 用 Ok/Err 匹配,IPv4/IPv6/TCP 全部改用 new_checked(),畸形帧静默丢弃而非 panic。
实现逻辑
修复方案正确,且与项目已有解析风格完全一致:
rx_meta.rs:49—IpVersion::of_packet(packet).ok()?+Ipv4Packet::new_checked(packet).ok()?raw.rs:225—Ipv4Packet::new_checked(packet)/Ipv6Packet::new_checked(packet)dhcp_server.rs:48—Ipv4Packet::new_checked(packet).ok()?ip_tos.rs:82,104—match IpVersion::of_packet(packet)+Ipv4Packet::new_checked(packet)withlet Ok(...)
合法报文的 passive TCP open 探测行为完全不变,仅影响畸形报文路径(从 panic 改为静默丢弃)。注释清晰解释了攻击面和为何需要防御式解析。
验证结果
| 检查项 | 结果 |
|---|---|
cargo fmt --check -p ax-net |
✅ 通过 |
cargo clippy -p ax-net -- -D warnings |
✅ 通过 |
cargo test -p ax-net |
✅ 34 passed(含新增 snoop_tcp_packet_tolerates_malformed_frames) |
CI 状态
CI 已通过的关键检查:
- Check formatting (run_host): ✅ success
- Run clippy: ✅ success
- Run sync-lint / spin-lint: ✅ success
- Test arceos x86_64 qemu (run_host): ✅ success
- Test starry aarch64 qemu (run_container): ✅ success
- Test axvisor riscv64 qemu (run_host): ✅ success
CI 失败/跳过的检查:
Test starry loongarch64 qemu / run_container: failure — 日志显示queue_enable断言和 1800s timeout,属于 loongarch64 VirtIO IRQ 间歇性问题(已有 tracker #1106),与本 PR 无关。Test starry riscv64 qemu / run_host: skipped — 路径过滤行为(mutual exclusion run_host/run_container)。- 各
run_container对应的run_host已成功时的 mutual exclusion 跳过:预期行为。
测试覆盖
新增单元测试 snoop_tcp_packet_tolerates_malformed_frames 覆盖 7 个用例:
- 空
buf—of_packet会越界buf[0] - 版本 nibble 0 —
of_packet返回Err - 版本 nibble 15 —
of_packet返回Err - IPv4 声明但仅 1 字节 — 截断 IPv4 头
- IPv4 IHL=15(60 字节)但仅 4 字节 —
new_unchecked越界 - IPv6 声明但仅 1 字节 — 截断 IPv6 头
- 合法 IPv4 头但 TCP payload 仅 2 字节(不足 20 字节 TCP 头)
每个用例在修复前都会 panic,修复后安全返回。测试位于修改函数同模块(mod tests),能直接覆盖修复点。
重复/重叠分析
- base 分支的
snoop_tcp_packet仍使用IpVersion::of_packet(buf).unwrap()和 unchecked packet constructors,本 PR 尚未被覆盖。 - open PR 中未发现另一个修复同一 malformed inbound packet panic 的 PR。
- #1435(
refactor(net): split IRQ handlers from NIC queues)也涉及ax-net,但范围是 VirtIO IRQ handler 重构,与本 PR 互补,无冲突。 - #1446、#1443、#1442 等 open PR 涉及 sdmmc/RISC-V IRQ 路由,完全不相关。
前置 review 考虑
mai-team-app[bot]已 APPROVED,分析与本审查一致。ZR233(MEMBER)已 APPROVED,确认本地 rebase 到最新 dev 无冲突,验证通过。ZR233 还确认 fork 无写权限无法代为推送 rebase。- issue comment 中 ZR233 建议作者执行
git rebase upstream/dev && git push --force-with-lease更新分支。
结论
无阻塞问题。PR 修复了一个真实的安全问题(远程可达的内核 DoS),方案正确,代码风格与项目一致,测试覆盖充分。mergeable_state: unstable 仅因为 loongarch64/riscv64 QEMU 测试的已知间歇性失败,与本变更无关。
Powered by mimo-v2.5-pro
c9bd710 to
d60d0a0
Compare
There was a problem hiding this comment.
审查总结
变更内容
本 PR 修复了 snoop_tcp_packet(net/ax-net/src/router.rs)中对攻击者可控字节使用 unwrap/new_unchecked 解析导致的远程可达内核 DoS。该函数在 smoltcp 校验之前对每个收到的报文运行(用于探测被动 TCP 打开),但以太网层仅校验 L2 头,对 0x0800/0x86DD 帧载荷原样入队。修复后改为防御式解析:空 buf 直接返回,IpVersion::of_packet() 用 Ok/Err 匹配,IPv4/IPv6/TCP 全部改用 new_checked(),畸形帧静默丢弃而非 panic。
实现逻辑
修复方案正确,且与项目已有解析风格完全一致:
rx_meta.rs:49—IpVersion::of_packet(packet).ok()?+Ipv4Packet::new_checked(packet).ok()?raw.rs:225—Ipv4Packet::new_checked(packet)/Ipv6Packet::new_checked(packet)dhcp_server.rs:48—Ipv4Packet::new_checked(packet).ok()?
合法报文的 passive TCP open 探测行为完全不变,仅影响畸形报文路径(从 panic 改为静默丢弃)。注释清晰解释了攻击面和防御式解析的必要性。
验证结果
| 检查项 | 结果 |
|---|---|
cargo fmt --check -p ax-net |
✅ 通过 |
cargo clippy -p ax-net -- -D warnings |
✅ 通过 |
cargo test -p ax-net |
✅ 34 passed(含新增 snoop_tcp_packet_tolerates_malformed_frames) |
CI 状态
CI 56 个检查中:17 success、28 skipped(run_host/run_container 互斥预期行为)、10 cancelled(stale CI 取消)、1 failure。
关键通过的检查:
- Check formatting ✅
- Run clippy ✅
- Run sync-lint / spin-lint ✅
- Test arceos (x86_64, riscv64, aarch64, loongarch64) ✅
- Test axvisor (aarch64, riscv64, loongarch64, x86_64) ✅
唯一失败:Test starry aarch64 qemu / run_container。该失败与本 PR 无关:
- 本 PR 仅修改
snoop_tcp_packet的错误处理路径(从 panic 改为静默丢弃),不影响正常报文处理。 - 变更不涉及 QEMU 测试用例、系统调用、或 Starry system 行为。
- 已有 tracker issue #1106 记录了 QEMU 容器测试中 affinity/scheduling 相关的间歇性失败模式。
测试覆盖
新增单元测试 snoop_tcp_packet_tolerates_malformed_frames 覆盖 7 个用例:
- 空
buf—of_packet会越界buf[0] - 版本 nibble 0 —
of_packet返回Err - 版本 nibble 15 —
of_packet返回Err - IPv4 声明但仅 1 字节 — 截断 IPv4 头
- IPv4 IHL=15(60 字节)但仅 4 字节 —
new_unchecked越界 - IPv6 声明但仅 1 字节 — 截断 IPv6 头
- 合法 IPv4 头但 TCP payload 仅 2 字节(不足 20 字节 TCP 头)
每个用例在修复前都会 panic,修复后安全返回。测试位于修改函数同模块(mod tests),直接覆盖修复点。
重复/重叠分析
- base 分支的
snoop_tcp_packet仍使用IpVersion::of_packet(buf).unwrap()和 unchecked packet constructors,本 PR 尚未被覆盖。 - open PR 中未发现另一个修复同一 malformed inbound packet panic 的 PR。
- #1435(
refactor(net): split IRQ handlers from NIC queues)也涉及ax-net,但范围是 VirtIO IRQ handler 重构,与本 PR 互补,无冲突。 - #1450、#1449 等 open PR 涉及 evdev/input 和 Python 测试应用,完全不相关。
前置 review 考虑
mai-team-app[bot]两次 APPROVED,分析与本审查一致。ZR233(MEMBER)APPROVED,已确认本地 rebase 无冲突,验证通过。- issue comment 中 ZR233 建议作者 rebase 更新分支,但 rebase 不影响本 PR 的正确性。
结论
无阻塞问题。PR 修复了一个真实的安全问题(远程可达的内核 DoS),方案正确,代码风格与项目一致,测试覆盖充分,无 crate/dependency 变更,mergeable_state: unstable 仅因为 QEMU 容器测试的已知间歇性失败,与本变更无关。
Powered by mimo-v2.5-pro
`snoop_tcp_packet` 在 smoltcp 校验之前、对每个收到的报文运行,而这些字节是 攻击者可控的:以太网层(`EthernetDevice::handle_frame`)只校验 L2 头,对任何 `0x0800`/`0x86DD` 帧都把其载荷原样入队。该函数却用 `IpVersion::of_packet().unwrap()` 和 `*::new_unchecked()` 解析这些字节,于是一个畸形/截断的帧即可触发内核 panic: - `of_packet(buf).unwrap()`:首字节高 4 位不是 4/6 时 `of_packet` 返回 Err → unwrap panic;`buf` 为空时 `of_packet` 直接对 `buf[0]` 越界。 - `Ipv4Packet::new_unchecked(buf).payload()`:按未校验的 IHL 切片,IHL 过大即越界。 - `TcpPacket::new_unchecked(payload)` 的 `src_port()`/`syn()` 等:对过短载荷越界。 一个构造的以太网帧(ethertype IPv4、IP 内容为垃圾或过短)即可让内核崩溃。 改为防御式解析:先挡空 `buf`,再用 `IpVersion::of_packet().ok()` 和 `*::new_checked()`,任何畸形/截断帧在此安全丢弃,而不是 panic。这与本仓 `rx_meta`/`raw`/`dhcp_server` 已有的解析写法一致。合法报文的检测行为不变。
d60d0a0 to
48f536d
Compare
There was a problem hiding this comment.
审查总结
变更内容
本 PR 修复了 snoop_tcp_packet(net/ax-net/src/router.rs)中对攻击者可控字节使用 unwrap/new_unchecked 解析导致的远程可达内核 DoS。该函数在 smoltcp 校验之前对每个收到的报文运行(用于探测被动 TCP 打开),但以太网层仅校验 L2 头,对 0x0800/0x86DD 帧载荷原样入队。修复后改为防御式解析:空 buf 直接返回,IpVersion::of_packet() 用 Ok/Err 匹配,IPv4/IPv6/TCP 全部改用 new_checked(),畸形帧静默丢弃而非 panic。
实现逻辑
修复方案正确,且与项目已有解析风格完全一致:
rx_meta.rs—IpVersion::of_packet(packet).ok()?+Ipv4Packet::new_checked(packet).ok()?raw.rs—Ipv4Packet::new_checked(packet)/Ipv6Packet::new_checked(packet)dhcp_server.rs—Ipv4Packet::new_checked(packet).ok()?
合法报文的 passive TCP open 探测行为完全不变,仅影响畸形报文路径(从 panic 改为静默丢弃)。注释清晰解释了攻击面和防御式解析的必要性。
验证结果
| 检查项 | 结果 |
|---|---|
cargo fmt --check -p ax-net |
✅ 通过 |
cargo clippy -p ax-net -- -D warnings |
✅ 通过 |
cargo test -p ax-net |
✅ 34 passed(含新增 snoop_tcp_packet_tolerates_malformed_frames) |
CI 状态
CI 53 个检查中:28 success、24 skipped(run_host/run_container 互斥预期行为)、1 failure。
关键通过的检查:
- Check formatting ✅
- Run clippy ✅
- Run sync-lint / spin-lint ✅
- Test arceos (x86_64, riscv64, aarch64, loongarch64) ✅
- Test axvisor (aarch64, riscv64, loongarch64, x86_64, boards) ✅
- Test starry aarch64/loongarch64/x86_64 qemu ✅
- Test starry self-hosted boards ✅
唯一失败:Test starry riscv64 qemu / run_container(job 84231318041)。该失败与本 PR 无关:
- 本 PR 仅修改
snoop_tcp_packet的错误处理路径(从 panic 改为静默丢弃),不影响正常报文处理。 - 变更不涉及 QEMU 测试用例、调度器、affinity 行为。
- 已有 tracker issue #1106 记录了
bug-sched-affinity-pid在 riscv64 QEMU 容器测试中的间歇性失败模式(affinity case panics),与本变更完全不重合。 - starry aarch64、loongarch64、x86_64 QEMU 测试均通过。
测试覆盖
新增单元测试 snoop_tcp_packet_tolerates_malformed_frames 覆盖 7 个用例:
- 空
buf—of_packet会越界buf[0] - 版本 nibble 0 —
of_packet返回Err - 版本 nibble 15 —
of_packet返回Err - IPv4 声明但仅 1 字节 — 截断 IPv4 头
- IPv4 IHL=15(60 字节)但仅 4 字节 —
new_unchecked越界 - IPv6 声明但仅 1 字节 — 截断 IPv6 头
- 合法 IPv4 头但 TCP payload 仅 2 字节(不足 20 字节 TCP 头)
每个用例在修复前都会 panic,修复后安全返回。测试位于修改函数同模块(mod tests),直接覆盖修复点。作为 bug fix,回归测试放在修改函数同模块单测里,能直接覆盖修复点,符合项目要求。
重复/重叠分析
- base 分支的
snoop_tcp_packet仍使用IpVersion::of_packet(buf).unwrap()和 unchecked packet constructors,本 PR 尚未被覆盖。 - open PR 中未发现另一个修复同一 malformed inbound packet panic 的 PR。
- #1435(
refactor(net): split IRQ handlers from NIC queues)也涉及ax-net,但范围是 VirtIO IRQ handler 重构,与本 PR 互补,无冲突。 - 未发现 crates.io patch 或 Cargo 依赖变更。
前置 review 考虑
mai-team-app[bot]已多次 APPROVED,分析与本审查一致。ZR233(MEMBER)已 APPROVED,确认本地 rebase 无冲突且验证通过。- issue comment 中 ZR233 建议作者 rebase 更新分支,但 rebase 不影响本 PR 的正确性。
结论
无阻塞问题。PR 修复了一个真实的安全问题(远程可达的内核 DoS),方案正确,代码风格与项目一致,测试覆盖充分。mergeable_state: unstable 仅因为 riscv64 QEMU 容器测试的已知间歇性失败(#1106),与本变更无关。
Powered by mimo-v2.5-pro
ZR233
left a comment
There was a problem hiding this comment.
按当前 CI 状态重新复审 head 48f536d2f67087233dd64550602499e97cadfbd4,需要撤回此前的通过结论,请求修改。
这个 PR 本身只修改 net/ax-net/src/router.rs,把 snoop_tcp_packet 的不可信包解析改成 checked constructor,并补了 malformed frame 单测;单看代码和 ax-net 单测方向没有问题。但现在不能继续合入,因为 PR 分支多次重跑 CI 仍然失败,且失败集中在 Starry QEMU system/SMP 路径,已经不能再按一次性的无关 flaky 处理。
我重新核对的 CI 证据:
- 当前 head
48f536d2的 run https://github.com/rcore-os/tgoskits/actions/runs/28426443287 为 failure;失败 job 是Test starry riscv64 qemu / run_container(https://github.com/rcore-os/tgoskits/actions/runs/28426443287/job/84231318041)。日志显示qemu-smp4/system跑到STARRY_SYSTEM_TEST_BEGIN: /usr/bin/starry-test-suit/bug-sched-affinity-pid后 1800s timeout,最终Error: starry qemu tests failed for 1 case(s): system。 - 同一 PR 分支近期多次 run 也失败:
28383072652(head99a8b041,Starry loongarch64 失败)、28415892438(headc9bd710c,Starry loongarch64 失败)、28422204748(headd60d0a0f,Starry aarch64 失败并伴随其它 Starry job cancel)、当前28426443287(head48f536d2,Starry riscv64 超时)。 - 当前 head 里 formatting、clippy、ArceOS/Axvisor 以及 Starry x86_64/aarch64/loongarch64 等检查有通过项,但 required Starry riscv64 QEMU 仍失败;失败用例是系统/SMP 调度相关路径,和本 PR 修改的网络包接收解析共同落在内核运行时行为范围内。
因此请先定位为什么该分支反复触发 Starry QEMU system/SMP 失败或超时:如果是本 PR 引入的调度/网络/中断侧影响,需要修复并补对应回归验证;如果能证明是明确的既有基础设施/已知问题,也请给出可核查证据(例如 base 同一 commit/同一 job 的对照、已知 issue 和日志片段),再重跑到当前 head 通过。当前状态下不能继续批准合入。
问题
snoop_tcp_packet(net/ax-net/src/router.rs)在 smoltcp 校验之前、对每个收到的报文运行(用于探测被动 TCP 打开)。它解析的是攻击者可控的字节:EthernetDevice::handle_frame只校验以太网 L2 头,对任意 ethertype 为0x0800/0x86DD的帧都把其载荷原样入队、一路传到这里。该函数却用unwrap/new_unchecked解析这些不可信字节,于是单个畸形或截断的帧即可让内核 panic:IpVersion::of_packet(buf).unwrap():首字节高 4 位非 4/6 时返回Err,引发 unwrap panic,且buf为空时buf[0]越界。Ipv4Packet::new_unchecked(buf).payload():按未经校验的 IHL 切片,IHL 过大即会越界引发 panic。TcpPacket::new_unchecked(payload)的src_port()/dst_port()/syn()等:对过短的 TCP 载荷引发越界产生 panic。构造一个 ethertype 为 IPv4、IP 内容为垃圾/过短的以太网帧即可触发,属于远程可达的内核 DoS。
修复
改为防御式解析:先处理
buf为空的情况,再用IpVersion::of_packet().ok()和*::new_checked(),任何畸形和截断帧在此处安全丢弃而非 panic。这与本仓库rx_meta.rs/raw.rs/dhcp_server.rs已有的解析写法一致。除此以外,合法报文的探测行为不变。测试
snoop_tcp_packet_tolerates_malformed_frames,覆盖空 buf、非法版本位、截断 IPv4/IPv6 头、IPv4 合法但 TCP 过短等用例。修复前每个用例都会 panic(实测空 buf 命中smoltcp .../wire/ip.rs:27的index out of bounds: the len is 0 but the index is 0),修复后全部安全返回。cargo test -p ax-net:34 passed。cargo xtask starry test qemu -c system(aarch64,smp1 + smp4):2/2 passed。