查看原文
其他

用 Linux 和 Go 换掉 x86 固件 !

Jake Edge 云头条 2021-03-21

英特尔管理引擎(ME)是一种独立的处理器和操作系统,在大多数x86系统上运行,不受用户的控制,长期以来是关注安全和隐私的用户所担心的对象。谷歌及其他公司一直在努力想方设法消除其尽可能多的功能(同时仍能够启动和运行系统)。来自谷歌的软件工程师罗纳德•明尼克(Ronald Minnich)近日出席了在布拉格召开的2017年欧洲嵌入式Linux大会,专门介绍了这方面的工作。


https://v.qq.com/txp/iframe/player.html?vid=u0510y7irjs&width=500&height=375&auto=0
他一开始就特别指出,他大多数时候谈论的固件是指他参与开发的coreboot固件平台,不过话题“并非完全围绕coreboot”。他列举好多人参与开发了该项目,旨在“把你那漏洞百出的固件换成Linux内核”,包括谷歌的另外几名员工和来自合作伙伴公司(Two Sigma、思科和Horizon Computing)的几个人。


他们取得的成果是,将开放计算项目(OCP)节点的启动时间从8分钟缩短至20秒。他表示,在他看来,这“也许是这项工作中最不重要的部分。”启动过程的所有用户空间部分一律用Go编写,这包括initramfs中的一切组件,其中包括init。这为启动过程带来了Linux的性能、可靠性和安全性,他们还能够为启动过程消除所有的ME和UEFI启动后活动。


描述乱象


明尼克表示,问题在于Linux已失去了对硬件的控制。早在20世纪90年代,我们好多人开始使用Linux时,Linux控制着x86平台中的一切。而如今,Linux和硬件之间至少有两个半内核。这些内核是专有的,很容易被利用不足为奇。它们在比Linux更高的特权级别下运行,可以以各种方式操纵/处理硬件和操作系统。更糟糕的是,漏洞代码可以被写入到系统闪存中,因而存留下来,很难或不可能被清除,砸烂主板可能是唯一的办法。


他发表过题为“如果你相信计算机,那你准疯了”的演讲,这归因于我们的系统上运行的所有专有代码。他希望这次演讲让大家有办法来解决其中一些问题,“那样我们才会变得理智一点。”


x86操作系统


他展示了一张幻灯片:



描述了x86系统上运行的看见和看不见的操作系统。 ring 0是Linux,因为“我们用完了ring编号”,像Xen这样的虚拟机管理程序是ring -1,但其下面的ring运行你无法访问的代码,有时是在你甚至不知道是系统一部分的处理器上。 ring -2有一个半内核,它包括UEFI(完整内核)和系统管理模式(SMM),SMM通过trap进入8086 16位模式,“半个内核”故而得名。那些控制着关于CPU的一切,是上面的ring看不见的。每当你合上笔记本电脑盖子或者做其他某些事情,SMM都会通过trap进入经典的8086模式;他讽刺地说“那应该会让你开心。”


ring-3是“真正让人担心的部分。”它运行MINIX 3,ME就在此处运行。他开玩笑说,ME方面拥有的系统比Linux、MacOS或Windows还多。


就他所知,ring-2中和ring-3中运行的系统之间没有共同的代码,但它们都有众多功能。两者都有IPv4和IPv6网络堆栈、文件系统、各种设备(磁盘、网络和USB等)的驱动程序和Web服务器功能。ME需要文件系统,是由于它可以用来为系统重新做镜像;明尼克表示,实际上,即使电源关了,它也可以为系统重新做镜像,只要系统插在墙壁电源上、连在网络上。


ring -3 ME由一大堆组件构成,有许多他没有搞明白。比如有诸如此类的组件:“全网络可管理性”、“常规网络可管理性”、“可管理性”以及“outbreak遏制启发式”。他提到了十年前瓦西柳斯•费尔费里斯(Vassilios Ververis)所写的硕士论文:



该论文剖析了ME的诸多不同缺陷。明尼克表示,结果让人很郁闷,因为论文表明ME的几乎每个部分都会受到攻击;有一些缺陷还没有被修复。


罗纳德•明尼克


