Jonathan Corbet 发布的文章

Rust for Linux 这个项目是希望今后可以使用 Rust 编程语言来编写内核代码,该项目已经进行了几年,有越来越多的开发者认为是时候将这项工作合并到主线中了。在 2022 年的 Linux 内核维护者峰会上,Miguel Ojeda 向大家更新了此项目的最新状况,希望能达成一致来确定何时可以完成合并。

他得到的答案是很清晰的:内核中确实很快会有 Rust 了。

这方面并没有什么悬念。Linus Torvalds 在会议开始时就说,他计划接受(可能在 12 月中旬发布的) 6.1 内核的 Rust 补丁,除非他听到强烈的反对意见。Ojeda 表示,他很期待这一天,并询问这些补丁应该如何进入主线。Torvalds 说,他不愿意直接接受这些补丁,所以看起来很可能需要 Kees Cook 来将这项工作引向上游。

Dave Airlie 说,有一些 MacBook 驱动程序的开发者打算用 Rust 来做他们的工作,所以很可能在不久之后就会有真正的 Rust 驱动程序进入上游了。不过,Torvalds 说他希望最开始只合入尽量少的内容,只是让基础设施先进入内核,让开发者开始使用它。它应该可以完成编译,但应该基本仅限在 “hello, world” 这种水平就好。他说,这将是一个向世界发出的信号:“终于落地了”。

Greg Kroah-Hartman 问道,针对特定子系统的 Rust 绑定实现,该如何进入上游;是应该通过 Rust 树还是通过相关子系统的维护者?Ojeda 回答说,Rust 核心支持应该通过 Rust 树来合入,但其他的应该经过维护者来合入。Alexei Starovoitov 担心,如果子系统维护者不想在他们的子系统中使用 Rust,他们也无法拒绝 Rust 补丁;James Bottomley 补充说,对于长期从事 C 语言开发的人来说,Rust 可能是一种很难理解的语言,把它强加给维护者并不合适。Torvalds 回答说,这应该由维护者决定;目前没有必要制定统一的规则。

Paolo Bonzini 说,对于不熟悉该语言的开发者来说,针对特定子系统实现抽象层的 Rust 代码往往是最难读懂的,“but it's stupid code”,并没有做什么复杂的动作。驱动程序级的 Rust 代码则要简单易懂得多。Torvalds 重申,就目前而言,维护者将可以说他们不想接受 Rust。但 Starovoitov 反驳说,无论他如何决定,BPF 都会受到影响;开发者需要能够对 Rust 代码进行跟踪 来调试问题。他补充说,每个人最终都会需要了解 Rust。Torvalds 回答说,他预计这个过程需要几年时间。

Cook 说,这种变化将类似于内核所经历的许多 C 语言变动。停止使用可变长度数组也是一个类似的过程,开发人员目前已经习惯了这一点。Torvalds 说,这其实更加类似于 BPF 的引入过程;这也是一种新的语言,起初是针对特定使用场景的,但现在已经无处不在了。

Ted Ts'o 指出,内核必须使用不稳定的 Rust 功能,这就导致不好确定应该使用 Rust 的哪个版本了。也许开发者应该宣布一个特定版本的编译器作为内核开发所使用的版本?这将鼓励发行版提供商把这个版本打包发行出来,使其得以更广泛地被采用。Thomas Gleixner 说,在 kernel.org 上提供我们选定的编译器应该就够了,但 Torvalds 回答说,只要有可能,他都希望优先从发行版提供商那里获取编译器。Bottomley 问道,Rust 什么时候会成为内核编译的必备条件;答案是 “当某人需要使用的硬件需要 Rust 的时候”。Torvalds 说,如果这一天到来了,那说明 Rust 在内核开发领域是非常成功的了。

Gleixner 问 Rust 语言现在的规范性如何;Ojeda 回答说,这取决于人们希望用什么。Rust 保证了稳定功能都可以向后兼容,所以这些功能不会意外不能用了。不过,内核正在使用一些不稳定的功能;这些功能出现变动是很有可能的。目前正在做的工作就是把这些功能稳定下来,以便让内核能够稳定地使用它们。

目前正在努力为 Rust 编写一个强调安全的系统的规范,这会最终得到一个类似于标准的文档。不过 Ojeda 说目前基于 GCC 的 gccrs Rust 编译器的开发者发现当前的文档有些地方比较模糊。其中经常把相关行为定义为 “参考 rustc 编译器的实现方式”。他说,这 “不是好事”,但会继续改善。

Gleixner 还询问了生成 Rust 绑定的工具,尤其是有没有自动化工具来确保 Rust 和 C 版本的数据结构是相互匹配的。Ojeda 说,这些工具确实存在,但它们还不能成功地对所有类型完成自动转换。这也是可以解决的。

