DEXCR (動態執行控制暫存器)

概述

DEXCR 是 PowerPC ISA 3.1B (Power10) 中引入的特權專用暫存器 (SPR),它允許按 CPU 控制幾種動態執行行為。 這些行為包括推測(例如,間接分支目標預測)以及啟用面向返回程式設計 (ROP) 保護指令。

執行控制在硬體中公開為 DEXCR 中最多 32 位(“方面”)。 每個方面控制某個行為,並且可以設定或清除以啟用/停用該方面。 DEXCR 有幾個變體用於不同的目的

DEXCR

一個特權 SPR,可以控制使用者空間和核心空間的方面

HDEXCR

一個超級visor 特權 SPR,可以控制超級visor 的方面,並強制核心和使用者空間的方面。

UDEXCR

一個可選的 ultravisor 特權 SPR,可以控制 ultravisor 的方面。

使用者空間可以使用專用 SPR 來檢查當前的 DEXCR 狀態,該 SPR 提供使用者空間 DEXCR 方面的非特權只讀檢視。 還有一個 SPR 提供超級visor 強制方面的只讀檢視,該檢視與使用者空間 DEXCR 檢視進行 OR 運算,從而給出程序的有效 DEXCR 狀態。

配置

prctl

程序可以使用 PR_PPC_GET_DEXCRPR_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 方面的索引之間沒有關係。

prctl() which

方面名稱

方面索引

PR_PPC_DEXCR_SBHE

投機分支提示啟用 (SBHE)

0

PR_PPC_DEXCR_IBRTPD

停用間接分支重複目標預測 (IBRTPD)

3

PR_PPC_DEXCR_SRAPD

停用子例程返回地址預測 (SRAPD)

4

PR_PPC_DEXCR_NPHIE

非特權雜湊指令啟用 (NPHIE)

5

prctl() ctrl

含義

PR_PPC_DEXCR_CTRL_EDITABLE

此方面可以使用 PR_PPC_SET_DEXCR 進行配置(僅獲取)

PR_PPC_DEXCR_CTRL_SET

已設定此方面/設定此方面

PR_PPC_DEXCR_CTRL_CLEAR

已清除此方面/清除此方面

PR_PPC_DEXCR_CTRL_SET_ONEXEC

執行後將設定此方面/執行後設置此方面

PR_PPC_DEXCR_CTRL_CLEAR_ONEXEC

執行後將清除此方面/執行後清除此方面

請注意

  • 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_DEXCR prctl 更改此設定。

  • 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 返回的狀態表示程序希望應用的值。 它不包括任何替代覆蓋,例如,如果超級visor 強制設定該方面。 要檢視真實的 DEXCR 狀態,軟體應直接讀取相應的 SPR。

  • 啟動程序時的方面狀態從父程序在 fork(2) 上的狀態複製而來。 該狀態在 execve(2) 上重置為固定值。 PR_PPC_SET_DEXCR prctl() 可以控制這兩個值。

  • *_ONEXEC 控制不會更改當前程序的 DEXCR。

使用 PR_PPC_SET_DEXCR 以及 PR_PPC_DEXCR_CTRL_SETPR_PPC_DEXCR_CTRL_CLEAR 之一來編輯給定的方面。

用於獲取和設定 DEXCR 的常見錯誤程式碼如下

錯誤

含義

EINVAL

核心不支援 DEXCR。

ENODEV

核心無法識別該方面,或者硬體不支援該方面。

PR_PPC_SET_DEXCR 也可能報告以下錯誤程式碼

錯誤

含義

EINVAL

ctrl 值包含無法識別的標誌。

EINVAL

ctrl 值包含相互衝突的標誌(例如,PR_PPC_DEXCR_CTRL_SET | PR_PPC_DEXCR_CTRL_CLEAR

EPERM

此方面無法使用 prctl() 修改(使用 PR_PPC_GET_DEXCR 檢查 PR_PPC_DEXCR_CTRL_EDITABLE 標誌)。

EPERM

該程序沒有足夠的許可權來執行該操作。 例如,在 exec 上清除 NPHIE 是一項特權操作(程序仍然可以在沒有許可權的情況下清除自己的 NPHIE 方面)。

此介面允許程序控制自己的 DEXCR 方面,併為程序樹中的任何子程序設定初始 DEXCR 值(直到下一個子程序使用 *_ONEXEC 控制)。 這允許對 DEXCR 的預設值進行細粒度控制,例如允許容器以不同的預設值執行。

coredump 和 ptrace

DEXCR 和 HDEXCR 的使用者空間值(按此順序)在 NT_PPC_DEXCR 下公開。 這些值均為 64 位且只讀,旨在協助生成核心轉儲。 DEXCR 將來可能會變為可寫。 這兩個暫存器的前 32 位(對應於非使用者空間位)被遮蔽掉。

如果核心配置 CONFIG_CHECKPOINT_RESTORE 已啟用,則 NT_PPC_HASHKEYR 可用,並公開程序的 HASHKEYR 值以進行讀取和寫入。 這是提高安全性和檢查點/恢復支援之間的一種權衡:程序通常不需要知道其金鑰,但恢復程序需要設定其原始金鑰。 因此,金鑰出現在核心轉儲中,攻擊者可能能夠從核心轉儲中檢索到該金鑰,並有效地繞過共享此金鑰的任何執行緒上的 ROP 保護(可能來自同一父程序的所有尚未執行 exec() 的執行緒)。