他援引了《连线》杂志上介绍ME漏洞的一篇文章的标题:《修复一个存在7年的重大缺陷》,他觉得很有趣。不太有趣的是,这个缺陷让零长度密码可以发送到Web服务器,从而让管理员访问使用ME的系统。他说,由于这个缺陷存在了7年,受影响的系统多达10亿个,他强烈怀疑所有那些系统都已通过固件更新打上了补丁。


他又说到了ring-2中的半个操作系统。 SMM最初是为了处理DOS系统上的电源管理;发生某些事件(系统管理中断即SMI)时,它可以接管系统。SMI方面有好多漏洞;一旦SMM被启用,就无法关闭它。SMM发挥其用途须从系统的其余部分使用8MB内存。他表示,SMM是“厂商对你保持控制的好方法”。


ring-2中运行的另一个部分是UEFI,它和SMM都在主CPU上运行。UEFI是“极其复杂的内核”;厂商们为内核编写代码,但它们并不了解所有规则,因而时常犯错。结果是“留下了很大的口子,人们可以趁虚而入”。据他所知,UEFI通过隐匿来实现安全。


他表示,UEFI有大量的漏洞。由于UEFI通过将一部分UEFI代码移交给UEFI内核来更新,所以他担心漏洞会持续感染启动过程,以至于它声称会更新自己,实际上没有这么做。       他总结了刚刚描述的内容:2.5个隐藏的操作系统,拥有网络堆栈、Web服务器和其他功能。这些操作系统存在断电通电和重新安装后仍然在的缺陷,那些缺陷在过去已被人利用。


解决乱象