最后,Gleixner 告诫 Rust 开发者不要改变 C 语言中锁定原语的语义;目前看来大家也没有表现出这样的倾向。Ts'o 补充说,应该从一开始就让 Rust 的锁定抽象能跟 lockdep 这个锁定检查工具配合起来。Chris Mason 插话说,如果 Rust 代码需要 lockdep,这将是该语言成功的另一个标志,是时候 “跳个舞庆祝胜利” 了。

人们经常说,将 Rust 合并到内核代码树中还是一个实验性质的动作;如果不成功就可以删除掉。Ojeda 说,为 Rust for Linux 工作的开发者们想知道试验期可能会有多长。不过,他并没有从这个小组讨论中得到切实的答案。

相反,Bottomley 建议说,与其引入 Rust,不如直接将更多类似 Rust 的功能移入 C 语言。Ojeda 说,他实际上一直在与 C 语言委员会合作来推动这些改进,但这方面的任何变动如果能够落实,也需要很长的时间。Christoph Hellwig 说,除非计划用 Rust 重写整个内核,否则这种改动无论如何都得去做;他对使用一种新的语言来重写已经能正常工作的代码的方案不是很满意。他说,也许 sparse 静态分析工具可以加强一下,从而实现更多 Rust 可以做到的检查。Ojeda 回答说,这种做法最终的效果就像是又获得了一个 Rust 一样——但时间上要晚很多。

Hellwig 继续说,可以随着时间的推移,来逐步采用类似 Rust 的一些功能。这 “必定是不如从 Rust 开始”,但内核社区现在有一个庞大的代码库需要管理。他说,需要有一种方法将类似 Rust 的语言的好处纳入所有的 C 代码中。Cook 说他一直在推动编译器开发人员来创建更安全的 C 语言。

Ts'o 在会议结束时指出,语言设计本身就是一个耗时很长的研究项目;也许我们大家应该在下一年来专注于策略问题。Torvalds 说,他希望看到各位维护者能运行一些持续集成测试并且加入 Rust 相关的测试——这个情况其实已经在进行中了。Laurent Pinchart 说,Rust 开发者需要准备好前期需要给内核社区提供支持;开发者会很快掌握一些技能,在一段时间后应该可以开始相互帮助了。Torvalds 补充说,Rust 其实并不是那么可怕的;“毕竟不是 Perl”。

当被问及文档问题时,Ojeda 说,Rust 的开发者正试图改进一些相应的 C 语言中已经完成了的文档。例如,可以让 Rust 的文档机制能很简单地就确保这些例子是可以被实际测试通过的。他们正在遵守关于应如何解释不安全区块的规则。

时间不够了,Matthew Wilcox 最后问道,内核开发人员是否应该编写地道的 Rust 代码,还是说应该写 “C in Rust”。Ojeda 回答说,这些代码在开始时可能更像 C 语言;采用更高级的功能(如 async)可能会需要更长时间。Gleixner 问,怎样才能防止开发者使用那些不稳定的特性(是说等内核使用的特性已经变成稳定特性之后);答案是指定内核开发时使用的编译器版本。

4 月 20 日,全世界都知道了明尼苏达大学(UMN)进行的一项研究计划,该计划涉及提交有意的错误补丁以纳入 Linux 内核。从那时起,由这项工作产生的一篇论文被撤回了,各种信件来来回回,来自 UMN 的许多补丁被审计。显然,现在是时候对情况进行更新了。

LCTT 译注:明尼苏达大学“伪君子提交”这件事引发了开源和技术社区的很多争议,我们也一直关注此事,本文是 LWN 编辑对事件后继发展的总结和观点。

关于这项研究的论文的撰写并不是最近事件的直接原因;相反,它是由 UMN 的另一位开发者发布的一个源于实验性静态分析工具的错误补丁引起的。这导致内核社区的开发者怀疑,提交故意恶意补丁的工作仍在进行。情况显然不是这样的,但当整个故事变得清晰时,讨论已经全面进行了。

LCTT 译注:提交“实验性静态分析工具的错误补丁”的开发者也是 UMN “伪君子提交”研究团队的成员,只是按该团队的说法,“伪君子提交”研究已经结束,最近引发争议的补丁来自另外一个项目。

老话仍然适用:不应该把那些可以充分解释为无能的东西归结为恶意。

4 月 22 日,Linux 基金会技术顾问委员会(TAB,写作本文的 LWN 编辑是该委员会的成员)发表了一份简短的声明,指出,除其他事项外,最近的补丁似乎是真诚地提交的。同时,Linux 基金会和 TAB 给 UMN 的研究人员发了一封信,概述了应该如何处理这种情况;该信没有公开发布,但 ZDNet 显然从某个地方得到了一份副本。除其他事项外,信中要求完全公开作为 UMN 项目的一部分而发送的错误补丁,并要求撤回这项工作所产生的论文。

