接着分享本人5月(已经过了两个月了,啊啊啊)在农大的slides(完整slide见参考资料4),上次方法综述见与社区共舞:如何追踪Linux内核社区最新动向(之一)这次以体系结构,内存为例分享如何了解社区最新动向。

Meltdown and Spectre

体系结构方面漏洞幽灵/熔断漏洞一共有五个变种(1,2,3,3a,4),这些漏洞的特点是在ISA下面做了侧信道攻击。通常从软件角度看,计算机其实就是ISA。安全也是基于ISA的防御。但是这五个漏洞说明,由于处理器性能的优化,是有可能通过微架构的弱点完成攻击的,漏洞具体情况可以参考如下材料:

这里以幽灵v1为例,说明如何从lwn merge window找到具体的代码。

内核开发流程

内核的开发流程分成merge window和 release candidate(rc)。

所以通常来说一个内核版本的开发周期是10周左右。可以在kernel.org看到最新的版本。例如下图是2018年6月23日的截图,可以看到当前最新版本是4.18 rc1。4.18的两个merge window已经结束。如果想了解4.18内核重大更新,可以参考LWN的merge window文章(参考链接1,参考链接3)。 kernel.org

从LWN Merge window找到具体代码修改

Linux 4.16 merge window part2(参考链接1)的Security-related部分提到:

Initial mitigations for Spectre variant 1 (bounds-check bypass) have been merged; see this article for details. The core of this support is a new array_index_nospec() macro that prevents speculation that might cause a bounds check to be circumvented.
The arm64 architecture has gained another set of Meltdown/Spectre mitigations. The array_index_nospec() operator is supported natively, and it has been applied in a few places in the kernel. Branch-predictor hardening has been improved as well.
S390 has also gained an implementation of array_index_nospec(), support for some new instructions to control branch prediction, and a variant on the retpoline concept called an “expoline”.

咱们来看看到底x86和arm64架构下,到底上面提到的array_index_nospec()是怎么写的。git log --oneline --grep array_index_nospec可以看到一些补丁: git_log_array_index_nospec

但是这里面没有上文提到的arm64和s390补丁。很奇怪吧。先看看最新的两个补丁:

可以想象,体系结构相关的优化可能在array_index_mask_nospec,所以我们用如下git命令同时搜索上述两个字符串: git log --oneline --grep "\(array_index_nospec\)\|\(array_index_mask_nospec\)”,这次能看到arm64和s390相关的补丁了。 git_log_array_index_nospec_and_array_index_mask_nospec

从上面的commit id(就是左侧12位的字母数字组合)可以看到x86和arm64补丁都做了什么:

Merge commits了解一下

上面分析的起点是LWN的文章,还是依赖别人整理过的资料。如何从git提交历史中直接找到这些信息呢?

看4.16分支里面和Spectre相关的merge commits: git log --grep [Ss]pectre --merges v4.16

git_log_spectre_merge_commit可以看到这个Merge合入了上述修改,小伙伴可以试着从这个Merge入手找到上面的commits。

PS: 这次Meltdown and Spectre对业界有很大震动,最近的google I/O和2018年图灵奖演讲都提到了这个漏洞。图灵奖演讲具体内容可以参考笔者的笔记:2018图灵奖Lecture:计算机体系结构的又一个黄金时代:特定领域的软硬件协同设计,增强安全,开源指令集和芯片的敏捷开发

memory子系统引入了新的flag

4.17内核引入了一个新的flag:MAP_FIXED_NOREPLACE。原先内核有个类似的flag“MAP_FIXED”,这个flag的作用是按用户要求在用户指定虚拟地址做映射,如果此处已有映射,会先删除之前的映射。原本MAP_FIXED的目的是给用户空间提供一个可控的虚拟地址映射方式。对于一个规划好的系统,可以保证没有冲突。可是问题在于,系统升级时系统原有映射的地址可能有变化,导致和MAP_FIXED映射的地方有冲突,于是原本系统的映射被干掉了,笔者原来在华为支撑产品线内核升级时,就遇到了类似的情况,现象很莫名其妙。MAP_FIXED_NOREPLACE保证不会替换该虚拟地址的已有映射。这次系统的提交信息如下,笔者不列出具体来源了,请小伙伴自己寻找:

The mmap() system call supports a new MAP_FIXED_NOREPLACE option. Like MAP_FIXED, it tries to place the new memory region at a user-supplied address.  Unlike MAP_FIXED, though, it will not replace an existing mapping at that address; instead, it will fail with EEXIST if such a mapping exists. This is the change that was discussed last year as MAP_FIXED_SAFE; it seems that the battle over the proper name for the feature has finally been resolved.
The way that system calls are invoked on the x86-64 architecture has been reworked to make it more uniform and flexible. The new scheme has also been designed to prevent unused (but caller-controlled) data from getting onto the call stack — where it could perhaps be used in a speculative-execution attack.

具体修改很简单:

map_fixed_noreplace

参考链接

  1. Linux 4.16 merge window:
    1. part1: https://lwn.net/Articles/746129/
    2. part2: https://lwn.net/Articles/746791/
  2. Linux 4.16 Changes:https://www.phoronix.com/scan.php?page=article&item=linux-416-changes&num=1
  3. Linux 4.17 merge window:
    1. Part1: https://lwn.net/Articles/750928/
    2. Part2: https://lwn.net/Articles/751482/
  4. Linux 4.18 merge window:
    1. Part1: https://lwn.net/Articles/756898/
    2. Part2: https://lwn.net/Articles/757187/
  5. 笔者的完整slide:<aarch64.me/public/documents/bamvor_slides/Recent_Linux_kernel.pdf>

你可能感兴趣的文章

这是本月的第一篇原创文章。半瓦平时有随手记笔记的习惯,公众号原创文章只分享自己有体会的信息,希望能促进价值信息流动。任何建议欢迎给我留言或添加我的微信(公众号回复“微信”,可以看到半瓦的微信):