牙膏挤破了,基础协议漏洞不是那么好修补的哦?网友:慢30%要吃鸡请上九代

据外媒报道,英特尔公司日前爆出了一个处理器的严重漏洞,该漏洞可导致本来单独用于保护密码等重要信息的存储区,可能会让一些软件程序获取权限,这使得过去十年间所有使用英特尔芯片的电脑都受到影响,包括微软公司的 Windows 和苹果公司的 OS X 操作系统。Windows和Linux都正在接受重要的安全更新,这一漏洞修补过程可能导致全球个人电脑性能下降,在最坏的情况下性能可能会下降30%,以抵御尚未完全披露的问题。

在过去的几个星期里,修补Linux内核的补丁已经在不断的进行。而从11月份以来,微软也一直在测试Insider程序中的Windows更新,预计下周二Patch Tuesday将会将这些更新纳入主流Windows版本。据 The Verge 报道,微软目前正式回应表示,将于美国东部时间 1 月 3 日 17 时(北京时间 1 月 4 日早上 6 时)发布紧急更新,并将自动应用于 Windows 10 系统。

从追踪寻址说起

系统中每个字节的内存都是隐含编号的,这些编号就是每个字节的地址。而使用物理内存地址操作系统是最早的操作系统。但物理内存地址由于许多原因而不方便;例如:在地址中经常存在间隙,并且(特别是在32位系统上)物理地址难于操作,需要36位数字者甚至更大的数字。

虚拟内存系统允许程序和内核本身在简单、干净、统一的环境中运行。每个程序和内核本身都使用虚拟地址来访问内存,而不是使用物理地址来弥补缺陷和其他问题。这些虚拟地址是连续的,不需要担心间隙,并且可以方便地调整大小以方便操作。即使物理地址需要36位或更多的编号,32位程序也只能看到32位地址。因此,现代的操作系统都依赖于被称为虚拟内存的广义概念。

虽然虚拟寻址对于几乎每一个软件都是透明的,但是处理器最终还是需要知道虚拟地址指向哪个物理存储器。所以得有一个从虚拟地址到物理地址的映射,并存储在一个称为页表的大型数据结构中。操作系统使用由处理器确定的布局来构建页表,而只要处理器和操作系统需要在虚拟地址和物理地址之间进行转换,他们就会结合使用页表。

整个映射过程对于现代操作系统和处理器来说是非常重要的,所以处理器具有专用的缓存 – 转换后备缓冲区(TLB),它存储一定数量的虚拟到物理映射,以避免每一次使用满页表。TLB并不是非常大 – 通常是几百个映射。系统使用的页表越多,TLB包含任何特定的虚拟 – 物理转换的可能性就越小。

虚拟内存的使用为我们提供了超越寻址的许多简单而又有用功能。其中最主要的是每个单独的程序都有自己的一组虚拟地址,并且有自己的虚拟到物理映射。这是用来提供“受保护的记忆”的基本技术。因为另一个程序的内存不是第一个程序的映射的一部分,所以一个程序不能破坏或篡改另一个程序的内存。

考虑到这一点,如果映射页面是被保护的,那么在做出决定之前,还需要有一些机制来解除保护,以允许代码分支的预测性执行。但从理论上讲,一旦做出决定,分支机构不予采取的结果就应该被废弃,以致所收集的信息不能被使用。也许在预测执行和指令重新排序(尚未提及)的组合中有一些东西允许从管道中稍后提取数据。

这也许就是问题的所在了,但如果是这样的话,那么这就可能是一个设计缺陷,而不是一个bug。

设计缺陷?

为了充分利用TLB,每个主流操作系统都将虚拟地址范围分为两部分:每个程序使用一半的地址;?另一半用于内核。在进程之间切换时,只有一半的页面表项改变——属于程序的项目。而内核的一半对每个程序都是通用的(因为只有一个内核),所以它可以对每个进程使用相同的页表映射。虽然仍然需要丢弃属于进程内存地址一半的映射,但是可以保留内核一半的映射,这对于TLB是一个极大地帮助。

然而这个设计并不完全是一成不变的。在Linux上完成了这个工作,以便为32位进程提供整个地址范围,内核页表和每个程序之间就不共享。虽然这给了程序更多的地址空间,但是却带来了性能成本,因为每次需要运行内核代码时,TLB都必须重新加载内核的页表项。因此,这种方法在x86系统上从未被广泛使用。

在内核和每个程序之间分配虚拟地址空间有一个缺点,就是内存保护功能被削弱了。如果内核拥有自己的一组页表和虚拟地址,那么它将得到与不同程序相同的保护,内核的内存将是简单的不可见的。但是通过拆分寻址,用户程序和内核使用相同的地址范围,原则上用户程序是能够读写内核内存的。