作为回应,UMN 的研究人员发布了一封公开信,向社区道歉,几天后又发布了他们作为“伪君子提交”项目的一部分所做工作的总结。总共有五个补丁是从两个 sock-puppet 账户提交的,但其中一个是普通的 bug 修复,被错误地从这个错误的账户发送。在剩下的四个补丁中,其中一个是试图插入一个 bug,但是它本身没插入成功,所以这个补丁实际上是有效的;另外三个(123)包含真正的 bug,这三个都没有被维护者接受,尽管拒绝的原因不一定是有关的 bug。

LCTT 译注:根据 UMN 团队发布的总结:

  • 第一个补丁是以“伪君子提交”而发出的,但是后来实际检查发现实际解决了问题,于是 UMN 团队就没有阻止该补丁被合入。
  • 第二个补丁没有合入,但是内核维护者说之前有个别人的类似实现的补丁合并过,后来发现有问题而被别人撤销了。
  • 第三个补丁没有合入,内核维护者发现了一个问题而没有接受,但是其实该补丁还有另外一个问题并没有被发现。
  • 第四个补丁没有合入,和上一个类似,内核维护者没有发现有意放入的缺陷,而是找到另外的编码问题,因此没有合入。
  • 第五个补丁是有效的补丁,但不是这个项目的,使用了错误的邮箱发出的。

论文本身已被撤回,不会按原计划在 5 月提交。希望大家可以认为 UMN 在短期内不会再进行类似的研究了。

LCTT 译注:在原文下面有不少评论认为这个研究方向应该继续下去,只是方式方法需要改善。

补丁的重新审查

UMN 活动引起的关注的一个直接结果是,人们对其开发者失去了信任,加上某些方面希望采取某种惩罚性行动。因此,当整个事件爆发时,首先发生的事情之一是 Greg Kroah-Hartman(GKH)发布了一个由 190 个部分组成的补丁系列,以撤销他能找到的尽可能多的 UMN 的补丁。事实上,这并不是所有的补丁;他提到了另外 68 个需要人工审查的补丁清单,因为它们不容易撤销。

碰巧的是,这些“容易撤销”的补丁也需要人工审查;一旦最初的愤怒过去,就没有什么愿望去恢复那些实际上没有错误的补丁。在过去的一周里,这种审查过程一直在进行,一些开发人员在为之努力。大多数可疑的补丁被证明是可以接受的(即使不是很好),已经从撤销列表中删除了;如果本文作者的计数是正确的,仍有 42 个补丁将被从内核中撤出。

对于这 42 个补丁,撤销背后的原因各不相同。在某些情况下,这些补丁适用于旧的、可能是未使用的驱动程序,而且没有人愿意去适当地审查它们。在其他情况下,其希望实现的变更做得很差,将以更好的方式重新实现。而有些补丁包含了严重的错误;这些肯定需要被恢复(而且一开始就不应该被接受)。

不过,看一下全套的 UMN 补丁,印证了一些我们的早期印象。首先,几乎所有的补丁都解决了某种真正的(即使是晦涩难懂的且难以解决)问题;为之写一个补丁是有理由的。虽然这些补丁中有许多显示出对代码的理解程度很低,因此包含了错误,但似乎其中任何一个修复程序的意图都不大可能是恶意的。

也就是说,“恶意”有多种定义。对一些相关的开发者来说,发布未经验证的实验性静态分析工具的补丁而不披露其性质是一种恶意行为。这是另一种涉及未经同意的人类的实验形式。至少,这是对内核开发社区有效工作所需的信任的一种侵犯。

LCTT 译注:如果研究涉及到人类,为了避免人类受到伤害,需要取得人类同意,这就是研究需要得到 IRB 许可的原因。UMN 认为 “伪君子提交” 不是针对人类的研究,给予了 IRB 免除许可。在这个事件中,有人对 UMN IRB 的意见也很大,而且怀疑 IRB 是否有能力对计算机相关研究给出有效判断。

这 190 个补丁中有 42 个坏补丁,坏补丁比率是 22%。很有可能,对几乎任何一个内核开发者的 190 个补丁进行详细审查,都会发现一些回想起来并不是一个好主意的补丁。但愿这个比率不会接近 22%。但必须说的是,所有这些补丁都被整个内核的子系统维护者所接受,这不是一个好的结果。也许这比最初的“伪君子提交”的研究人员所寻找的结果更有意思。他们故意插入 bug 的努力失败了,但却在无意中增加几十个 bug

同时,还有一份不能干净地撤销的补丁清单。这个名单还没有公布,但 GKH 是从其中的七个子集开始的。他还指出,TAB 将在所有这些补丁的审计工作完成后公布一份完整的报告。到目前为止,这些补丁中还没有任何一个在主线上被撤销;这似乎有可能在 5.13 合并窗口结束时发生。

吸取的教训

从这一系列事件中得到的关键教训之一显然是:不要把自由软件开发社区作为你的实验性工具的一种免费验证服务。内核开发者很高兴看到新工具的产生,并且 —— 如果这些工具能带来好的结果 —— 就使用它们。他们也会帮助测试这些工具,但他们不太乐意成为缺乏适当审查和解释的工具产生的补丁的接受者。

