ARM64 GIC时序侧信道

摘要 ARM64 通用中断控制器在分发硬件中断时,会短暂挂起当前执行的指令流。在核心保存上下文期间,被中断的指令序列可能已经执行了部分加载指令,将敏感数据预取到 L1 数据缓存。攻击者若能够控制中断到达的精确时机(例如通过软件生成的中断 SGI),可在安全世界(EL3)的关键指令(如 eret)执行前中断它,使预加载的安全世界缓存行在普通世界可被探测,从而绕过 TrustZone 的隔离,窃取安全世界的加密密钥或敏感数据。 GIC 与 ARM64 异常入口的时序窗口 GICv3 中断分发路径 ARM64 平台的通用中断控制器(GIC)负责管理所有中断源,并向 CPU 核心分发。GICv3 由分发器(Distributor)和再分发器(Redistributor)以及 CPU 接口组成。软件生成中断(SGI)通过写 ICC_SGI0R_EL1 或 ICC_SGI1R_EL1 寄存器来触发,可指定目标核心和中断 ID。攻击者如果具备在普通世界 EL1 的代码执行能力,便可以向自身或其他核心注入 SGI,制造精确的本地中断。 当中断到达核心时,CPU 完成当前指令的边界,然后进入异常入口流程:保存处理器状态到栈,跳转到中断向量。ARM64 的中断向量表定义了不同异常级别和类型的入口。关键点是,从异常被触发到第一条异常处理指令执行之间存在固定的指令流水线延迟,并且在这个窗口内,处理器可能已经执行了后续的部分指令(由于分支预测和推测执行)。 安全世界与普通世界的切换 在 TrustZone 架构中,普通世界(Normal World)和安全世界(Secure World)的切换通过 smc 指令进入 EL3,或在 EL3 中通过 eret 返回普通世界。当安全世界正在执行敏感操作(如加密、认证)时,若被中断抢占,处理器必须先保存安全世界上下文,然后跳到中断处理程序。如果该中断处理程序位于普通世界(例如在 EL1 内核中),则会进行一次世界切换(从安全世界到普通世界),这涉及缓存和 TLB 的维护操作。 [EL0 用户态代码] │ ├─ (发生异常/中断, 如 SVC / IRQ) ▼ [硬件自动行为 (CPU Core)] ├─…

CXL 内存池信任污染

摘要 Compute Express Link(CXL)3.0 通过 Type 3 内存扩展设备实现了多主机共享内存池,为云原生架构提供了前所未有的内存弹性。然而,共享意味着信任边界的扩张:当多个虚拟机(VM)通过 CXL 交换机共享同一物理内存池时,内存页的生命周期管理与安全隔离完全依赖于主机侧的内存分配器和 CXL 设备固件。如果设备在页释放后未执行可靠的清零或加密边界切换,攻击者便可在合法 VM 释放共享页后,立即从另一台主机申请分配同一物理页,读取前一个租户的残留数据——包括加密密钥、凭证和模型参数。更严重的是,部分 CXL 设备固件未严格验证主机发来的 HDM 地址范围,允许跨域访问。 CXL内存池 CXL协议与Type 3设备 CXL 构建在 PCIe 物理层之上,提供三种协议:CXL.io(用于配置和控制)、CXL.cache(用于缓存一致性)和 CXL.mem(用于内存访问)。Type 3 设备(如内存扩展卡)仅实现 CXL.io 和 CXL.mem,不参与缓存一致性,主要提供大容量内存扩展。 在 CXL 3.0 中,多主机共享内存池成为可能。通过 CXL 交换机和 Fabric Manager,多个主机(或虚拟机管理程序)可以访问同一块 Type 3 设备上的内存区域。这种架构允许动态分配和释放内存资源,提高数据中心的利用率。 多主机共享内存池 共享内存池打破了传统“一个主机一块内存”的边界。CXL 设备上的物理内存被划分为多个主机物理地址空间(Host Physical Address Space, HPAS),每个主机通过 HDM(Host-managed Device Memory)解码器将其分配给自己的地址空间。 安全性挑战在于: 内存释放后的数据残留:当一台主机释放一块 CXL…

Intel TDX MMIO 暗门

摘要 Intel Trust Domain Extensions 通过内存加密和 MRTD 测量为信任域提供硬件级隔离,使 VM 免受即使已被攻陷的 VMM 的侵害。然而,TD 与 VMM 之间共享内存的设计引入了一个根本性的信任悖论:TD 依赖 VMM 维护的 EPT 映射来访问共享页,而 EPT 由不可信的 VMM 完全控制。攻击者(即恶意 VMM)可在 TD 向共享页写入数据后、读取响应前的极短时间内,将 EPT 中的 GPA→HPA 映射切换到包含恶意数据的物理页,实现 L2 地址劫持。由于 TDX 的运行时 EPT 变更不会被证明报告捕获,该攻击可完全绕过远程验证。 TDX 的信任边界 信任域与不可信 VMM Intel TDX 将虚拟机封装为信任域,其内存由 MKTME(多密钥全内存加密)引擎使用 TD 私钥加密,VMM 无法解密读取。TD 的 CPU 状态、寄存器和缓存也被隔离。远程验证方通过 MRTD(TD 内容的 SHA-384 测量)确认…

WebRTC 插入流音频劫持

