延迟DMA攻击:利用设备重映射绕过IOMMU虚拟化隔离

发布时间:2026/5/27 20:05:38

延迟DMA攻击:利用设备重映射绕过IOMMU虚拟化隔离 1. 项目概述一种绕过IOMMU防护的新型威胁在虚拟化安全领域IOMMU输入输出内存管理单元长久以来被视为抵御DMA直接内存访问攻击的基石。它的工作原理类似于为每个DMA设备如网卡、存储控制器配备了一位严格的“内存门卫”。当虚拟机VM通过I/O透传方式直接控制一个物理设备时IOMMU会确保这个设备发起的任何内存访问请求都只能指向该虚拟机自身被授权的物理内存区域。这构成了虚拟机之间、以及虚拟机与宿主机之间至关重要的硬件隔离防线。然而安全研究就像一场永无止境的攻防博弈。最近一种名为“延迟DMA攻击”Deferred DMA Attack的新型攻击手法被提出它巧妙地利用了虚拟化环境中的一个动态特性——设备重分配成功地在特定条件下绕过了IOMMU的防护。简单来说攻击者控制一个拥有DMA设备的虚拟机在虚拟机被销毁前向设备发送一个“延时执行”的恶意DMA命令。随后当虚拟机被销毁该DMA设备被重新分配给宿主机或另一个特权虚拟机时那个预先设定的恶意DMA操作才真正执行。此时由于设备已映射到新的、权限更高的内存空间IOMMU会“放行”这次访问从而导致攻击者成功触及本应隔离的内存。这项研究并非纸上谈兵研究团队在真实的动态分区型虚拟机监控程序Jailhouse上使用常见的SD主机控制器SDHC成功实现了攻击的概念验证PoC。这揭示了一个此前被忽视的攻击面动态的资源管理如VM的创建/销毁、设备的动态分配与DMA设备的异步执行特性相结合可能产生致命的安全间隙。对于从事云计算底层安全、嵌入式系统虚拟化或系统级安全设计的工程师和安全研究员而言理解这种攻击的原理、适用条件及防御思路至关重要。它不仅是一个具体漏洞的利用更是一种对现有虚拟化安全模型假设的挑战。2. 攻击原理与威胁模型深度解析要理解延迟DMA攻击为何能成功我们需要深入其运作的每一个环节并明确其生效的精确条件。这不仅仅是知道“发生了什么”更要明白“为什么能发生”。2.1 核心攻击流程拆解攻击的成功依赖于一个精心设计的时间差其流程可以分解为以下几个关键阶段攻击准备阶段攻击者控制一个非特权虚拟机我们称之为“恶意VM”。该虚拟机通过I/O透传直接控制一个DMA设备例如SDHC。攻击者在该虚拟机内运行一个被篡改的恶意设备驱动程序。恶意命令注入与延迟构建恶意驱动程序向DMA设备提交一个复杂的I/O命令。这个命令的核心特点是它包含一个最终会触发恶意DMA操作的“描述符”但在此之前设备需要执行大量耗时的、非恶意的预备操作。例如在SDHC的案例中驱动程序构建一个“描述符表”其中包含大量循环的“链接描述符”只有在循环了成千上万次之后才会遇到那个指向宿主机内存地址的“恶意缓冲区描述符”。这个循环过程人为地制造了数秒甚至数分钟的延迟。触发重映射在设备还在慢悠悠地循环执行那些无害的描述符时外部事件可能是计划内的维护、资源回收或攻击者诱发的操作导致了这个恶意虚拟机被销毁。设备上下文切换虚拟机监控程序在销毁VM后会回收其资源。对于之前分配给该VM的DMA设备监控程序需要将其重新分配给其他实体通常是宿主机自身或一个特权VM。这个过程涉及在IOMMU中更新该设备的“流ID”Stream ID对应的页表上下文将其从已销毁VM的地址空间映射切换到新实体的地址空间。延迟攻击生效就在设备完成重映射获得了访问宿主机内存权限的瞬间或之后它终于执行到了那个预先埋设的恶意描述符。此时IOMMU检查这次DMA请求源设备是SDHC其流ID当前映射到宿主机的上下文。IOMMU查询宿主机上下文的页表发现目标地址假设是宿主机内核的某个函数指针是合法的于是放行。一次本应被拦截的、跨越隔离边界的DMA写入或读取就此发生。这个攻击最精妙也最危险的地方在于发出攻击指令的实体恶意VM已经不存在了但攻击却在其死后由它生前控制的“僵尸设备”完成。IOMMU的检查在此时是完全“合规”的因为它基于设备当前的、合法的映射关系进行判断无法追溯这次DMA请求最初的发起者。2.2 攻击生效的必备条件并非所有虚拟化环境都容易受到此攻击。论文中明确指出了几个必须同时满足的软硬件条件动态设备重映射虚拟机监控程序必须支持在运行时动态地将DMA设备从一个VM的地址空间解除映射并重新映射到另一个实体宿主机或另一个VM。静态分区型监控程序资源分配后不再改变不受此影响。Jailhouse虽然常被称作静态分区但其“根单元”root cell视角下设备可以在单元销毁时被动态回收和重分配因此符合条件。非受信驱动控制DMA设备攻击者必须能够在一个VM内运行非受信的设备驱动程序并拥有对该设备的完全控制权能够构造特殊的、包含延迟的DMA命令序列。设备支持可预测的延迟引入目标DMA设备必须允许驱动程序在发送命令和最终DMA操作之间插入一个足够长且驱动程序能够监控或维持的延迟。这个延迟必须长于虚拟机销毁和设备重映射过程所需的时间。延迟在重映射过程中得以保持这是最微妙也最关键的條件。在设备从VM上下文切换到宿主机上下文的过程中设备正在执行的“延迟循环”不能被打断。如果设备在切换期间失去了对其指令缓冲区如描述符表的访问权限攻击就会失败。这取决于设备如何访问其指令是从系统内存获取还是从内部存储获取以及监控程序在重映射时如何处理设备对旧内存区域的访问。关键洞察许多高性能SoC上的DMA设备如SDHC、网络控制器其指令描述符通常存放在系统主内存中。在重映射时如果IOMMU立即切断设备对旧VM内存的访问那么正在从该内存读取描述符的设备就会发生访问错误而停止攻击失败。但在Jailhouse的某些实现中设备的流ID被直接“交换”到根单元的上下文中间没有设置一个“无映射”的故障状态使得设备可以持续访问原内存区域直到它读取到新的、映射到宿主机的描述符地址为止。这正是攻击在Jailhouse上成功的关键。3. 基于SD主机控制器的攻击实现细节选择SD主机控制器作为攻击载体具有典型意义它广泛存在于各种嵌入式平台和开发板中其DMA机制ADMA2公开且可编程是验证攻击可行性的理想目标。3.1 SDHC DMA机制与攻击面分析SDHC通过一种称为“描述符表”的链表结构来组织DMA操作。每个描述符是一个64位的数据结构主要包含一个操作类型ACT字段、一个地址和一个长度字段。缓冲区描述符 (ACT0b11)指示SDHC执行一次DMA传输将数据从地址指向的系统内存区域传输到SD卡写操作或反向传输读操作。链接描述符 (ACT0b10)不执行DMA而是告诉SDHC“跳转到地址指向的位那里有下一个描述符表”。这用于构建描述符链表。驱动程序在内存中构建好这个描述符表将表的基地址写入SDHC的特定寄存器然后发送一个读/写命令。SDHC的DMA引擎便会开始自动遍历并执行这个描述符表。攻击的突破口就在这里描述符中的地址是“客户物理地址”GPA/IPA。当SDHC属于某个VM时IOMMU会将这个GPA转换为该VM被允许访问的物理地址。攻击者的目标就是构造一个描述符其地址指向一个它本无权访问的GPA例如属于宿主机内核的GPA并确保这个描述符在SDHC被重映射到宿主机上下文之后才被执行。3.2 构建“延时引爆”的描述符表单纯的恶意描述符会被IOMMU立即阻止。因此攻击的核心技术在于“延时”。研究团队设计了一种巧妙的“自修改描述符表”技术内存中的循环表驱动程序在VM内存中分配一个描述符表。这个表几乎全部由“链接描述符”组成最后一个链接描述符指回表的开头形成一个闭环。这样SDHC会在这个环里不停地打转执行空操作从而产生延迟。SD卡上的“弹药库”攻击者预先在SD卡的特定扇区写入一系列数据。这些数据的开头部分是一段和内存中第一个描述符一模一样的数据用于在循环中覆盖自身保持循环而在这段数据的末尾放置着那个恶意的缓冲区描述符。“偷梁换柱”的触发点在内存描述符表的第一个位置放置一个特殊的缓冲区描述符。这个描述符的命令是从SD卡的“弹药库”起始地址读取8字节一个描述符的大小DMA写入到内存中描述符表的第一个位置。也就是说它用SD卡上的数据覆盖自己。延迟循环与引爆SDHC启动后读取第一个描述符覆盖指令从SD卡读取数据覆盖自身第一次覆盖内容不变。然后SDHC沿着链接描述符循环一圈回到开头。再次读取第一个描述符此时已被覆盖为指向SD卡下一个扇区的覆盖指令再次覆盖自身……如此循环。SD卡上的“读地址”在每次DMA后会自动递增。经过N次循环后“读地址”终于指向了SD卡上预先埋藏的恶意描述符。在第N1次循环回到表头时SDHC读取到的第一个描述符变成了恶意描述符。随后它执行这个描述符发起对恶意目标地址的DMA访问。通过控制SD卡上“无害描述符”区域的大小攻击者可以精确控制延迟的时长。论文中的测试显示仅用32KB的SD卡数据配合一个4MB的内存描述符表就能制造出超过7分钟的延迟。考虑到SD卡动辄数GB的容量制造数小时甚至更长的延迟轻而易举。3.3 攻击实施的具体步骤在Jailhouse的PoC中攻击的实施遵循以下步骤这为安全测试人员提供了清晰的复现路径环境准备在目标平台如Zynq ZCU104上启动Jailhouse宿主机根单元运行Linux。创建一个非特权“恶意单元”并将SDHC设备通过I/O透传分配给它。驱动篡改在恶意单元内加载一个经过修改的SDHC驱动。这个驱动需要暴露额外的控制接口例如通过sysfs允许用户空间程序构造特定的描述符表。配置攻击参数通过驱动接口在VM内存中分配描述符表缓冲区。计算并准备SD卡上的数据布局包括大量用于循环的填充描述符和最终的那个恶意描述符。恶意描述符中的目标地址需要攻击者通过信息泄露或其他方式推测或获取的宿主机内存GPA。使用dd等工具将构造好的描述符序列写入SD卡的特定扇区。启动攻击循环通过驱动接口命令SDHC开始执行那个精心构造的、第一个描述符为“自覆盖”指令的描述符表。此时SDHC进入漫长的循环等待状态。触发重映射从宿主机根单元执行命令jailhouse cell destroy [恶意单元ID]销毁恶意虚拟机。Jailhouse随后将SDHC设备的流ID从已销毁单元的IOMMU上下文重新关联到根单元的上下文。攻击生效SDHC在循环足够次数后从SD卡中读出了恶意描述符并用它覆盖了内存中的表头。在下一个循环中它执行了这次恶意的DMA操作。由于此时其IOMMU上下文已是根单元这次对宿主机内存的访问被允许攻击成功。实操心得在真实环境中复现此攻击的最大挑战在于确定宿主机内存的准确GPA地址。这通常需要结合其他信息泄露漏洞。在PoC环境中研究者通常借助硬件调试器如Lauterbach直接查看内存布局来获取目标地址。这提醒我们此类攻击往往不是孤立的它可能成为利用链中的关键一环。4. 攻击的适用性分析与平台限制延迟DMA攻击并非一个“通杀”所有虚拟化环境的银弹武器。其成功与否高度依赖于虚拟机监控程序、硬件平台和具体DMA设备三者的具体实现和交互方式。4.1 对主流虚拟化技术的适用性评估研究团队除了在Jailhouse上成功演示外还探讨了在其他常见虚拟化方案上的可能性Xen在ARM版本的Xen上测试主攻击场景设备重映射到Dom0未能成功。原因是Xen的设计逻辑不同如果一个设备在设备树中被标记为xen,passthrough它从一开始就不会映射到Dom0。当拥有该设备的VM被销毁时设备不会被重新映射到Dom0而是进入一种“未分配”状态IOMMU会阻止其所有内存访问从而中断攻击。另一种设想场景——设备在VM间动态热迁移——对于SDHC这类内存映射设备Xen当前并不支持。KVM/VFIOVFIO框架为Linux用户空间或KVM虚拟机提供安全的设备直通。它同样涉及设备的绑定与解绑相当于重映射。理论上如果一个非受信的用户空间驱动被解绑设备随后被绑定到另一个驱动攻击可能成立。但是基于SDHC的实现面临一个严峻挑战攻击无法精确感知设备何时被重映射。如果延迟设置得太短设备可能在重映射前就执行恶意操作触发IOMMU错误如果设置得太长新绑定的驱动很可能在恶意操作执行前就复位了设备导致攻击失败。此外VFIO框架通常会在设备分配给新使用者前尝试对其进行复位这是一个有效的通用缓解措施。4.2 设备特性对攻击可行性的关键影响DMA设备的内在架构决定了攻击的难易度设备类型描述符存储位置对攻击的友好度原因分析SDHC类设备系统主内存 (RAM)较低攻击的“延迟循环”依赖于持续访问存放在VM内存中的描述符表。在重映射过程中如果IOMMU切断了设备对旧VM内存的访问循环会立即中断攻击失败。其成功依赖于监控程序重映射逻辑的“宽容性”如Jailhouse的直接上下文交换。内置存储设备设备内部内存较高描述符表存储在设备自身的SRAM或缓存中。即使设备在IOMMU中的映射被完全取消它仍然可以访问内部的指令并继续执行。这大大降低了击对监控程序重映射逻辑的依赖使得攻击更易成功。可编程DMA控制器(如NXP SDMA)设备内部内存 (可加载)很高这类设备拥有独立的内核、指令集和内存。攻击者可以将完整的恶意程序包括延迟循环和最终攻击加载到设备内部RAM中执行。设备执行完全自主与系统内存访问脱钩几乎不受重映射过程影响是理想的攻击载体。论文指出在高性能SoC如Zynq MPSoC上像SDHC这样依赖外部内存的描述符的设备更为常见。但在许多嵌入式微控制器中使用内部描述符存储的DMA外设则很普遍这扩大了攻击的潜在影响范围。4.3 平台配置带来的变数平台的特定配置可能意外地为攻击打开绿灯。例如在Zynq UltraScale MPSoC上存在一个默认禁用的寄存器 (IOU_INTERCONNECT_ROUTE)。如果此寄存器保持禁用状态来自IOP外设包括SDHC的DMA流量对于某些特定内存区域如片上内存OCM可以绕过IOMMU。如果攻击者能将描述符表放置在OCM中那么无论IOMMU如何重映射SDHC都能持续访问到描述符表使得攻击极易成功。这凸显了安全配置审查的重要性一个不起眼的默认设置可能隐藏着巨大的风险。5. 防御与缓解策略探讨面对这种利用时序和状态转移的攻击单一的防御措施往往不够。需要从虚拟机监控程序、设备驱动和硬件平台多个层面构建纵深防御。5.1 设备复位最直接有效的屏障在将DMA设备从一个安全域如VM回收并重新分配给另一个安全域之前对其进行彻底的硬件复位是阻断此类攻击最可靠的方法。原理复位会将设备的所有内部状态机、寄存器、缓存和正在执行的命令队列清零恢复到上电初始状态。任何由前一个使用者设置的延迟命令都会被清除。实现挑战标准化缺失对于PCIe设备存在功能级复位FLR等标准机制。但对于集成在SoC中的大量内存映射外设如SDHC、UART、SPI控制器往往缺乏统一、可靠的复位接口。复位可能通过一个专用的控制寄存器位、一个GPIO引脚或者甚至需要操作电源域来实现。对VFIO/KVMVFIO框架试图提供通用的复位接口。如果设备支持标准复位如PCIe FLRVFIO会调用它。如果不支持则需要设备驱动提供一个自定义的复位回调函数。如果两者都没有系统管理员可能需要通过内核参数声明“无需复位”但这显然会引入风险。建议在设计和采购硬件平台时应优先选择为关键DMA外设提供了明确、可靠复位机制的SoC。在驱动和虚拟机监控程序开发中必须为每个直通设备实现或集成复位例程并将其作为设备重分配流程中的强制步骤。5.2 改进IOMMU重映射流程虚拟机监控程序可以优化其设备重映射的逻辑以消除攻击赖以生存的“时间窗口”。引入“故障上下文”过渡态在将设备的流ID从旧上下文切换到新上下文之间插入一个短暂的“故障上下文”或“空上下文”状态。在这个状态下设备发出的任何内存访问事务都会被IOMMU拦截并报错。这可以确保设备在失去旧映射后、获得新映射前的瞬间任何正在进行的DMA操作都会被中止。以ARM SMMUv2为例可以通过编程S2CR寄存器将设备的流ID临时指向一个配置为触发故障的上下文而不是直接切换到根单元的上下文。清零或取消映射设备内存在销毁VM时监控程序应主动清零或取消映射该VM曾使用的、可能被DMA设备用作描述符表的内存页面。这可以破坏攻击的“延迟循环”所需的数据。但这种方法可能影响性能且对于设备使用内部存储的描述符无效。5.3 监控与检测机制除了预防还可以通过监控来发现此类攻击的企图。IOMMU故障监控监控程序可以加强对IOMMU故障特别是由直通设备引起的故障的日志记录和告警。一次在VM销毁后不久、由该VM曾控制的设备触发的IOMMU故障可能是一个重要的攻击迹象。设备行为基线对关键DMA设备建立正常行为基线例如典型的描述符链长度、命令间隔时间等。一个构造了异常冗长循环描述符表的驱动其行为可能偏离基线触发异常检测。5.4 系统设计层面的考量从根本上说延迟DMA攻击提醒我们在动态虚拟化环境中“资源所有权”的转移是一个需要极其小心处理的安全关键操作。最小权限与动态分配是否所有VM都需要真正的设备直通对于许多用例采用virtio等半虚拟化方案或SR-IOV等硬件辅助虚拟化可以避免将完整的DMA设备控制权交给非受信VM。安全启动与可信驱动在高度敏感的环境中可以考虑仅允许加载经过签名验证的可信设备驱动到VM中从根本上杜绝恶意驱动的运行。混合关键性系统设计在汽车、航空电子等嵌入式领域采用时间触发架构或更严格的静态分区限制动态创建/销毁VM和设备重分配可以从架构上消除此类攻击面。6. 总结与对从业者的启示延迟DMA攻击的研究将我们的注意力从IOMMU静态的访问控制策略引向了虚拟化环境中动态生命周期的安全管理。它证明即使硬件隔离机制本身无懈可击但其与资源动态管理策略的交互界面可能存在缝隙。对于嵌入式系统、边缘计算和云基础设施的开发者与安全架构师而言这项工作的价值在于提供了几个明确的行动方向审计你的动态重映射逻辑检查你的虚拟机监控程序或VFIO使用场景中在VM销毁、设备解绑时IOMMU上下文切换的具体实现。是否存在从旧映射直接切换到新映射而没有中间隔离态的风险评估设备复位能力为你平台上的每一个支持直通的DMA设备建立清单并明确其可靠的复位方法。确保在设备所有权转移前复位操作被有效执行。压力测试将“延迟DMA攻击”作为一种新的测试用例纳入你的虚拟化平台安全测试套件。尝试在受控环境中复现以验证现有防护措施的有效性。关注设备内部存储在安全评估中要特别关注那些使用内部存储描述符或拥有可编程引擎的DMA控制器。它们可能是更危险的攻击载体。安全是一个持续的过程。延迟DMA攻击并非宣告IOMMU或现有虚拟化模型的失败而是指出了在追求灵活性与动态性的道路上我们必须更加审慎地处理每一个状态变迁的瞬间。这项研究就像一记警钟提醒我们在构建复杂系统时时间也是一个至关重要的安全维度。

相关新闻