Spaghettifying DRAM
Spaghettifying DRAM (DRAM 意大利面化)
skitter-creek-bath-salts Unlocking everything on the CPU with DRAM scrambling — PSP, C6, microcode, SMM, and anything else the specs left out. &x == &x. Usually. Poke the DRAM controller and an address can be made to land wherever you want in memory. skitter-creek-bath-salts modifies the bottom layers of the memory hierarchy to rewire the physical DRAM address translations. This scrambles platform memory, exposing protected regions of DRAM — carveouts invisible even to the kernel. When the address translations break, so do the security primitives built on them, and we unlock everything.
skitter-creek-bath-salts 通过 DRAM 加扰解锁 CPU 上的所有内容——包括 PSP、C6、微代码、SMM 以及规范中遗漏的任何其他内容。通常情况下,&x == &x。但只要触动 DRAM 控制器,就可以让地址落在内存中的任何位置。skitter-creek-bath-salts 修改了内存层级的最底层,以重新连接物理 DRAM 地址转换。这会扰乱平台内存,暴露受保护的 DRAM 区域——即便是内核也无法察觉的隐藏区域。当地址转换失效时,建立在其上的安全原语也会随之失效,从而解锁一切。
TL;DR
- Unlock your Platform Security Processor
- Unlock System Management Mode
- Unlock C6 DRAM
- Unlock your CPU microcode
简而言之
- 解锁你的平台安全处理器 (PSP)
- 解锁系统管理模式 (SMM)
- 解锁 C6 DRAM
- 解锁你的 CPU 微代码
Target
Developed and tested on AMD Family 16h CPUs, the last generation whose datasheets document the DRAM controller’s translation registers — and show that they can’t be locked. 17h and beyond simply leave this information out. The odyssey of *p is similar across generations and architectures, and the underlying transforms extend even to ARM, RISC-V, and beyond; skitter-creek-bath-salts shows us only how to begin.
目标
该项目在 AMD Family 16h CPU 上开发并测试,这是最后一代在数据手册中记录了 DRAM 控制器转换寄存器,并显示其无法被锁定的架构。17h 及以后的版本干脆省略了这些信息。*p 的旅程在不同代际和架构中是相似的,其底层的转换甚至延伸到 ARM、RISC-V 等架构;skitter-creek-bath-salts 只是向我们展示了如何开始。
The odyssey of *p
It’s a long way down. Memory is built on layers of abstraction so deep they become almost absurd. When your code dereferences *p, it appears to access the DRAM at p. It does not — p is a virtual address, and before a single bit of DRAM is touched, it must survive the gauntlet below:
*p 的旅程
这是一条漫长的下行之路。内存建立在极其深奥的抽象层之上,深到近乎荒谬。当你的代码解引用 *p 时,它看起来是在访问 p 处的 DRAM。事实并非如此——p 是一个虚拟地址,在触及 DRAM 的任何一位之前,它必须经历以下重重考验:
(此处省略复杂的内存寻址流程图)
This project works at the deepest levels of the *p pipeline, the MCT/DCT layer — where a physical address from the data fabric/interconnect enters the memory controller and is rewritten one final time into the raw DRAM coordinates that are issued to the DIMM.
该项目工作在 *p 流水线的最深处,即 MCT/DCT 层——在这里,来自数据结构/互连的物理地址进入内存控制器,并被最后一次重写为发送给 DIMM 的原始 DRAM 坐标。
Spaghettifying DRAM
Physical addresses are really more of a suggestion. xor dword [0xf80c2094], 0x00400000. That’s the exploit. All of it. One bit-flip in the DRAM controller rewires the bottom of the *p pipeline, and the data that was at &x is now somewhere else mid-flight. Suddenly &x != &x. Every mechanism the CPU, firmware, uncore, and chipset use to wall off protected memory sits above the memory controller, and none of it sees what happens below. The fences guard physical addresses, not DRAM coordinates; rearrange the coordinates and the barriers above never notice. But rewiring DRAM is easy. The bit above is the bank-swizzle-mode in the DCT, and it’s just one of dozens that control the address remaps at the final layer — all you have to do is poke them to make everything built.
DRAM 意大利面化
物理地址实际上更像是一种建议。xor dword [0xf80c2094], 0x00400000。这就是漏洞利用的全部。DRAM 控制器中的一个位翻转重新连接了 *p 流水线的底部,原本位于 &x 的数据在传输过程中被转移到了别处。突然间,&x != &x 了。CPU、固件、非核心组件 (uncore) 和芯片组用于隔离受保护内存的每一种机制都位于内存控制器之上,它们都无法看到底层发生了什么。这些围栏保护的是物理地址,而不是 DRAM 坐标;只要重新排列坐标,上层的屏障就永远不会察觉。但重连 DRAM 很容易。上面的位是 DCT 中的 bank-swizzle-mode,它只是控制最终层地址重映射的数十个位之一——你所要做的就是触动它们,从而重构一切。