为了防止这种明显不利的情况,处理器和虚拟寻址系统就有了“rings”或“modes”的概念。x86处理器有很多rings,但是对于这个问题,只有两个是与之相关的,分别是:“用户”(ring 3)和“管理员(也称为内核模式)”(ring 0)。在运行常规用户程序时,处理器进入就用户模式(ring 3)。运行内核代码时,处理器则处于管理员模式(ring 0)。

这些 ring 主要用于保护内核内存不受用户程序的影响。页表不仅仅是从虚拟地址到物理地址的映射,它们还包含关于这些地址的元数据,包括有关哪些ring可以访问地址的信息。内核的页表项全部被标记为只能访问ring 0;?该程序的条目被标记为可以从任何ring访问。如果在ring 3中尝试访问ring 0存储器,则处理器阻止访问并产生异常。这样做的结果是,在ring 3中运行的用户程序应该无法获知有关内核及其ring 0内存的任何信息。

内核内存映射到用户模式进程上,就可以允许系统调用(访问硬件/内核服务的请求)执行,而不必切换到另一个虚拟地址空间。如果每个进程都在自己的虚拟地址空间中运行,那么在它们之间切换就是一件相当费劲的事情了;因为它涉及到刷新CPU的转换后备缓冲区(TLB,用于快速查找虚拟内存地址的物理位置)以及其他一些事情。

访问未在TLB中缓存的内存页大约需要200个CPU周期,对缓存项的访问通常少于一个周期。这意味着,对于每一个系统调用,CPU将需要切换虚拟内存上下文,冲洗该TLB将花费相当长的时间。

如果可以在“真实的受保护”模式下运行内核的关键部分(即根本没有虚拟地址转换,但通过使用键或限制寄存器的某种形式的存储器保护),那么可能是合理的。如果没有足够的物理内存来容纳一个内核,那将不会取得太多的进展,而这只是其中许多方面之一,通过这种或那种缓存提高性能会导致潜在的具体执行异常。

漏洞甚至可能不是数据,它可能小到从spec-ex路径的时间变化需要更长的时间或更长的时间,允许攻击者探测内核空间寻找不是/有效的页面 。更糟糕的是,spec-ex分支可能会影响时序的规格化读取秘密数据,而不会直接暴露数据本身。

至少,理论上是这样的。

这个安全漏洞怎么会被滥用?

众所周知的是每个处理器都执行着一定的预测执行。例如,添加一些给定的两位数字,然后将结果存储在内存中的指令,处理器可能会对确定内存中的目标,在是否实际可访问和可写入之前预测性地执行添加。在通常情况下,如果位置是可写的,处理器会设法节省一些时间,就像计算并行算法一样,计算出内存中的目标是什么。如果发现该位置不可访问(例如,试图写入没有映射且完全没有物理位置的地址的程序)就会产生一个异常,并且预测执行也会被浪费。

英特尔处理器允许预测性地执行写入ring 0存储器的ring 3代码。处理器做了正确地阻止写操作,但是预测性的执行很快地干扰了处理器状态,因为某些数据将被加载到缓存和TLB中以确定是否允许写入。这反过来意味着一些操作将会快几个周期,或者几个周期较慢,这取决于它们的数据是否仍然在缓存中。除此之外,英特尔的处理器还具有一些特殊功能,例如Skylake处理器中引入的软件防护扩展(SGX),稍微改变了如何处理访问内存的尝试。同样,处理器仍然保护ring 0内存不受ring 3程序的影响,但是它的缓存和其他内部状态又一次被改变,这样就造成了可测量的差异。

但是我们不知道的是内核信息有多少可以泄露给用户程序,或者泄露的程度如何。哪些英特尔处理器受到影响?再次说明:这一点并不完全清楚,但有迹象表明,每一个预测性执行的英特尔芯片(这是自1995年以来推出的所有主流处理器)都可能以这种方式泄漏信息。

这个问题的首先来自奥地利格拉茨技术大学的研究人员。他们发现的信息泄露足以破坏内核模式地址空间布局随机化(内核ASLR或KASLR)。ASLR是防止缓冲区溢出的最后努力。使用ASLR,程序及其数据被放置在随机存储器地址中,这使攻击者难以利用安全漏洞。KASLR将相同的随机化应用于内核,以便内核的数据(包括页表)和代码是随机定位的。(格拉茨的研究人员开发了KAISER,一组Linux内核补丁来防御这个问题)

如果问题只是使得ASLR的去随机化,那么这可能不会成为一个巨大的灾难。ASLR虽然是已知不完善的,但它是一个很好的保护,这就意味着成为攻击者的障碍,但不是一个不可逾越的障碍。行业反应 :Windows和Linux的一个相当重大的改变,是在一些秘密的情况下开发的;表明ASLR不仅被打败,而且更广泛的内核泄漏信息的能力已经被开发出来。