另一个教训是我们已经知道的:内核维护者(以及许多其他自由软件项目的维护者)工作压力过度,没有时间正确地审查经过他们手中的每一个补丁。因此,他们不得不依赖向他们提交补丁的开发者的可信度。可以说,当这种信任得到妥善建立时,内核开发过程是勉强可持续的;如果通常无法信任进入的补丁时,那么它将无法维持下去。

推论 —— 也是我们已经知道的 —— 是进入内核的代码往往不像我们所想的那样得到很好的审查。我们希望相信每一行被合并的代码都经过了高质量的内核开发人员的仔细审查。有些代码确实得到了这种审查,但不是所有的代码。例如,考虑一下 5.12 开发周期(一个相对较小的周期),它在十周的时间里向内核添加了超过 50 万行的代码。仔细审查 50 万行代码所需的资源将是巨大的,因此,不幸的是,其中许多行在被合并之前只得到了粗略的审查而已。

最后一个教训是,人们可能倾向于认为内核正面临着被具有比 UMN 研究人员所展示的更多技能和资源的行为者插入恶意补丁的可怕风险。这可能是事实,但事情的简单真相是,正规的内核开发者继续以这样的速度插入错误,恶意行为者应该没有什么必要增加更多。2 月份发布的 5.11 内核,到 5.11.17 为止,在稳定更新中已经积累了 2281 个修复。如果我们做一个(过于简单的)假设,即每个修复都会修正一个原始的 5.11 补丁,那么进入 5.11 的补丁中有 16%(到目前为止)被证明是有错误的。这并不比 UMN 补丁的比率好多少。

所以,这也许是我们从整个经历中得到的真正教训:内核处理流程的速度是它最好的属性之一,我们都依赖它来尽可能快地获得功能。但是这种速度可能与严肃的补丁审查和低数量的错误不相容。在一段时间内,我们可能会看到处理变得有点慢,因为维护者觉得有必要更仔细地审查变化,特别是那些来自新的开发人员。但是,如果我们不能将更谨慎的处理流程制度化,我们将继续看到大量的 bug,而这些 bug 是否是故意插入的,其实并不重要。


via: https://lwn.net/SubscriberLink/854645/334317047842b6c3/

作者:Jonathan Corbet 译者:wxy 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

英特尔处理器曝出了一个严重的硬件设计漏洞,迫使包括 Linux、Windows 在内的主要操作系统和各大云计算服务商都忙着打补丁。因为漏洞信息没有解密,所以目前只能通过已发布的补丁反推这个漏洞

这里是一篇对该漏洞的技术分析文章。

在十月底的时候,KAISER 补丁集被披露了;它做了一项工作,将内核空间与用户空间使用的 页表 page tables 进行了隔离,以解决 x86 处理器上向攻击者透露内核布局的安全漏洞。这些补丁是自它们被公布以来,这一星期中最值关注的事情,但是,它们似乎正在接近最终的状态。这应该是再次审视它们的合适机会。

这项工作被重命名为 “ 内核页表隔离 kernel page-table isolation ” (KPTI),但是目的是一样的:分割页表,将现在被用户空间和内核空间共享使用的这张表分成两套,内核空间和用户空间各自使用一个。这对内核的内存管理产生了根本性的变化,并且,这是本来人们期望先争论多年再做决定的,尤其是考虑到它的性能影响的时候。不过,KPTI 仍然处于快速发展的轨道上。一组预备补丁 已被被合并到 4.15 - rc4 之后的主版本线上了 — 一般情况下仅重要的修复才被允许这样做 — 并且其余的似乎被确定进入 4.16 版的合并窗口中。许多内核开发者都在这项工作上投入了大量的时间,并且 Linus Torvalds 要求 将这项工作 回迁 backport 到长期稳定内核中。

也就是说,KPTI 已经在最后期限的压力下安全补丁的所有标记都已经就绪了。对于任何基于 ARM 的读者,在这里值的注意的是,在这项工作中有一个 为 arm64 的等效补丁集

51 个补丁乃至更多

在这篇文章中,x86 补丁系列正处在 163 版本。它包含 51 个补丁,因此,我们应该感谢那些没有公开的版本。最初的补丁集,由 Dave Hansen 发布,由 Thomas Gleixner、Peter Zijlstra、Andy Lutomirski、和 Hugh Dickins 根据许多其它人的建议,做了大量的修订。任何还存在的缺陷都不是由于没有足够多的有经验的开发人员过目所导致的。

在现代系统中,页表是以一个树形结构进行组织的,这样可以高效地存储稀疏内存映射和支持巨页特性;可以查看这篇 2005 年的文章 了解更多细节以及它是怎么工作的示意图。在一个有四级页面表的系统上(目前的大多数大型系统都是这样),顶级是页面全局目录(PGD)。紧接着是页面上层目录(PUD)、页面中层目录(PMD)和页面表条目(PTE)。有五级页面表的系统是在 PGD 下面插入了一层(称为 P4D)。