他问道:“那我们如何收拾这个烂摊子?”有人说改用AMD处理器,但现在这不是真正的解决方案。Ryzen号称是开放的,但事实并非如此,它仍有闭源组件。所以该项目专注于英特尔x86处理器,目标是缩小2.5个操作系统的范围。该项目名为“非扩展性缩减版固件”(NERF),一方面是由于研发团队认为,UEFI中的“可扩展”是有害的。很显然,NERF本身没有完整网页,不过明尼克谈到的一些组件确实有网页。[更正,确实有一个NERF网页:https://trmm.net/NERF。]



NERF的想法是,减小固件所能造成的危害。此外,还努力让固件执行的操作更透明化。为此,删除了固件中差不多所有的运行时组件;他表示,“差不多”是指ME很难完全杀死。如果你完全删除了ME,节点可能无法启动,但NERF删除了ME的Web服务器和IP堆栈。UEFI IP堆栈及其他驱动程序也被删除。除此之外,面向ME和UEFI的self-reflash功能已被删除,所以Linux管理所有的闪存更新。


NERF组件是精简版的ME ROM和UEFI ROM,它剩下最基本的部分;此外,必要时, SMM被禁用或被引导到Linux。除此之外,运行的是带有基于Go的用户空间(u-root)的Linux内核。他特别指出,就想为这方面做贡献的Go程序员对这个项目尤其感兴趣。


他们宁愿完全删除ME,但这根本不是一个法子。如果你删除ME,系统可能无法启动、通电,或者就算确实能通电,也会在30分钟后再次关闭。不过有个好消息:ME有多个组件,大部分组件可以删除。


他提到了将处理ME ROM、删除大部分组件的me_cleaner项目(https://github.com/corna/me_cleaner)。比如在MinnowMax上,ME使用8MB闪存中的5MB,但me_cleaner可以缩减至300KB。所以你只需要300KB的ME来启动Linux,这摆脱了你其实不希望ME处理的所有事情。他表示,缩减ME适用于MinnowMax及其他许多主板。


如果你“参与够早”,可以完全禁用SMM。运行SMM没有任何要求;要是SMM成了某个硬件的问题,有办法将SMI引导到内核。他表示,主题就是牢牢控制Linux。


UEFI“很庞大、极其复杂”,但是实施过程中犯了很多错误。不过,一些中断(包括内存错误检测中断)仍需要发送到UEFI。他们希望通过确保不可扩展来消除UEFI驱动程序带来漏洞的机会。他展示了一张显示UEFI提供的所有不同服务的“视力表”;他特别指出,它看起来像内核,因为它就是内核,“它是整个Linux的一小部分”。


接下来,他展示了标准的UEFI启动过程;先是两个阶段(安全即SEC和EFI前初始化即PEI),这些是完全专有的,厂商根本不会发布。不过此外,名为驱动程序执行环境(DXE)的下一个阶段有明确定义的接口,多个组件(DXE核心、驱动程序和启动管理器等)符合该接口。


启动管理器负责启动操作系统。你看到允许选择UEFI系统上启动哪个的屏幕时,那就是启动管理器。他们所做的是,把启动管理器换成符合DXE接口的Linux内核。在大会上别处演示的OCP节点系统上,通电后启动Linux内核用时20秒;基于Go的用户空间执行DHCP查询,对服务器内核执行wget,执行kexec切换到新内核,这多了3秒。计划把DXE核心组件换成更了解如何启动Linux的开源组件;明尼克表示,那有望进一步缩短启动时间。


他不认为我们可以访问UEFI的那部分早期启动代码(SEC和PEI)。即使对于运行coreboot的Chromebook来说,那部分也是二进制大对象(binary blob)。他表示,我们能做的就是换成明确定义的接口,这一块已完成。此外,旨在摈弃所有的UEFI运行时服务,这方面已完成。


作为其Heads项目(https://github.com/osresearch/heads)的一部分,特拉梅尔•哈德森(Trammel Hudson)已拿来几个Makefile和类似的文件创建成一个NERF镜像。该镜像可与自定义内核和initramfs结合使用,尽量取代UEFI。它们在戴尔服务器、MinowMax和OCP节点上取得了很好的结果。


明尼克表示,使用Linux让固件更易于使用。通常,固件中有许多需要谨慎对待、针对特定硬件的部分需要更改,而使用DXE接口可消除许多此类问题。他预计,不同的系统会需要不同的内核,不过他一直在MinnowMax(小系统)和OCP节点(庞大系统)上使用同一个内核。


他表示,用户空间部分一律用Go编写,Go在谷歌内部比C更受信任。5.9MB大小的initramfs含有用户空间的所有源代码、所有的Go编译器和软件包源代码以及Go工具链。命令在需要时实时创建,每个命令通常仅需要200ms;一旦命令创建,“几乎瞬间”(1ms)运行。从安全的角度来看,这很好,因为需要检查的所有源代码都已到位。


要是遇到这种情况:这种大小的initramfs没有足够的空间,或没有足够的CPU资源来执行快速编译步骤,u-root Go命令还有另一种模式。这好比BusyBox,原因在于有一个与一堆不同的命令名称关联的二进制文件;这个模式使用Go抽象语法树包将命令重写成包。这将占用的内存减少到2MB,这在闪存空间较小的系统上很有用。


明尼克考虑用于启动桌面系统的u-root工作有几个重要影响。有了u-root,不需要处理脚本或单元文件,只有一个程序来启动系统,这有助于“进程迅速启动”。它不仅更易了解,还让启动过程更快。谷歌有个名为NiChrome的项目,短短5秒内就可以让Chromebook从开机通电一路进入到X11和浏览器。


Go是一种编译语言,但常常用于编写脚本。明尼克“一直”用Go编写脚本;多年前,他停止编写Bash脚本,改用Go。用Go编写脚本来得“更容易、更可靠”。


他最后说,他希望在2018年看到厂商交付使用NERF和u-root的硬件。他表示,许多公司希望拥有自己了解底层的固件;它们还希望固件快速启动、又安全。在问答环节,明尼克被问及安全启动(secure boot)和TPM。目前两者都不支持,不过眼下u-root中有一个试验性的验证启动程序。至于TPM支持,他认为该项目将效仿Chrome操作系统的做法,而不是走安全启动这条路。


明尼克还被问到了这项工作与coreboot的关系。他表示,coreboot应该始终是首选,但12年来没有用于服务器平台。所以他会建议开发人员“可以的话总是使用coreboot”,不可以的话,看看NERF。


云头条:未经授权谢绝转载


相关阅读:

中高端IT圈人群,欢迎加入!

赏金制:欢迎来爆料!长期有效!

x86处理器曝严重设计缺陷 漏洞已存在18年

为什么Linus Torvalds偏爱x86而不是ARM架构

在云时代,X86架构无戏可唱!

Gartner:2016年服务器虚拟化基础设施魔力象限|「云头条」

Gartner:服务器虚拟化已达到饱和点

存储行业方向完全错了:这家公司“重新发明”存储架构,解放了硬件!

AT&T 欲丢弃全部路由器(100000只),统一换成白盒硬件!(附白皮书)


欢迎加入交流,群主微信:aclood(加好友时备注任职单位、职位,否则不予通过)



    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存