事实上,研究人员已经开始发出警告,说他们可以泄漏并读取任意内核数据。另一种可能性是该漏洞可能被用来逃离虚拟机并损害管理程序。Windows和Linux开发人员选择的解决方案基本上是相同的,并且源自KAISER的工作:内核页表项不再与每个进程共享。在Linux中,这被称为内核页面表隔离(KPTI)。

有了这些补丁,内存地址仍然分成两部分,这只是内核的一半几乎是空的。这并不完全是空的,因为一些内核部分需要永久映射,无论处理器是在ring 3?还是在ring?0中运行,而是接近于空。真正的内核页表仅在内核本身运行时使用,这意味着,即使一个恶意的用户程序试图探测内核内存和泄漏信息,它也会失败。

这是首先破坏了拆分地址空间的原因。TLB现在需要在每次切换到用户程序时清除与真实内核页表相关的任何条目,从而结束启用分割的性能节省。这种影响会因工作量而异。每当一个程序调用内核时(从磁盘读取数据,发送数据到网络,打开一个文件等等),这个调用将会更加昂贵,因为这会迫使TLB被刷新并加载真正的内核页表。那些不使用内核的程序可能会遇到2-3%的打击,但仍然有一些开销,因为内核总是偶尔运行,以处理诸如多任务之类的事情。

但是调入内核的工作负载将会有更多的性能下降。在一个基准测试中,除了调用内核之外,其他任何事情都没有什么影响,它的性能下降了大约50%。换句话说,每次调用内核的时间比修补程序长两倍。

英特尔回应安全研究调查结果

英特尔和其他技术公司已经意识到新的安全研究,描述了软件分析方法,当用于恶意目的时,有可能不正确地收集来自运行设计的计算设备的敏感数据。英特尔相信这些漏洞利用不会破坏,修改或删除数据。

最近有报道称,这些漏洞是由“错误”或“缺陷”引起的,对于英特尔产品来说是独一无二的。基于迄今为止的分析,许多类型的计算设备(具有许多不同的供应商的处理器和操作系统)容易受到这些攻击。

英特尔致力于产品和客户安全,并正与包括AMD,ARM Holdings和多家操作系统供应商在内的许多其他技术公司紧密合作,制定行业范围的方法,以及时和建设性地解决此问题。英特尔已经开始提供软件和固件更新以减轻这些漏洞。与一些报告相反,任何性能影响都取决于工作负载,对于普通计算机用户来说,不应该是显着的,并且会随着时间的推移而被缓解。

英特尔致力于采取行业最佳做法,负责披露潜在的安全问题,这就是为什么英特尔和其他供应商计划在下周公布更多软件和固件更新时披露此问题的原因。不过,由于目前媒体报道不准确,英特尔今天发表这个声明。

请与您的操作系统供应商或系统制造商联系,并尽快应用所有可用的更新。遵循良好的安全措施来防止恶意软件通常也将有助于防止可能的利用,直到可以应用更新。

英特尔相信其产品是世界上最安全的产品,在合作伙伴的支持下,目前解决方案可以为客户提供最好的安全性。

当然,英特尔的老对头 AMD 肯定不会放过这次机会,虽然没有发声明,但是 AMD 官方指出他们安全研究团队已经发现了三个针对推测执行的变体。他们认为,AMD 的处理器并不会受其影响。由于 AMD 处理器的不同架构,这次的安全漏洞对他们的产品来说影响几乎为零。

CPU 数据高速缓存时间可能会被滥用,这无疑加速泄漏了错误推测的执行信息,将导致(最坏的情况下)在各种语境下任意虚拟内存跨本地安全边界的读取漏洞。这个已经被证实不是Intel CPU爆出底层设计漏洞,只要CPU带有预测执行功能就都存在此漏洞,包括但不限于X86、ARM。

可以这么说,这个漏洞是相当严重的,不在于危害,而在于波及范围。至于AMD所说的架构设计不同所以风险接近零,只能说他们还没搞清楚状况就回应了。

写在最后:

目前来说,有些平台(如SPARC和IBM的S390)可以避免这个问题,因为它们的处理器内存管理不需要拆分地址空间和共享内核页表;?这些平台上的操作系统总是将它们的核心页面表与用户模式分开。但就已知的情况来看,这个问题的变种已经影响到了包括英特尔、AMD 和 ARM 的某些处理器。这说明了什么?无论英特尔,还是 AMD,还是 ARM,大家的处理器都有问题,一个都别想跑!后续相关问题的细节,还是坐等英特尔、AMD 等企业发布关于设计缺陷的技术纰漏以及安全细节声明。