页面故障解析通常遍历整个树去查找所需的 PTE,但是,巨页可以被更高层级的特定条目所表示。例如,一个 2MB 的内存 chunk 既可以由 PMD 层级的一个单个的巨页条目表示,也可以由一个单页 PTE 条目的完整页面表示。

在当前的内核中,每个处理器有一个单个的 PGD;在 KPTI 系列补丁中所采取的第一步的其中一个措施是,去创建一个第二个 PGD。当内核运行时,原来的仍然在使用;它映射所有的地址空间。当处理器运行在用户空间时,(在打完该系列补丁之后)第二个被激活。它指向属于该进程的页面的相同目录层次,但是,描述内核空间(位于虚拟地址空间的顶端)的部分通常都不在这里。

页表条目包含权限描述位,它们记录了内存该如何被访问;不用说都知道,这些位是用来设置阻止用户空间访问内核页面的,即便是通过那些被映射到该地址空间的页面访问。不幸的是,一些硬件级的错误允许用户空间的攻击者去确定一个给定的内核空间地址是否被映射,而不管那个页面上映射的地址是否被允许访问。而那个信息可以被用于击败内核地址空间布局随机化,可以使一个本地的攻击者更易于得逞。在 KPTI 背后的核心思想是,切换到一个没有内核空间映射的 PGD,将会使基于这个漏洞的攻击失效,而到现在为止,我们还没有看到这些攻击。

细节

这个想法很简单,但是,就像经常发生的那样,有各种各样麻烦的细节使得这个简单的想法变成了一个由 51 个部分构成的补丁集。其中最初的一个是,如果处理器在用户模式运行时响应一个硬件中断,处理中断需要的内核代码将在地址空间中不存在。因此,必须有足够的内核代码映射在用户模式中,以能够切换回到内核 PGD,使剩余的代码也可用。对于 traps、非屏蔽中断、和系统调用,也存在一个相似的情况。这个代码很小而且可以与其它部分隔离,但是,在处理安全且有效地切换时,涉及到一些很复杂的细节。

另一个难题来自 x86 本地描述符表(LDT)的构成,它可以被用于去改变用户空间的内存布局。它可以使用鲜为人知的 modify_ldt() 系统调用来做微调。例如,在 Linux 上早期的 POSIX 线程实现,使用了 LDT 去创建一个本地线程存储区域。在现在的 Linux 系统上,LDT 几乎不再使用了,但是,一些应用程序(比如,Wine)仍然需要它。当它被使用时,LDT 必须能够被用户空间和内核空间都可以访问到,但是,它必须一直处于内核空间中。KPTI 补丁集打乱内核附近的内存,在 PGD 级别上为 LDT 保留一个完全的条目;因此,vmalloc() 调用的可用空间收缩到仅有 12,800TB。那是一个非常巨大的 LDT 空间数,可以满足有很多 CPU 系统的需要。这种变化的其中一个结果是,LDT 的位置将是固定的,并且已知道用户空间 ——因此这将是个潜在的问题,由于覆写 LDT 的能力很容易被用来破坏整个系统。在这个系列的最终的补丁是映射为只读 LDT,以阻止此类攻击。

另一个潜在的安全缺陷是,如果内核可以一直被操纵直至返回用户空间,以至于不切换回经过过滤的 PGD。因为内核空间 PGD 也映射用户空间内存,这种疏忽可能在一段时间内不会被察觉到。对此问题的应对方法是将虚拟内存空间中用户空间的部分以非可执行的方式映射到内核的 PGD。只要用户空间(的程序)开始从一个错误的页面表开始执行,它将会立即崩溃。

最后,虽然所有已存在的 x86 处理器似乎都会受到这个信息泄露的漏洞影响,但是,以后的处理器可能不会受此影响。KPTI 有一个可测量的运行时成本,估计在 5%。有些用户也许不愿意为这些成本埋单,尤其是他们拿到了不存在这个问题的新处理器之后。为此将会有一个 nopti (内核)命令行选项来在启动的时候禁用这个机制。这个补丁系列也增加了一个新的“特性”标识(X86_BUG_CPU_INSECURE)去标识有漏洞的 CPU;它被设置在现在所有的 x86 CPU 上(LCTT 译注:AMD 表示不背这锅),但是在以后的硬件上可能没有。如果没有该特性标识,页面隔离将自动被关闭。

在 4.16 版的合并窗口打开之前剩下将近一个月。在这期间,针对一些新发现而不可避免的小毛病,KPTI 补丁集毫无疑问的将迎来一系列的小修订。一旦所有的事情都敲定了,看起来这些代码将会被合并同时以相对快的速度迁回到稳定版本的内核。显而易见的是,我们将会收到一个更慢,但是更安全的内核作为一个新年礼物。


via: https://lwn.net/SubscriberLink/741878/eb6c9d3913d7cb2b/

作者:Jonathan Corbet 译者:qhwdw 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

欢迎来到 Linux 天气预报

