本文档记录了针对 CVE-2026-74727 相关上游修复的本地构建、功能测试、聚焦源码审查以及确定性的 VPN-IP 与传输端点 rehash 不变量回归测试,测试对象为 x86_64 上的 Ubuntu 内核源码包 linux 7.0.0-38.38。传输端点测试还在本地构建的 Generic KASAN 内核上重新构建并运行。
这是对现有上游修复的向后移植审查,而非新发现的漏洞或原创安全修复。记录的上游作者为 Antonio Quartulli。记录的提交为 33ec10567fe14456063daf549fdf1a4f53448e4c。
drivers/net/ovpn/peer.c 中的改动可防止对已从 peer ID 哈希表中移除的 peer 再次执行 rehash。分发时请保留原始补丁头、作者信息与许可证。本文档不会对内核补丁重新授权。
原始上游补丁按字节原样收录。其 SHA-256 与记录测试会话中使用的产物一致。其作者、提交信息与代码改动已对照 GitHub 上的公开上游提交进行核对。本文档不包含任何二进制文件。
补丁校验和已与收录文件独立核对。模块校验和记录于操作员的测试会话中;此处不分发该二进制文件。
| 产物 | SHA-256 |
|---|---|
CVE-2026-74727-upstream.patch | baf0962c60b182776a86e040d2ec5b35eea2737c2e2eb6f17f87eb7d2fe47b24 |
测试用 ovpn.ko | 0853fdce14ce1c4d64857871dc873bf98a1b8fe8243bf042ad6daffc906e6d27 |
请使用单独解压的精确 Ubuntu 源码包 linux 7.0.0-38.38 副本。首先安装匹配的内核头文件与构建工具链。记录的编译器为 Ubuntu GCC 15.2.0-16ubuntu1,与运行中内核的编译器一致。
在源码根目录下,补丁位于其父目录中:
patch --dry-run --batch --forward --fuzz=0 -p1 < ../CVE-2026-74727-upstream.patch
patch --batch --forward --fuzz=0 -p1 < ../CVE-2026-74727-upstream.patch
make -C /lib/modules/7.0.0-38-generic/build \
M="$PWD/drivers/net/ovpn" CONFIG_OVPN=m \
CC=x86_64-linux-gnu-gcc -j1 modules
记录的补丁应用使用了零模糊匹配,行偏移为 -6 和 -5。构建返回退出码 0。由于 vmlinux 不可用,BTF 生成被跳过。模块 vermagic 匹配 7.0.0-38-generic SMP preempt mod_unload modversions。
vermagic 匹配且构建成功,并不能证明模块是安全的,也不能证明该漏洞已被完全验证。
测试在禁用 Secure Boot、内核为 7.0.0-38-generic 的 Hyper-V Ubuntu 虚拟机上手动执行。结果基于操作员提供的终端输出:
192.0.2.2 改为 192.0.2.3;返回的对等端状态确认了该更改。此操作仅限于临时测试命名空间,未更改运行中的 VPN 地址。2026-10-06,两个独立测试模块执行了从未打补丁的备份和已打补丁的源码中提取的实际 ovpn_peer_hash_vpn_ip() 函数。私有合成对象在整个过程中保持分配状态。在模拟完成从哈希表中移除后,测试在 ovpn->lock 下再次调用该函数。
| 属性 | 补丁前 | 补丁后 |
|---|---|---|
| 活动对等端已录入 IPv4 和 IPv6 表 | PASS | PASS |
| 已移除的对等端保持在 IPv4 和 IPv6 表之外 | FAIL | PASS |
| 已移除对等端重哈希后占用的 IPv4 / IPv6 桶数 | 1 / 1 | 0 / 0 |
这是对特定移除后不变量的运行时检查,并非并发删除竞态或释放后使用的复现。基线的变量失败是预期内的,表明该测试能够区分两个函数版本。随后两个模块均被卸载。运行中的 VPN 保持活动,其地址未变。审查的日志区间包含测试结果,且没有匹配的 BUG、Oops、general protection fault 或 soft lockup 消息。
有关记录的输出、复现说明和限制,请参见 TESTING.md。生成器位于 tests/prepare-ovpn-rehash-regtest.py。
2026-10-06,独立测试模块还执行了从已打补丁和未打补丁的源码中提取的实际 ovpn_peer_endpoints_update() 函数,并使用了生产绑定辅助函数。对于 IPv4 和 IPv6,私有合成数据包头导致活动对等端浮动,然后在其哈希条目已被移除但存储仍保持分配的情况下,触发了另一次端点更新。
| 属性,针对 IPv4 和 IPv6 | 补丁前 | 补丁后 |
|---|---|---|
| 活动对等端浮动并保留在传输表中 | PASS | PASS |
| 在模拟移除后到达端点更新 | PASS | PASS |
| 已移除的对等端保持在传输表之外 | FAIL | PASS |
| 已移除对等端更新后占用的传输桶数 | 1 | 0 |
未传输任何数据包,也未修改任何真实接口、VPN 对等端或地址。随后两个测试模块均被卸载;运行中的 VPN 保持活动,其地址未变。审查的日志区间包含四项测试结果,且没有匹配的 BUG、Oops、general protection fault 或 soft lockup 行。
有关范围、复现说明和记录结果,请参见 FLOAT-TESTING.md 和 tests/prepare-ovpn-float-regtest.py。
2026-10-06,审查过的 Ubuntu 源码被构建为完整内核,配置为 CONFIG_KASAN=y、CONFIG_KASAN_GENERIC=y、CONFIG_KASAN_OUTLINE=y 和 CONFIG_STACKTRACE=y。其 release 字符串为 7.0.14-ovpn-kasan。内核和模块构建均返回退出码 0。虚拟机引导了该内核,其管理 VPN 服务处于活动状态。
现有的合成 float 模块针对该完整构建重新编译,并在传输后通过校验和与 vermagic 验证。IPv4 和 IPv6 结果保持不变:active-peer 和 endpoint-update 检查在两种变体中均通过;removed-peer 不变量在基线中失败,在修补变体中通过。所提供的过滤测试日志中未出现 KASAN 错误。这是合成测试在启用 KASAN 下的执行,并非对原始 use-after-free 的 KASAN 复现。仅 VPN-IP 的测试未在 KASAN 下重新运行。
测试模块已卸载。虚拟机随后返回发行版内核 7.0.0-38-generic,并确认管理 VPN 处于活动状态。单独安装的测试内核及其模块仍可供未来测试使用;发行版内核被配置为 GRUB 默认项。
有关配置、确切结果、产物哈希和限制,请参见 KASAN-TESTING.md。有关基于操作员提供的源码摘录进行的聚焦锁、引用和释放路径审查,请参见 SOURCE-REVIEW.md。
并发删除/重哈希竞态未被复现。两条修改过的重哈希路径均在确定性的合成移除后状态下进行了测试;只有 float 测试随后在 KASAN 下重新运行。这并不能确立真实并发下的完全正确性。未执行基于漏洞利用的回归测试、启用 KCSAN 的运行、启用 lockdep 的运行或持续并发测试。这些测试未覆盖完整的已认证网络接收路径、真实生产删除回调或每一次哈希表查找。实际的引用计数和 RCU peer 拆除是静态审查的,未通过完整的生命周期测试进行验证。先前的 VPN IPv4 CLI 测试仅确认了 API 行为。
先前的独立 backport 模块未被持久安装。后来在现有虚拟机上安装并手动引导了一个单独的 KASAN 测试内核,该虚拟机的管理 VPN 在测试期间仍在使用;它并非完全一次性的环境。虚拟机已返回其发行版内核。这些结果不建议将测试内核部署到生产环境。其他 OpenVPN 内核漏洞不在本补丁的范围内。未提议二进制发布。
使用具有控制台访问权限的隔离测试虚拟机。停止 VPN 服务可能会断开 SSH 会话。网络命名空间共享主机内核,无法保护虚拟机免受内核崩溃的影响。
保持发行版模块文件不变。如果测试模块仅通过 insmod 加载,请停止所有使用它的服务,在不强制移除的情况下卸载它,使用 modprobe ovpn 加载原始模块,然后从控制台重启这些服务。如果卸载失败,请检查剩余使用者,而不是强制卸载。在未进行持久安装的情况下,重启也会返回发行版模块。