DEXCR (Dynamic Execution Control Register)¶
概述¶
DEXCR 是在 PowerPC ISA 3.1B (Power10) 中引入的一个特权专用寄存器 (SPR),它允许按 CPU 控制多种动态执行行为。这些行为包括推测执行(例如,间接分支目标预测)以及启用面向返回的编程(ROP)保护指令。
执行控制在硬件中表现为 DEXCR 中的最多 32 位(称为“方面”(aspects))。每个方面控制特定的行为,并且可以通过设置或清除来启用/禁用该方面。出于不同的目的,DEXCR 有几种变体:
- DEXCR
一个可以控制用户空间和内核空间方面的特权 SPR。
- HDEXCR
一个虚拟机监控程序(hypervisor)特权的 SPR,可以控制 hypervisor 的方面并强制内核和用户空间实施某些方面。
- UDEXCR
一个可选的超级监控程序(ultravisor)特权的 SPR,可以控制 ultravisor 的方面。
用户空间可以使用专用的 SPR 来检查当前的 DEXCR 状态,该 SPR 提供用户空间 DEXCR 方面的非特权只读视图。还有一个 SPR 提供 hypervisor 强制方面的只读视图,将其与用户空间 DEXCR 视图进行按位或(OR)运算即可得出进程的有效 DEXCR 状态。
配置¶
prctl¶
进程可以使用成对的 PR_PPC_GET_DEXCR 和 PR_PPC_SET_DEXCR prctl(2) 命令来控制其自己的用户空间 DEXCR 值。这些调用的形式如下:
prctl(PR_PPC_GET_DEXCR, unsigned long which, 0, 0, 0);
prctl(PR_PPC_SET_DEXCR, unsigned long which, unsigned long ctrl, 0, 0);
可能的 ‘which’ 和 ‘ctrl’ 值如下。注意,‘which’ 值与 DEXCR 方面的索引之间没有任何关系。
|
方面名称 |
方面索引 |
|---|---|---|
|
推测分支提示启用 (SBHE) |
0 |
|
间接分支循环目标预测禁用 (IBRTPD) |
3 |
|
子例程返回地址预测禁用 (SRAPD) |
4 |
|
非特权哈希指令启用 (NPHIE) |
5 |
|
含义 |
|---|---|
|
此方面可使用 PR_PPC_SET_DEXCR 进行配置(仅用于获取返回的标志) |
|
此方面已设置 / 设置此方面 |
|
此方面已清除 / 清除此方面 |
|
执行 exec 后将设置此方面 / 在 exec 后设置此方面 |
|
执行 exec 后将清除此方面 / 在 exec 后清除此方面 |
请注意
which 是一个普通值,而不是位掩码。必须单独处理各个方面。
ctrl 是一个位掩码。
PR_PPC_GET_DEXCR返回当前配置和 onexec 配置。例如,PR_PPC_GET_DEXCR可能返回PR_PPC_DEXCR_CTRL_EDITABLE | PR_PPC_DEXCR_CTRL_SET | PR_PPC_DEXCR_CTRL_CLEAR_ONEXEC。这表示该方面当前已设置,当您运行 exec 时将被清除,并且您可以使用PR_PPC_SET_DEXCRprctl 来更改它。设置/清除(set/clear)术语是指设置/清除 DEXCR 中的位。例如:
prctl(PR_PPC_SET_DEXCR, PR_PPC_DEXCR_IBRTPD, PR_PPC_DEXCR_CTRL_SET, 0, 0);
将设置 DEXCR 中的 IBRTPD 方面位,从而导致间接分支预测被禁用。
PR_PPC_GET_DEXCR返回的状态表示进程希望应用的值。它不包含任何替代覆盖,例如 hypervisor 是否强制设置了该方面。要查看真实的 DEXCR 状态,软件应直接读取相应的 SPR。启动进程时的方面状态在 fork(2) 时从父进程的状态复制而来。在 execve(2) 时状态重置为固定值。PR_PPC_SET_DEXCR
prctl()可以控制这两个值。*_ONEXEC控件不会改变当前进程的 DEXCR。
使用带有 PR_PPC_DEXCR_CTRL_SET 或 PR_PPC_DEXCR_CTRL_CLEAR 之一的 PR_PPC_SET_DEXCR 来编辑给定的方面。
获取和设置 DEXCR 的常见错误代码如下:
错误 |
含义 |
|---|---|
|
内核不支持 DEXCR。 |
|
内核不识别该方面,或者硬件不支持该方面。 |
PR_PPC_SET_DEXCR 还可能报告以下错误代码:
错误 |
含义 |
|---|---|
|
ctrl 值包含无法识别的标志。 |
|
ctrl 值包含互相冲突的标志(例如, |
|
无法使用 |
|
进程没有足够的权限来执行该操作。例如,在 exec 时清除 NPHIE 是一个特权操作(进程仍然可以在没有权限的情况下清除其自己的 NPHIE 方面)。 |
此接口允许进程控制其自己的 DEXCR 方面,并为其进程树中的任何子进程设置初始 DEXCR 值(直到下一个使用 *_ONEXEC 控件的子进程)。这允许对 DEXCR 的默认值进行精细控制,例如允许容器以不同的默认值运行。
coredump 和 ptrace¶
DEXCR 和 HDEXCR 的用户空间值(按此顺序)通过 NT_PPC_DEXCR 暴露。它们各自为 64 位且只读,旨在辅助核心转储(core dumps)。DEXCR 在将来可能会变为可写。这两个寄存器的高 32 位(对应于非用户空间位)被屏蔽掉。
如果启用了内核配置 CONFIG_CHECKPOINT_RESTORE,则 NT_PPC_HASHKEYR 可用,并公开用于读写的进程 HASHKEYR 值。这是增强安全性与支持检查点/恢复之间的一种权衡:进程通常不需要知道其密钥,但恢复进程需要设置其原始密钥。因此,该密钥会出现在核心转储中,攻击者可能能够从 coredump 中检索它,并有效地绕过共享此密钥的任何线程(可能来自未运行 exec() 的同一父进程的所有线程)上的 ROP 保护。