推測控制

相當多的 CPU 具有與推測相關的缺陷,這些缺陷實際上是漏洞,導致各種形式的資料洩露,甚至跨越特權域。

核心以各種形式為這些漏洞提供緩解措施。 其中一些緩解措施是編譯時可配置的,有些可以透過核心命令列提供。

還有一類緩解措施非常昂貴,但它們可以限制在受控環境中的特定程序或任務集。 控制這些緩解措施的機制是透過prctl(2)

有兩個與此相關的 prctl 選項

  • PR_GET_SPECULATION_CTRL

  • PR_SET_SPECULATION_CTRL

PR_GET_SPECULATION_CTRL

PR_GET_SPECULATION_CTRL 返回使用 prctl(2) 的 arg2 選擇的推測缺陷的狀態。 返回值使用位 0-3,其含義如下

定義

描述

0

PR_SPEC_PRCTL

可以透過 PR_SET_SPECULATION_CTRL 按任務控制緩解措施。

1

PR_SPEC_ENABLE

推測功能已啟用,緩解措施已停用。

2

PR_SPEC_DISABLE

推測功能已停用,緩解措施已啟用。

3

PR_SPEC_FORCE_DISABLE

與 PR_SPEC_DISABLE 相同,但無法撤消。 後續的 prctl(..., PR_SPEC_ENABLE) 將失敗。

4

PR_SPEC_DISABLE_NOEXEC

與 PR_SPEC_DISABLE 相同,但在 execve(2) 上將清除狀態。

如果所有位均為 0,則 CPU 不受推測缺陷的影響。

如果設定了 PR_SPEC_PRCTL,則可以使用每任務控制緩解措施。 如果未設定,則對推測缺陷的 prctl(PR_SET_SPECULATION_CTRL) 將失敗。

PR_SET_SPECULATION_CTRL

PR_SET_SPECULATION_CTRL 允許控制推測缺陷,該缺陷由 prctl(2) 的 arg2 按任務選擇。 arg3 用於傳入控制值,即 PR_SPEC_ENABLE 或 PR_SPEC_DISABLE 或 PR_SPEC_FORCE_DISABLE。

常見錯誤程式碼

含義

EINVAL

該架構未實現 prctl,或者未使用的 prctl(2) 引數不為 0。

ENODEV

arg2 選擇了一個不受支援的推測缺陷。

PR_SET_SPECULATION_CTRL 錯誤程式碼

含義

0

成功

ERANGE

arg3 不正確,即它既不是 PR_SPEC_ENABLE,也不是 PR_SPEC_DISABLE,也不是 PR_SPEC_FORCE_DISABLE。

ENXIO

無法控制所選的推測缺陷。 請參閱 PR_GET_SPECULATION_CTRL。

EPERM

推測已透過 PR_SPEC_FORCE_DISABLE 停用,並且呼叫者試圖再次啟用它。

推測缺陷控制

  • PR_SPEC_STORE_BYPASS:推測性儲存旁路

    呼叫
    • prctl(PR_GET_SPECULATION_CTRL, PR_SPEC_STORE_BYPASS, 0, 0, 0);

    • prctl(PR_SET_SPECULATION_CTRL, PR_SPEC_STORE_BYPASS, PR_SPEC_ENABLE, 0, 0);

    • prctl(PR_SET_SPECULATION_CTRL, PR_SPEC_STORE_BYPASS, PR_SPEC_DISABLE, 0, 0);

    • prctl(PR_SET_SPECULATION_CTRL, PR_SPEC_STORE_BYPASS, PR_SPEC_FORCE_DISABLE, 0, 0);

    • prctl(PR_SET_SPECULATION_CTRL, PR_SPEC_STORE_BYPASS, PR_SPEC_DISABLE_NOEXEC, 0, 0);

  • PR_SPEC_INDIR_BRANCH:使用者程序中的間接分支推測

    (緩解針對使用者程序的 Spectre V2 樣式攻擊)

    呼叫
    • prctl(PR_GET_SPECULATION_CTRL, PR_SPEC_INDIRECT_BRANCH, 0, 0, 0);

    • prctl(PR_SET_SPECULATION_CTRL, PR_SPEC_INDIRECT_BRANCH, PR_SPEC_ENABLE, 0, 0);

    • prctl(PR_SET_SPECULATION_CTRL, PR_SPEC_INDIRECT_BRANCH, PR_SPEC_DISABLE, 0, 0);

    • prctl(PR_SET_SPECULATION_CTRL, PR_SPEC_INDIRECT_BRANCH, PR_SPEC_FORCE_DISABLE, 0, 0);

  • PR_SPEC_L1D_FLUSH:在任務切換出上下文時重新整理 L1D 快取

    (僅當任務在非 SMT 核心上執行時有效)

    呼叫
    • prctl(PR_GET_SPECULATION_CTRL, PR_SPEC_L1D_FLUSH, 0, 0, 0);

    • prctl(PR_SET_SPECULATION_CTRL, PR_SPEC_L1D_FLUSH, PR_SPEC_ENABLE, 0, 0);

    • prctl(PR_SET_SPECULATION_CTRL, PR_SPEC_L1D_FLUSH, PR_SPEC_DISABLE, 0, 0);