MPK学习笔记


MPK(转载)

转载自:https://mstmoonshine.github.io/p/intra-unikernel-mpk/#:~:text=Memory%20Protection%20Keys%20(MPK)%20%E6%98%AF,%E9%9A%94%E7%A6%BB%E6%9D%A5%E6%8F%90%E5%8D%87%E5%AE%89%E5%85%A8%E6%80%A7%E3%80%82

MPK 的目标是提供每个 core 独立的内存访问权限管理。使用 MPK 之前,首先要将内存分组,最多分成 16 组。这 16 组的二进制编号 0b0000 ~ 0b1111 被称为 protection key。MPK 使用 x86 page table 中的 4 个 unused bits 来 label 分组信息:比如,如果这 4 个 bits 被设置成 0b1001,那么这个 page 就属于第 9 组。

分组之后,MPK 的使用就无需页表参与了。CPU 的每个 core 都有一个 32-bit 的寄存器(PKRU)来储存当前 core 对每个组的访问权限。PKRU 寄存器中包含 16 对 bit pair,对应 16 个 page group,每个 pair 包含两个 bit, 分别代表 R / W 权限。每个 pair 的取值对应三种可能的权限 (0, 0): read/write,(1, 0): read-only,(x, 1): no-access。如下图所示:

注:尽管图中的 Group 15 和 Group 14 中 page 都是连续的,但是这并不是必须的。)

PKRU 寄存器可以通过 WRPKRU 和 RDPKRU 这两条指令来写入/读取。

到此为止 MPK 看起来很像 Arm 中的 TZASC 或者 RISC-V 中的 PMP。但是 MPK 和它们有一个重大区别:WRPKRU 和 RDPKRU 都不是特权指令!也就是说,在 ring 3(User space)中就可以直接运行这两条指令,来修改 MPK 的设置。

因为这个 PKRU 不是由特权指令读写的,MPK 能够提供的安全性其实是相当有限的,那要它还有什么用呢?MPK 的优点在于快,进行一次 PKRU 读写只需要 20 cycles 左右,相比进行一次 context switch 来说,PKRU 的切换非常快速。

因此 MPK 的目标并不是去防御尽可能多的攻击,而是以非常廉价的开销去防御一些特定类别的攻击。

参考

https://mstmoonshine.github.io/p/intra-unikernel-mpk/#:~:text=Memory%20Protection%20Keys%20(MPK)%20%E6%98%AF,%E9%9A%94%E7%A6%BB%E6%9D%A5%E6%8F%90%E5%8D%87%E5%AE%89%E5%85%A8%E6%80%A7%E3%80%82


文章作者: q1ming
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 q1ming !
  目录