关注了就能看到更多这么棒的文章哦~
Guest-first memory for KVM
By Jonathan Corbet
November 2, 2023
ChatGPT translation
https://lwn.net/Articles/949277/
保护计算(confidential-computing)实现的核心目标之一是保护客户(guest)系统的内存免受来自客户本身之外的其他使用者的访问。主机(host)计算机和 hypervisor 也是应该不可以访问的;事实上,它们经常被视为一种威胁(thread)。硬件供应商添加了诸如内存加密之类的功能,以使内存对 host 来说是无法访问的,但这些功能可能难以使用,并且并非所有 CPU 都可用,因此人们对可以提高保密性的纯软件解决方案仍然感兴趣。由 Sean Christopherson 发布的guest-first memory补丁集,其中包含多名开发人员的工作,似乎将在即将发布的内核版本中引入一些基于软件的保护。
在缺少加密机制的情况下,保护内存免受主机访问通常依赖于地址空间隔离,也就是安排好空间,使得主机无法访问客户的内存。在这种情况下的保护通常不是很完整,毕竟一个完全恶意的 host 内核可能会撤销这个保护,但它可以有效防范许多其他来自主机端的攻击。早在 2020 年,KVM受保护的内存工作创建了一个新的超级调用(hypercall),通过它,客户可以请求主机取消映射由该客户端使用的内存范围;这将使主机系统(在内核和用户空间级别)无法访问该内存。然而,这个工作遇到了一些问题,并且从未进入主线。
客户端优先(guest-first)内存工作采用了类似的方法,但将控制权移交给主机,并减少了可用的保护选项。具体而言,它添加了一个新的 KVM ioctl()
命令,称为 KVM_CREATE_GUEST_MEMFD
,它以字节为单位接受一个 size 作为参数,并返回一个新的文件描述符。该操作类似于memfd_create(),因为返回的描述符引用了一个匿名文件,具有所请求的大小,完全存在于内存中。不同之处在于,此 memfd 与创建它的虚拟机是关联起来的,并且不能在主机上(或任何其他虚拟机)映射到用户空间。但是,这段内存可以通过常规 KVM 内存管理操作的一种变体来映射到客户端的“物理”地址空间。
通过此操作,hypervisor 可以为客户端分配内存资源,而无需能够自身访问该内存。这可以保护客户免受其内存内容被披露或被修改的风险,无论是出于意外还是由于(可能受到威胁的)hypervisor 的恶意行为都不再担心。与一些先前的尝试(包括 KVM 受保护的内存)不同,此操作不会将受影响的内存从主机内核的直接内存映射(direct memory map)中移除映射。因此,使用此内存的客户端可以不受主机上用户空间的威胁,但仍可能受到被攻破的内核的攻击。成功攻击的门槛已经显著提高,但这跟保护确实并非完全无懈可击。
根据补丁说明,使用客户端优先内存有许多优势。目前,KVM 不允许客户端对内存具有比 hypervisor 更高的访问级别;如果要在客户端中映射内存为可写,那么在 hypervisor 中,该内存必须同时被映射并且可写,即使 hypervisor 没有必要能够写入该内存。摆脱 hypervisor 映射的客户端优先内存,显然可以解决这个问题。
在硬件支持的内存加密存在的情况下,客户端优先内存也可能是有用的。加密内存已经受到 hypervisor 的访问保护;如果 hypervisor 试图这样做,CPU 将生成一个 trap,这可能导致 hypervisor 的崩溃。然而,如果该内存一开始就没有映射到 hypervisor 中,它就不会因为偶然而被触及。对于开发和调试旨在与硬件支持的保密计算功能一起工作的 hypervisor,不可映射的内存也可能是有用的,即使在不具备这些功能的硬件上也是如此。
从长远来看,这个功能可能也对专用内存池的管理有用;可以在池中设置一个客户端 memfd,而无需主机的访问。这可能允许在主机上管理客户系统的内存而无需使用 struct page
,从而降低主机的开销并增加该内存的隔离性。此外,眼光放在长远,这组 patch 创建了一个更通用的“受保护的虚拟机”概念,旨在成为 KVM 内的机密计算机制的容器。
然而,与此同时,客户端优先内存的缺点是无法迁移,这意味着主机端的内存管理进程(如压缩)将不得不避开它。当牵涉到 KVM 受保护的内存时,这一限制被认为是一个重大问题,但在这组 patch 中没有得到解决,并且在“至少在可预见的将来”内也不会得到解决。
尽管如此,KVM 维护者 Paolo Bonzini 已经表示他计划在 6.7 合并窗口之后合入这组 patch,并计划将其引入 linux-next,随后将其推送到 6.8 内核版本。他还表示,他打算将此系列应用于未来的 RHEL 内核,这意味着只要客户端内存一旦进入主线且 API 已经稳定下来,就会在不久的将来出现在 RHEL 版本中。但是,在客户端内存进入主线并且 API 稳定下来之前,这仍然不太可能发生。
可能还需要一些调整;这是一个由 35 个部分组成的补丁,添加了将近 3000 行代码,因此即使经过 13 次修订后,仍然可能需要一些调整。尽管如此,看起来在多年的努力中,增加了对客户系统提供的地址空间隔离量正在取得进展。幸运的话,共享云系统的用户(是很多人)都将从这种加固措施中受益。
全文完
LWN 文章遵循 CC BY-SA 4.0 许可协议。
欢迎分享、转载及基于现有协议再创作~
长按下面二维码关注,关注 LWN 深度文章以及开源社区的各种新近言论~