亲爱的KV,
我已经在同一家公司工作超过十年了,我们构建的东西你可以认为是一种设备——基本上是一台功能强大的服务器,旨在完成一项单一的工作,而不是作为通用系统运行。当我们刚开始构建这个系统时,我们几乎所有实现的功能都被添加到操作系统内核作为扩展和内核模块。我们是一个小型团队,都是有能力的C程序员,我们认为以这种方式构建系统可以让我们更好地控制整个系统,并获得显著的性能提升,因为我们不必在内核和用户空间之间复制内存来完成工作。
随着系统的扩展和更多开发人员加入项目,管理层开始质疑为什么我们要在如此难以编程的环境中使用过时的语言构建软件。人力资源部抱怨说,他们找不到足够合格的工程师来满足管理层对更多人手来开发更多功能的需求。最终,决定将大量功能从内核移到用户空间。这导致系统分裂,几乎所有东西都必须通过内核才能到达系统的任何其他部分,这导致性能下降以及大量系统性错误。我不得不承认,如果这些错误发生在内核中,会导致系统崩溃并重启,但即使在用户空间中,它们也会导致功能重启,丢失状态并导致服务中断。
对于我们的下一个产品,管理层希望将几乎所有功能都移到用户空间,他们认为通过拥有更安全的编程环境,团队可以更快、更少错误地创建更多功能。你时不时地谈论内核编程;你也认为内核不适合“凡人”,大多数程序员应该坚持在更安全的用户空间环境中工作吗?
安全第一
亲爱的安全,
业力之轮周而复始,无人幸免,包括程序员、内核、用户空间或其他。
在用户空间编程更安全的原因非常少,其中最主要的原因是虚拟内存系统,它欺骗程序相信它们完全控制系统内存,并捕获少量常见的C语言编程错误,例如触摸程序无权触摸的内存片段。其他原因包括操作系统在过去30年中为程序提供的经过考验的编程API。所有这些都意味着程序员可能会在代码发布之前捕获更多错误,这是一个好消息——旧闻,但仍然是好消息。在用户空间中构建代码并不能解决隔离、组合和效率这些由来已久的问题。
如果你试图构建的是一个程序,它接受一些输入并将其转换为另一种形式,想想像sed
、diff
和awk
这样的常用工具,那么,是的,这些程序非常适合用户空间。你描述的是一个系统,它可能比与典型最终用户的交互更多地与外部世界交互。
一旦我们进入数据处理的高吞吐量和/或低延迟系统的世界,例如路由器、高端存储设备,甚至当前一些物联网设备(参见“物联网:恐怖互联网”),那么你的系统就有一组完全不同的约束,大多数程序员没有被教导如何为这种环境编写代码;相反,他们是通过非常痛苦的经验来学习的。当然,试图向人力资源部或管理层解释这一点,就像用头撞桌子一样——只有当你停下来时才会感觉良好。
你说你已经做了很长时间了,所以你肯定已经看到,在内核中难以做对的事情,在用户空间中也几乎同样难以做对,并且很少能表现得那么好。如果你的问题必须分解为一组协作进程,那么在用户空间中编程与在内核中编程是完全相同的问题,只是需要为任何形式的进程间通信支付更多开销。我个人最喜欢的这种愚蠢形式是,当程序员在用户空间中构建系统,使用共享内存,然后重现内核编程中看到的每一种可能的锁定问题扭曲。协调就是协调,无论你是在内核中、用户空间中还是用鸽子传递消息来完成,尽管前两个地方需要清理的粪便更少。
任何这些系统中的紧张关系都在于性能和隔离之间。虚拟内存——它为我们提供了用户/内核空间划分和进程编程模型,从而使程序彼此受到保护——只是最普遍的隔离形式。如果程序员真的信任,那么他们会把他们所有的代码混合到一个单独的可执行文件中,其中每一段代码都可以触摸每一段内存,但我们知道那会变成什么样。它会变得非常糟糕。该怎么办?
在过去的几年里,出现了一些可能有助于解决这个问题的技术创新,包括Rust和Go等新的系统编程语言,它们具有更多的内置安全性,但它们尚未在操作系统等系统环境中证明其价值。目前还没有人用Go或Rust编写的东西来替换类Unix操作系统。诸如CHERI项目中开展的关于Capabilities的新型计算机架构,由SRI International和剑桥大学开发,也可能使分解软件以实现安全性和在整个系统中保持高水平性能成为可能,但这也有待在技术的实际部署中得到证明。
目前,我们仍然受困于用户空间的虚假安全感,我们认为程序崩溃时整个系统不会重启是一种 благословение(恩赐),并且我们知道在操作系統内核的广阔开放的单一地址空间中编程有多么困难。
在一个高性能代码继续用花哨的汇编器(又名C)编写的世界中,没有内存安全性和大量其他风险,唯一的补救方法是坚持软件工程基础知识。减少处于危险之中的代码量(也称为攻击面),保持子系统之间的耦合高效且显式,并努力为这项工作提供更好的工具,例如静态代码检查器和大型运行时测试套件。
或者,你知道,只是把你所有精心制作的内核代码扔到用户空间,然后抱最好的希望。因为,正如我们都知道的,希望绝对是编程的最佳实践。
KV
Kode Vicious,凡人称之为George V. Neville-Neil,为了乐趣和利润而从事网络和操作系统代码工作。他还教授各种与编程相关的科目。他的兴趣领域是代码探险、操作系统和重写你的坏代码(好吧,也许不是最后一个)。他获得了马萨诸塞州波士顿东北大学计算机科学学士学位,并且是、Usenix协会和IEEE的成员。Neville-Neil是与Marshall Kirk McKusick和Robert N. M. Watson合著的《FreeBSD操作系统的设计与实现》(第二版)的作者之一。他是一位狂热的自行车爱好者和旅行家,目前居住在纽约市。
一段不错的代码
George V. Neville-Neil
色彩鲜明的隐喻和正确地重用函数
https://queue.org.cn/detail.cfm?id=2246038
虚拟化的成本
Ulrich Drepper
软件开发人员需要意识到在使用虚拟化技术时面临的妥协。
https://queue.org.cn/detail.cfm?id=1348591
Unikernels:虚拟库操作系统的崛起
Anil Madhavapeddy 和 David J. Scott
如果虚拟设备中的所有软件层都在同一个安全的高级语言框架内编译,会怎么样?
https://queue.org.cn/detail.cfm?id=2566628
版权所有 © 2017,由所有者/作者持有。出版权已授权给 。
最初发表于 Queue vol. 15, no. 6—
在数字图书馆中评论本文
Catherine Hayes, David Malone - 质疑评估非加密哈希函数的标准
虽然加密和非加密哈希函数无处不在,但在它们的设计方式上似乎存在差距。存在许多受各种安全需求驱动的加密哈希标准,但在非加密方面,存在一定的民间传说,尽管哈希函数历史悠久,但尚未得到充分探索。虽然针对真实世界数据集的均匀分布很有意义,但在面对具有特定模式的数据集时,这可能是一个挑战。
Nicole Forsgren, Eirini Kalliamvakou, Abi Noda, Michaela Greiler, Brian Houck, Margaret-Anne Storey - DevEx 实践
随着领导者在财政紧缩和人工智能等变革性技术的背景下寻求优化软件交付,DevEx(开发者体验)在许多软件组织中越来越受到关注。技术领导者凭直觉接受,良好的开发者体验可以提高软件交付的效率和开发者的幸福感。然而,在许多组织中,旨在改善 DevEx 的拟议倡议和投资难以获得支持,因为业务利益相关者质疑改进的价值主张。
João Varajão, António Trigo, Miguel Almeida - 低代码开发生产力
本文旨在通过展示使用基于代码、低代码和极限低代码技术进行的实验室实验结果,以研究生产力差异,从而为该主题提供新的见解。低代码技术清楚地显示出更高的生产力水平,为低代码在短期/中期内主导软件开发主流提供了强有力的论据。本文报告了程序和协议、结果、局限性和未来研究的机会。
Ivar Jacobson, Alistair Cockburn - 用例至关重要
虽然软件行业是一个快节奏且令人兴奋的世界,其中不断开发新的工具、技术和技巧来服务于商业和社会,但它也很健忘。在其快速前进的匆忙中,它容易受到时尚的异想天开的影响,并且可能会忘记或忽略某些它面临的永恒问题的成熟解决方案。用例,于 1986 年首次引入并在后来普及,就是这些成熟的解决方案之一。