2026年11月13日
每次变更,我们都攻击自己的构建
不可能失败的安全测试说明不了任何问题。所以 NoWayOS 的测试都配有专门为失败而构建的版本,它的关卡则放在拉取请求够不到的地方。
本页内容
对任何安全测试,都有一个让人不舒服的问题:它失败过吗?一个从未失败过的测试之所以通过,可能是因为系统健全,也可能是因为这个测试什么都看不见。从外面看,两者一模一样。
所以 NoWayOS 不只是测试自己的安全性。每次变更,它都会攻击它,并检查这些攻击被拦了下来。
伸手去拿不属于自己的东西
NoWayOS 系统的每个部分都运行在 seL4 上各自的隔离舱里,只持有被授予它的东西。隔离测试会故意让探针越过这些边界。一个探针去读从未给过它的地址。一个探针去写它只能读的页面。一个探针持有的东西与用户界面完全相同,它试图写入显示的控制页面,而界面对这个页面只能读。另一个探针持有的东西与网络客户端完全相同,它试图写入网络驱动的内存。
seL4 必须把它们全部拦下,而一个旁观的部分必须继续运行,不受任何影响。
一个为失败而构建的测试
接下来是转折。在用户界面的隔离测试旁边,有一个故意放宽了一项授权的变体:界面的替身得到了显示的私有页面。这个变体的测试必须失败。如果它哪天通过了,就说明隔离测试是瞎的,构建会指出这一点。
同样的想法贯穿其余的检查。各部分之间消息的每个解码器,都有来自 Kani 模型检查器的有界证明,证明它绝不会 panic、溢出或越界读取。随后,变异检查会故意把解码器改坏,以表明这些证明能够察觉。每个处理外部输入的解析器,都用恶意数据做模糊测试。
这一切都是 make ci 的一部分,也就是每次变更都必须通过的关卡。隔离测试每次都运行;一项证明或一轮模糊测试,只要它覆盖的代码有变化,就会重新运行。
一个为失败而构建的测试
测试探针伸手去够一个从未授予它的页面。seL4 把它拦下,测试通过。
变体故意放宽一项授权。探针穿了过去,所以这个测试必须失败。如果它哪天通过了,第一个测试就是瞎的。
够不到的关卡
关卡的强度,取决于能改动它的那只手。因此,对 NoWayOS 的每一项贡献必须通过的检查,都定义在 Defence Agent 里,这是一个独立的公开仓库。触及关卡的拉取请求会被标记出来,交给维护者。
Defence Agent 也用同样的方式测试自己:二十个预先埋好的拉取请求,每一个都藏着审阅者可能漏掉的东西。有注释里隐藏的从右到左文本,有被换成相似的西里尔字母的一个字母,有直接从 git 仓库获取的依赖,有会运行不可信代码的工作流。每一个都必须被发现,而三个真实的历史变更必须通过。
要证据,不要形容词
这一切都不会让设备变得“无法被黑客攻破”。没有什么能做到这一点,我们也永远不会这样说。它给您的是证据:一份记录,写明尝试了什么、拦下了什么,以及能展示这一切的命令。请阅读一个真实镜像的证据,或者这些关卡本身。