vlambda博客
学习文章列表

LWN:改进KVM来增强guest系统保护和安全!

点击上方蓝色“ Linux News搬运工”关注我们~

Enhancing KVM for guest protection and security

November 20, 2019

This article was contributed by Sergio Lopez


KVM Forum

原文来自:https://lwn.net/Articles/805114/


KVM里面一个主要的原则,就是希望能尽量重用Linux的基础设施(指Linux现有代码中的各个子系统),并且着重关注处理器的虚拟化。在2007年的时候,这个原则也就意味着代码改动更加小,也不会过于分散在kernel的各个子系统里面,这一点在跟诸如Xen这样的其他虚拟化技术对比的时候是个明显优势。因此,KVM也比较轻松地就合入了mainline。


不过,现在大家更加关注微架构漏洞了(microarchitectural vulnerabilities),重点已经发生了变化,因此KVM对其他kernel子系统的依赖就变成了一个缺点。比如说,host (宿主机)kernel扩展了TCB(Trusted Computing Base),也就带来了更大的受攻击面。此外kernel的数据结构例如direct memory map也会允许Linux能访问到guest系统里面的memory,这其实根本没有必要,并且也违反了只赋予最小权限的原则。在KVM Forum 2019会议上,长期KVM贡献者Jun Nakajima在自己的主题演讲“改善KVM对guest系统的保护和安全”中解释了这方面的风险,以及提出了一些改进策略。


Removing the VMM from the TCB



第一步就是要把user-space VMM从TCB里拿掉。可以让guest系统使用一个新的KVM机制来指定哪一块内存空间应该共享出去,剩下的内存空间就全部标记为guest私有。VMM这边发起的对guest不希望共享出去内容的访问,全部都会导致page fault采取对应的措施,例如给VMM发送一个signal。


这意味着guest系统里面运行的kernel需要做一些修改,这样才能利用这个机制,并且确保DMA操作必须是完全利用跟VMM共享的这块内存区域的(可以利用软件I/O translation buffer来做,就是基于swiotlb的弹性缓冲区)。这个策略目前已经用来支持AMD SEV了,可以让guest系统运行中拥有内存加密的能力(从而让host kernel和user-space VMM都无法访问),而Nakajima指出这个方案的目的是尽量利用现有代码。


Protecting guests from the host kernel


如果把user-space VMM从TCB拿掉,确实是会有用处的,不过这只是第一步而已。更进一步来说,我们打算把host Linux kernel也从TCB中拿掉,这就需要更多的改动,才能让hypervisor掌控(原文用的"absorb",不确定怎么翻译最合适了)这个host kernel,把它原本具有的对guest系统全部访问的权限剥夺掉。


这个功能早在2016年KVM Forum的时候就有介绍了,当时对这个功能的称呼是VBH (virtualization-based hardening),正如这个名字所说,hypervisor会利用硬件虚拟化来保护自己避免受到host kernel的攻击。在hypervisor自己初始化好之后,Linux就会进入guest mode运行(会带有一些特殊权限),hypervisor就可以用EPT/NPT(extended and nested page tables)跟IOMMU配合起来,控制Linux对物理内存的访问。



这样改了之后,虽然还远未达到Type-1 Hypervisor的要求,不过KVM已经把Linux的底层虚拟内存功能的很大一部分绕过去了。当然,这也就意味着hypervisor自己需要能提供诸如swapping page等机制,也要定义一些新的接口提供对真正后端内存(RAM,software-defined,NVDIMM等)的访问。



总而言之,大家似乎已经公认需要重新思考KVM管理guest系统内存的方式,以及重新思考KVM和Linux其他子系统的关系。


Going further: removing KVM from the TCB



为了克服这个问题,Nakajima提出了两个选项。一个是修改适配guest里面运行的kernel,把那些可能会触发VM-exit从而导致KVM访问guest memory的操作都替换成显式的hypercall。另一个选项,为了避免修改驱动程序,可以把这类操作表现为一个virtualization exception (#VE) 处理函数(handler)。这个处理函数可以模拟进行各类内存映射I/O操作(MMIO, memory-mapped I/O)并转化为hypercall。


这两种策略可以选一个,用来确保guest memory和hypervisor隔离开。总之都可以帮助避免不小心泄露数据,也能阻止side-channel attach,不过如果攻击者获得了KVM完全控制权的话,还是能修改内存映射(mapping),因此也可能访问到每一个guest系统的私有区域的。如果连这个风险也要解除的话,就需要硬件机制的帮助了,例如AMD SEV及其后续的SEV-ES(Encrypted State)和SEV-SNP(Secure Nested Paging)。这样就能让guest memory可以被透明地加密掉,这样哪怕是hypervisor也不能访问明文数据。


Proof of concept and performance


最后,Nakajima展示了一个原型系统,实现的功能包括把guest mapping从VMM和host kernel里面都摘除出去,然后给出了初步的性能数据。针对virtio设备上的磁盘读取操作,在一个guest系统里面,他测得CPU耗时增加了1.2%,如果使用超过10个guest,就有1.3%的增加。针对写操作来说影响要小一些,单个guest是1.1%的增长,超过10个guest的情况时1.2%。针对网络发送操作,也是在一个virtio设备上,单guest系统的CPU耗时增加2.6%,超过10个guest系统增加3.8%。



全文完

LWN文章遵循CC BY-SA 4.0许可协议。

极度欢迎将文章分享到朋友圈 
热烈欢迎转载以及基于现有协议修改再创作~


长按下面二维码关注:Linux News搬运工,希望每周的深度文章以及开源社区的各种新近言论,能够让大家满意~