内存安全绝对主义者:Rust 与 Fil-C 之争
Memory Safety Absolutists
看到标题,你或许第一时间想到了 Rust 开发者。确实,Rust 社区对内存安全的热情常被误解为语言战争。但本文并非针对 Rust,而是探讨新兴的 Fil-C 项目如何让 C、C++ 和 Zig 代码也能实现内存安全。Fil-C 通过结合垃圾回收和 InvisiCaps 技术,在非法内存访问时触发 panic。然而,Fil-C 的作者和 Zig 的 Andrew Kelley 却公开质疑 Rust 的安全性,认为其 unsafe 块破坏了安全承诺。这种‘内存安全绝对主义’忽视了现实权衡:Fil-C 存在 ABI 不兼容、性能损耗和引入 GC 等代价,并不适用于所有场景。Rust 在 Android 等大规模项目中已证明其漏洞密度比 C/C++ 低上千倍。真正的务实者应关注风险与收益的平衡,而非盲目追求理论上的完美安全。
如果你真的如此关心内存安全,以至于连 Rust 每百万行代码 0.2 个漏洞都不可接受,那我希望你也会同样严厉地批评那些编译 YOLO 风格 C/C++ 和非 Fil 模式 Zig 的人。
- himata4113
我对于拒绝内存安全最大的担忧是,这些问题最终会演变成我的问题。当我被迫使用这些应用程序时,我必须担心是否存在某种利用随机编解码器中溢出漏洞的零点击零日攻击。我不是以软件开发者,而是以普通用户的身份,希望我的应用程序是用 Rust 编写的,或者至少最低限度地使用 Fil-C。
现在,作为一名软件开发者,我觉得这一点甚至更重要,因为我使用的库是由成千上万其他开发者维护的,他们也可能使用存在这些漏洞的应用程序,导致他们的系统被入侵,进而向成千上万其他开发者推送恶意软件,最终导致更多库被入侵。
我相信,对于成千上万甚至数百万人依赖的软件来说,内存安全应该是标准,而不应该成为某种政治议题,争论 X 更好、Y 那样、Z 又是另一种。
但话说回来,社会工程学才是恶意软件传播的主要来源,所以我也说不准。
- smj-edison
只要企业继续以敌对态度侵蚀个人自由,我就认为这些“内存安全绝对主义者”是独裁者。因为人类无论如何总会犯错,这应该是事物的自然状态;而试图以“安全”为名彻底消除所有人类错误,最终只会导致可怕的极权社会。
“如果自由不包括犯错的自由,那就不值得拥有。”
“那些为了获得一点暂时的安全而放弃基本自由的人,既不配拥有自由,也不配拥有安全。”
- inigyou
这或许是一个不同的视角,但我喜欢 Zig 和 C 的原因之一,是因为我学会了如何推理指针。过去我曾在一个约 12,000 行代码的副项目中用过 Rust,当时我完全接受了树状所有权和 XOR 可变性。但事实证明,有些非常棒的数据结构只能用 Rust 的 unsafe 来表达。侵入式双向链表简直酷毙了。我可以拥有一个 LRU 缓存,通过调整指针来改变队首元素,同时保持地址稳定,从而让哈希表保持稳定?这简直太酷了。用指针进行原子操作来实现链表,对于在多线程间实现分配器的空闲链表来说非常巧妙。能够仅仅通过……跟随指针,使用广度优先搜索遍历活动堆,让 Dijkstra 算法的优雅真正活了起来。
现在,也许我只遇到了这些算法,因为我遇到的正是这些问题,但在 Rust 社区,我 consistently 收到的信息是链表是一种过时的数据结构。在某些情况下确实如此,但当它们适用时,效果却好得惊人。
我知道用 Zig 编程会留下大量内存不安全的空间。也许这是件坏事。但我正在实现一个解释器,这些算法对它的快速运行至关重要。我确实需要清楚每一次内存分配发生在哪里,以及计算机正在执行什么指令。所以目前我坚持使用 Zig,尽管我知道这让我自己敞开了……
- Animats
我认为“Fil-C 比 Rust 更安全”这种说法,是对十年来 Rust 布道者不断告诉人们“不用 Rust 你就是蠢货、你就是错的”这一现象的一种可以理解的反动。
- Panzerschrek
正在试图搞懂 Fil-C 的“inviscaps”。[1]
当你用 Fil-C 的“malloc”分配空间时,一些额外的边界检查数据会出现在程序实际可用的空间之前。指针是“胖指针”,包含一个指向缓冲区开头的指针和一个指向缓冲区内部某处的指针,从而允许普通的 C 指针操作。
围绕这个有很多新术语。但大致上,这和 GCC 的“胖指针”[2][3] 是同一个概念。所以这并不是一个新想法。这个想法已经被尝试过几次,但从未流行起来。
这会有性能损耗。尤其是当编译器无法将检查移出循环时。
[1] https://fil-c.org/invisicaps