摘要 WebRTC 通过 RTCRtpSender.setParameters() 允许动态调整编码参数,其 encodings 数组用于描述 simulcast 各层的 rid 和 active 状态。然而,Chromium 实现中,对该数组与底层 RTP 流同步源的映射更新并非原子操作——攻击者可在重协商信令阶段插入一个携带伪造 rid 的高优先级编码条目,调用 setParameters() 后,内部编码器可能为这个新条目分配独立的 SSRC,而该 SSRC 并未出现在远端 SDP 中。此时音频数据会被同时发送到合法接收者和攻击者控制的 SSRC,形成无声监听。更隐蔽的是,利用 RTCRtpContributingSource 统计信息无法及时反映这一变化,使得劫持长期隐匿。 Simulcast与RTCRtpEncodingParameters的映射关系 Simulcast 的 RID 与 SSRC WebRTC 的 Simulcast 允许一个发送器(RTCRtpSender)同时生成多个不同码率或分辨率的视频/音频流,每个流由一个独立的 SSRC 标识。 在 SDP 协商中,a=simulcast:send 属性声明了这些流的 rid(Restriction Identifier),接收方根据 rid 识别流。例如: a=simulcast:send low;medium;high a=rid:low send pt=96;max-br=100000 a=rid:medium send pt=96;max-br=500000 a=rid:high send pt=96;max-br=1000000 在发送方,RTCRtpSender.getParameters().encodings 返回一个数组,每个元素对应一个 simulcast 层,包含 rid、active、maxBitrate 等属性。底层媒体引擎根据这些参数创建独立的 RTP 编码流,每个流对应唯一的 SSRC,并且该 SSRC 会通过 a=ssrc: 属性在 SDP 中声明。正常情况下,rid 与 SSRC 的映射在 setParameters() 调用后保持不变,除非明确移除或禁用某层。 setParameters的非原子性 setParameters() 允许修改 encodings 数组的某些字段(在…

Swift 中的不可见角色

摘要 Swift 5.10 引入了严格并发检查,通过 @Sendable 闭包和 Actor 隔离在编译期防止数据竞争。然而,这些安全保证几乎完全依赖于编译器的静态分析,运行时缺乏强制机制。攻击者可利用 UnsafeMutablePointer 将非 Sendable 类型强制转换为 @Sendable 闭包,并将其跨 Actor 传递;在另一个 Actor 上通过 withUnsafeCurrentTask 执行任意代码,破坏原 Actor 的状态,实现数据竞争和类型混淆。更隐蔽的是,利用 TaskLocal 传递裸指针,或通过 GCD 直接调度绕过 @MainActor 隔离,可在服务器端 Swift 应用(如 Vapor)中实现持久化的隐蔽后门。 Sendable与 Actor 隔离 Sendable协议的类型安全承诺 Sendable 是 Swift 并发模型的核心协议之一,用于标记可以安全地跨并发域传递的类型。值类型(如 Int、String)、无内部共享状态的 final class 以及显式标记为 @Sendable 的闭包均符合 Sendable。编译器会检查所有跨 Actor 或 Task 传递的值的类型,如果非 Sendable 类型被错误传递,则发出严格并发检查的编译错误或警告。 在底层,@Sendable 闭包会被编译器转换为捕获不可变副本或同步原语保护的上下文,但这一转换完全发生在 SIL(Swift Intermediate Language)层,最终生成的 LLVM IR 中并没有额外的运行时检查。也就是说,一旦绕过编译器的静态检查,运行时将不加区别地执行任何闭包。 Actor 隔离的执行语义 Actor 是一种引用类型,通过串行执行队列保护其内部状态。所有对 Actor 可变状态的访问都必须通过 await 异步调用或在 Actor 内部的同步代码中进行。编译器负责保证这一约束:在 Actor 外部,无法直接访问其存储属性或调用未标记 nonisolated 的方法。 运行时实现上,Actor 携带一个内部的 DistributedActor 标识和串行执行器。当任务需要在 Actor 上执行时,会被调度到该执行器上排队。但 Actor 的执行器本身是可替换的,且 GCD 等旧并发 API 可以绕过这一调度机制,直接将任务提交到任意队列执行。这构成了 Actor…

GPU 虚拟地址投毒

摘要 NVIDIA GPUDirect RDMA 和 CUDA 统一内存允许 GPU 直接访问另一块 GPU 的显存,其底层依赖 IOMMU 将虚拟地址映射到物理页。然而,在统一内存页面迁移期间,旧物理页的 IOMMU 映射可能未被及时刷新,导致 GPU A 在释放本地缓存后仍可通过 GPU B 访问到已被重分配的系统内存。攻击者可利用这一“虚拟地址投毒”缺陷,在容器化的多租户 GPU 集群中实施跨 GPU 数据窃取——读取其他容器的模型参数或推理数据,彻底打破 GPU 内存隔离。 CUDA Unified Memory 与 IOMMU 的协同 统一内存的虚拟地址抽象 CUDA 统一内存提供了一个单一的虚拟地址空间,CPU 和所有 GPU 均可访问。 当应用程序调用 cudaMallocManaged 分配统一内存时,CUDA 驱动在内部创建虚拟地址映射,但物理页最初可能仅在 CPU 端分配。当 GPU 第一次访问该地址时,触发缺页,驱动将页面迁移到 GPU 本地显存。后续若另一个 GPU 访问同一地址,页面可从第一个 GPU 的显存通过 NVLink 或 PCIe 直接迁移。…