本页面是为了跟踪在不久的将来某个时间内有可能出现在主线内核和/或主要发行版中的 Linux 开发社区的进展情况。你的“首席气象学家”是 LWN.net 执行主编 Jonathan Corbet。如果你有改进预测的建议(特别是如果你有一个你认为应该跟踪的项目或修补程序的情况下),请在下面补充你的意见。

预测摘要

当前情况:内核 4.12 于 7 月 2 日发布。它包含了许多新功能,包括:

  • BFQ 和 Kyber 块 I/O 调度器。已经开发多年的 BFQ 在交互式系统上表现更好,这引起了移动设备领域的兴趣。相反,Kyber 是一个更简单的调度程序,旨在用于通常出现在企业配置中的快速设备。
  • epoll\_wait() 系统调用现在可以执行网络套接字的繁忙轮询。
  • 实时修补机制已经实现了混合一致性模型,这将可以把更复杂的补丁应用于运行中的内核。
  • 可信执行框架应该使得内核与在 ARM TrustZone 安全世界中运行的代码之间的交互更加容易。

4.12 是最繁忙的内核开发周期之一,合并了近 15000 次更新。有关这些变化来源的概述,请参阅这里

短期预测:4.13 内核预期在 2017 年 9 月初发布。这个内核中会出现的一些变化是:

4.13 内核现在处于稳定时期,所以在这个开发周期的剩余时间内只会接受修复补丁。

这篇文章根据知识共享署名 - 共享 3.0 许可证获得许可。


via: https://www.linux.com/news/2017/7/linux-weather-forecast

作者:JONATHAN CORBET 译者:geekpi 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

从各方面来看,互联网向 IPv6 的过渡是件很缓慢的事情。不过在最近几年,可能是由于 IPv4 地址资源的枯竭,IPv6 的使用处于上升态势。相应的,开发者也有兴趣确保软件能在 IPv4 和 IPv6 下工作。但是,正如近期 OpenBSD 邮件列表中的讨论所关注的,一个使得向 IPv6 转换更加轻松的机制设计同时也可能导致网络更不安全——并且 Linux 发行版们的默认配置可能并不安全。

地址映射

IPv6 在很多方面看起来可能很像 IPv4,但它是一个不同地址空间的不同的协议。服务器程序想要接受使用二者之中任意一个协议的连接,必须给两个不同的地址族分别打开一个套接字——IPv4 的 AF_INET 和 IPv6 的 AF_INET6。特别是一个程序希望在主机上的使用两种地址协议的任意接口都接受连接的话,需要创建一个绑定到全零通配符地址(0.0.0.0)的 AF_INET 套接字和一个绑定到 IPv6 等效地址(写作 ::)的 AF_INET6 套接字。它必须在两个套接字上都监听连接——或者有人会这么认为。

多年前,在 RFC 3493,IETF 指定了一个机制,程序可以使用一个单独的 IPv6 套接字工作在两个协议之上。有了一个启用这个行为的套接字,程序只需要绑定到 :: 地址从而在所有接口上接受使用这两个协议的连接。当创建了一个 IPv4 连接到该绑定端口,源地址会像 RFC 2373 中描述的那样映射到 IPv6。所以,举个例子,一个使用了这个模式的程序会将一个 192.168.1.1 的传入连接看作来自 ::ffff:192.168.1.1(这个混合的写法就是这种地址的通常写法)。程序也能通过相同的映射方法打开一个到 IPv4 地址的连接。

RFC 要求默认实现这个行为,所以大多数系统这么做了。不过也有些例外,OpenBSD 就是其中之一;在那里,希望在两种协议下工作的程序能做的只能是创建两个独立的套接字。但一个在 Linux 中打开两个套接字的程序会遇到麻烦:IPv4 和 IPv6 套接字都会尝试绑定到 IPv4 地址,所以不论是哪个,后者都会失败。换句话说,一个绑定到 :: 指定端口的套接字的程序会同时绑定到那个端口上的 IPv6 的 :: 和 IPv4 的 0.0.0.0 地址。如果程序之后尝试绑定一个 IPv4 套接字到 0.0.0.0 的相同端口上时,这个操作会失败,因为这个端口已经被绑定了。

当然有个办法可以解决这个问题;程序可以调用 setsockopt() 来打开 IPV6_V6ONLY 选项。一个打开两个套接字并且设置了 IPV6_V6ONLY 的程序应该可以在所有的系统间移植。

读者们可能对不是每个程序都能正确处理这一问题没那么震惊。事实证明,这些程序的其中之一是 网络时间协议 Network Time Protocol OpenNTPD 实现。Brent Cook 最近给上游 OpenNTPD 源码提交了一个小补丁,添加了必要的 setsockopt() 调用,它也被提交到了 OpenBSD 中了。不过那个补丁看起来不大可能被接受,最可能的原因是因为 OpenBSD 式的理由(LCTT 译注:如前文提到的,OpenBSD 并不受这个问题的影响)。

安全担忧

正如上文所提到,OpenBSD 根本不支持 IPv4 映射的 IPv6 套接字。即使一个程序试着通过将 IPV6_V6ONLY 选项设置为 0 来显式地启用地址映射,它的作者也会感到沮丧,因为这个设置在 OpenBSD 系统中无效。这个决定背后的原因是这个映射带来了一些安全隐忧。攻击打开的接口的攻击类型有很多种,但它们最后都会回到规定的两个途径到达相同的端口,每个端口都有它自己的控制规则。

任何给定的服务器系统可能都设置了防火墙规则,描述端口的允许访问权限。也许还会有适当的机制,比如 TCP wrappers 或一个基于 BPF 的过滤器,或一个网络上的路由器可以做连接状态协议过滤。结果可能是导致防火墙保护和潜在的所有类型的混乱连接之间的缺口造成同一 IPv4 地址可以通过两个不同的协议到达。如果地址映射是在网络边界完成的,情况甚至会变得更加复杂;参看这个 2003 年的 RFC 草案,它描述了如果映射地址在主机之间传播,一些随之而来的其它攻击场景。

改变系统和软件正确地处理 IPv4 映射的 IPv6 地址当然可以实现。但那增加了系统的整体复杂度,并且可以确定这个改动没有实际地完整实现到它应该实现的范围内。如同 Theo de Raadt 说的

有时候人们将一个糟糕的想法放进了 RFC。之后他们发现这个想法是不可能的就将它丢回垃圾箱了。结果就是概念变得如此复杂,每个人都得在管理和编码方面是个全职专家。

我们也根本不清楚这些全职专家有多少在实际配置使用 IPv4 映射的 IPv6 地址的系统和网络。

有人可能会说,尽管 IPv4 映射的 IPv6 地址造成了安全危险,更改一下程序让它在实现了地址映射的系统上关闭地址映射应该没什么危害。但 Theo 认为不应该这么做,有两个理由。第一个是有许多破旧的程序,它们永远不会被修复。而实际的原因是给发行版们施加了压力去默认关闭地址映射。正如他说的:“最终有人会理解这个危害是系统性的,并更改系统默认行为使之‘secure by default’。”

Linux 上的地址映射

在 Linux 系统,地址映射由一个叫做 net.ipv6.bindv6only 的 sysctl 开关控制;它默认设置为 0(启用地址映射)。管理员(或发行版们)可以通过将它设置为 1 来关闭地址映射,但在部署这样一个系统到生产环境之前最好确认软件都能正常工作。一个快速调查显示没有哪个主要发行版改变这个默认值;Debian 在 2009 年的 “squeeze” 中改变了这个默认值,但这个改动破坏了很多的软件包(比如任何包含 Java 的程序),在经过了几次的 Debian 式的讨论之后,它恢复到了原来的设置。看上去不少程序依赖于默认启用地址映射。

OpenBSD 有以“secure by default”的名义打破其核心系统之外的东西的传统;而 Linux 发行版们则更倾向于难以作出这样的改变。所以那些一般不愿意收到他们用户的不满的发行版们,不太可能很快对 bindv6only 的默认设置作出改变。好消息是这个功能作为默认已经很多年了,但很难找到被利用的例子。但是,正如我们都知道的,谁都无法保证这样的利用不可能发生。


via: https://lwn.net/Articles/688462/

作者:Jonathan Corbet 译者:alim0x 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

Linux 内核开发很少吸引像华盛顿邮报这样主流媒体的关注,内核社区在安全方面进展的冗长功能列表就更少人看了。所以当这样一个专题发布到网上,就吸引了很多人的注意(LCTT 译注:华盛顿邮报发表了一篇很长的专题文章,批评 Linux “没有一个系统性的机制以在骇客之前发现和解决安全问题,或引入更新的防御技术”,“Linux 内核开发社区没有一个首席安全官”等等)。关于这篇文章有不同的反应,很多人认为这是对 Linux 直接的攻击。文章背后的动机很难知道,但是从历史经验来看,它也可以看作对我们早就该前进的方向的一次非常必要的推动。

回顾一件昏暗遥远过去的事件 - 确切地说是在 1999 年 4 月。一家叫 Mindcraft 的分析公司发布了一份报告显示 Windows NT 在 Web 服务器开销方面完胜 Red Hat Linux 5.2 加 Apache。Linux 社区,包括当时还很年轻的 LWN,对此反应很迅速而且强烈。这份报告是微软资助的 FUD 的一部分,用来消除那些全球垄断计划的新兴威胁。报告中所用的 Linux 系统有意配置成低性能,同时选择了当时 Linux 并不能很好支持的硬件,等等。

在大家稍微冷静一点后,尽管如此,事实很明显:Mindcraft 的人,不管什么动机,说的也有一定道理。当时 Linux 确实在性能方面存在一些已经被充分认识到的问题。然后社区做了最正确的事情:我们坐下来解决问题。比如,单独唤醒的调度器可以解决接受连接请求时的惊群问题。其他很多小问题也都解决了。在差不多一年里,内核在这类开销方面的性能已经有了非常大的改善。

这份 Mindcraft 的报告,某种意义上来说,往 Linux 屁股上踢了很有必要的一脚,推动整个社区去处理一些当时被忽略的事情。

华盛顿邮报的文章明显以负面的看法看待 Linux 内核以及它的贡献者。它随意地混淆了内核问题和其他根本不是内核脆弱性引起的问题(比如,AshleyMadison.com 被黑)。不过供应商没什么兴趣为他们的客户提供安全补丁的事实,就像一头在房间里巨象一样明显。还有谣言说这篇文章后面的黑暗势力希望打击一下 Linux 的势头。这些也许都是真的,但是也不能掩盖一个简单的事实,就是文章说的确实是真的。

我们会合理地测试并解决问题。而这些问题,不管是不是安全相关,能很快得到修复,然后再通过稳定更新的机制将这些补丁发布给内核用户。比起外面很多应用程序(自由的和商业的),内核的支持工作做的非常好。但是指责我们解决问题的能力时却遗漏了关键的一点:解决安全问题终究来说是一个打鼹鼠游戏。总是会出来更多的鼹鼠,其中有一些在攻击者发现并利用后很长时间我们都还不知道(所以没法使劲打下去)。尽管 Linux 的商业支持已经非常努力地在将补丁传递给用户,这种问题还是会让我们的用户很受伤 - 只是这并不是故意的。

关键是只是解决问题并不够,一些关心安全性的开发者也已经开始尝试做些什么。我们必须认识到,缺陷永远都解决不完,所以要让缺陷更难被发现和利用。这意思就是限制访问内核信息,绝对不允许内核执行用户空间内存中的指令,让内核去侦测整形溢出,以及 Kee Cook 在十月底内核峰会的讲话中所提出的其他所有事情。其中许多技术被其他操作系统深刻理解并采用了;另外一些需要我们去创新。但是,如果我们想充分保护我们的用户免受攻击,这些改变是必须要做的。

为什么内核还没有引入这些技术?华盛顿邮报的文章坚定地指责开发社区,特别是 Linus Torvalds。内核社区的传统就是相对安全性更侧重于性能和功能,在需要牺牲性能来改善内核安全性时并不愿意折衷处理。这些指责一定程度上是对的;好的一面是,因为问题的范围变得清晰,态度看上去有所改善。Kee 的演讲都听进去了,而且很明显让开发者开始思考和讨论这些问题了。

而被忽略的一点是,并不仅仅是 Linus 在拒绝有用的安全补丁。而是就没有多少这种补丁在内核社区里流传。特别是,在这个领域工作的开发者就那么些人,而且从没有认真地尝试把自己的工作整合到上游。要合并任何大的侵入性补丁,需要和内核社区一起工作,为这些改动编写用例,将改动分割成方便审核的碎片,处理审核意见,等等。整个过程可能会有点无聊而且让人沮丧,但这却是内核维护的运作方式,而且很明显只有这样才能在长时间的开发中形成更有用更可维护的内核。

几乎没有人会走这个流程来将最新的安全技术引入内核。对于这类补丁可能收到的不利反应,有人觉得也许会导致“寒蝉效应”,但是这个说法并不充分:不管最初的反应有多麻烦,多年以来开发者已经合并了大量的改动。而少数安全开发者连试都没试过。

他们为什么不愿意尝试?一个比较明显的答案是,几乎没有人会因此拿到报酬。几乎所有引入内核的工作都由付费开发者完成,而且已经持续多年。公司能看到利润的领域在内核里都有大量的工作以及很好的进展。而公司觉得和它们没关系的领域就不会这样了。为实时 Linux 的开发找到赞助支持的困难就是很明显的例子。其他领域,比如文档,也在慢慢萧条。安全性很明显也属于这类领域。可能有很多原因导致 Linux 落后于防御式安全技术,但是其中最关键的一条是,靠 Linux 赚钱的公司没有重视这些技术的开发和应用。

有迹象显示局面已有所转变。越来越多的开发人员开始关注安全相关问题,尽管对他们工作的商业支持还仍然不够。对于安全相关的改变已经没有之前那样的下意识反应了。像内核自我保护项目这样,已经开始把现有的安全技术集成进入内核了。

我们还有很长的路要走,但是,如果能有一些支持以及正确的观念,短期内就能有很大的进展。内核社区在确定了自己的想法后可以做到很让人惊叹的事情。幸运的是,华盛顿邮报的文章将有助于提供形成这种想法的必要动力。以历史的角度看,我们很可能会把这次事件看作一个转折点,我们最终被倒逼着去完成之前很明确需要做的事情。Linux 不应该再继续讲述这个安全不合格的故事了。


via: https://lwn.net/Articles/663474/

作者:Jonathan Corbet 译者:zpl1025 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出