一行splice()摧毀Linux核心隔離:
1. 簡介
報告提供了 DirtyDecrypt (CVE-2026-31635) 的全面技術分析,這是一個在 Linux kernel 的 RxGK 子系統中發現的關鍵本機權限提升(Local Privilege Escalation, LPE)漏洞。該漏洞源於 page-cache 毀損機制,具體是透過
MSG_SPLICE_PAGES
aliasing,使得無特權的本機使用者可以取得 root 權限。報告深入探討漏洞的技術細節、攻擊機制、受影響的元件以及緩解策略。報告也將此漏洞與「Dirty」系列中的相關漏洞(例如 Dirty Frag)進行比較,以提供對這類 kernel 漏洞更廣泛的認識。
2. 技術背景
Linux kernel 採用了多種機制來最佳化資料處理與跨行程通訊(Inter-Process Communication, IPC)。其中關鍵的機制包括 page cache 與 zero-copy 操作,特別是透過
splice()
系統呼叫。page cache 是一個基礎元件,會將近期存取的檔案資料儲存在 RAM 中,大幅加速後續的讀取與寫入操作。zero-copy 機制(例如
splice()
)用途為透過直接在 kernel 緩衝區(如 pipe、socket)之間傳輸資料,避免將資料複製到使用者空間,進而降低 CPU 負擔。這些機制雖然非常高效,但如果實作或安全防護不當,可能會引入漏洞,導致未經授權的記憶體存取或修改。
「Dirty」系列的漏洞,包括 Dirty Pipe (CVE-2022-0847) 與 Copy Fail (CVE-2026-31431),都利用這些資料處理路徑中的缺陷,通常與不足的 Copy-on-Write (COW) 保護有關。這類漏洞通常讓無特權的程序能修改 page cache 中的唯讀頁面,進而毀損敏感檔案或記憶體區域,最終達到本機權限提升。DirtyDecrypt 延續了這個脈絡,但目標鎖定在 RxGK 子系統,這是 RxRPC(遠端程序呼叫)的一個 GSS-API 安全層,主要用於 Andrew File System (AFS)。
3. 漏洞分析 (CVE-2026-31635)
DirtyDecrypt,也稱為「DirtyCBC」,是一個存在於 Linux kernel 之 RxGK 子系統中的本機權限提升(LPE)漏洞。漏洞的核心在於
rxgk_decrypt_skb()
函式中存在一個嚴重的缺陷:缺少 Copy-on-Write (COW) 防護機制,導致 page-cache 可以被毀損。這個問題發生在 decrypt-before-MAC 操作期間,該操作作用於
sk_buff
scatterlist 頁面,而這些頁面可能 alias 到 page-cache 頁面,特別是透過
MSG_SPLICE_PAGES
aliasing 引入的頁面。
漏洞的攻擊鏈涉及數個 kernel 函式 [1] :
rxgk_verify_response() -> rxgk_extract_token() -> rxgk_decrypt_skb() -> skb_to_sgvec() -> crypto_krb5_decrypt()
在這個序列中,
rxgk_decrypt_skb()
函式負責解密傳入的 RxGK 封包。然而,如果
sk_buff
(socket buffer) 包含的頁面同時也是 page cache 的一部分且被共享(例如透過
splice()
操作),而且沒有正確強制執行 COW 機制,那麼原地解密程序就可能不小心寫入這些共享的、理論上應為唯讀的 page-cache 頁面。這讓攻擊者可以修改 page cache 中的任意資料,進而覆寫敏感檔案(例如
/etc/shadow
或
/usr/bin/su
),最終取得 root 權限。
該漏洞利用了 AES-CBC 選擇明文構造(chosen-plaintext construction),使攻擊者能精確控制對 page cache 的修改。受影響的系統主要是那些啟用
CONFIG_RXGK
的系統,包括 Fedora、Arch Linux 和 openSUSE Tumbleweed 等發行版。此漏洞風險極高,特別是在容器化環境中,若 Kubernetes 節點使用滾動更新的發行版,就可能容易受到攻擊。
4. 程式碼分析與架構流程
雖然原始文章沒有提供
rxgk_decrypt_skb()
的直接原始程式碼,但描述中強調了它在漏洞中的角色。該函式中缺少適當的 COW 防護是關鍵缺陷。概念上,該函式處理網路封包,在解密過程中會直接操作
sk_buff
的資料。如果這份資料指向一個 page-cache 頁面,而無特權使用者已經操作該頁面使其被共享,那麼解密寫入操作就會直接修改 page cache,繞過安全防護。
該漏洞的架構流程可以用下圖表示:
此圖展示了 DirtyDecrypt 漏洞的攻擊流程。無特權使用者首先透過 splice() 建立檔案 page cache 頁面別名 (aliasing),使該頁面可被後續網路封包處理流程引用。當 kernel 處理一個合法的 RxGK 封包時,會進入 rxgk_decrypt_skb(),並在資料尚未完全驗證的情況下進行解密。由於缺乏 Copy-on-Write (COW) 機制,解密操作會直接對該共享的 page cache 頁面進行 in-place 修改。攻擊者因此可藉由控制封包內容,對底層檔案進行部分或任意覆寫,進而竄改敏感系統檔案,最終達成權限提升至 root。
使用 Falco 規則進行偵測
為了偵測可能的漏洞利用嘗試或有漏洞模組的存在,可以使用 Falco 規則。原始文章建議使用一條規則來偵測
rxgk
模組的載入
[1]
:
- rule: rxgk_module_loaded_on_production_host
desc: rxrpc kernel module loaded on a production host outside the maintenance window (heuristic for DirtyDecrypt exploit attempt)
condition: >
spawned_process and
proc.name = "modprobe" and
proc.cmdline contains "rxrpc"
output: >
rxrpc module load detected (proc=%proc.name cmdline=%proc.cmdline user=%user.name pid=%proc.pid host=%container.hostname)
priority: WARNING
tags: [cve-2026-31635, dirtydecrypt, linux-kernel, lpe]
- rule: unexpected_rxgk_decrypt_skb_activity
desc: Unusual kernel activity around rxgk decryption path
condition: >
evt.type = "syscall" and
syscall.name in ("setresuid", "setreuid", "setuid") and
proc.aname[1] = "rxgk_decrypt_skb"
output: >
Unexpected privilege change from rxgk path (proc=%proc.name user=%user.name)
priority: CRITICAL
tags: [cve-2026-31635, dirtydecrypt]
第一條規則監控透過
modprobe
載入
rxrpc
kernel 模組的行為,這是可能與 RxGK 子系統相關活動的強烈指標。第二條規則是概念啟發式規則,目的在偵測源自
rxgk_decrypt_skb
函式的非預期權限變更(例如
setuid
、
setresuid
),這將表示一次成功的 LPE 攻擊嘗試。
5. 與 Dirty Frag 的比較
DirtyDecrypt 與另一個重大的 Linux kernel 漏洞 Dirty Frag 有著概念上的相似性。Dirty Frag 是一個複合式漏洞,它串聯了兩個不同的 page-cache 寫入缺陷:xfrm-ESP Page-Cache Write (CVE-2026-43284) 與 RxRPC Page-Cache Write (CVE-2026-43500) [2] 。DirtyDecrypt 與 Dirty Frag 都利用了在對 page cache 進行別名的網路緩衝區進行原地解密時,因缺少 COW 防護而產生的漏洞。
主要的差異在於它們所針對的特定 kernel 函式與子系統不同。DirtyDecrypt 專門針對 RxGK RESPONSE 路徑中的
rxgk_decrypt_skb()
,而 Dirty Frag 則針對 xfrm-ESP 子系統中的
esp_input()
函式,以及另一個獨立的 RxRPC 路徑。在 Dirty Frag 的 xfrm-ESP 變體中,
esp_input()
函式略過了
skb_cow_data()
檢查,使得原地 AEAD 解密能夠覆寫共享的 page-cache 頁面。實際的寫入操作發生在
crypto_authenc_esn_decrypt()
中,它會在 scatter-gather list (SGL) 中的一個受控偏移量位置,執行一個 4 位元組的寫入
[2]
。
針對 Dirty Frag 的修補方式引入了
SKBFL_SHARED_FRAG
旗標,並在
esp_input()
中強制進行 COW 檢查:如果該旗標被設定,就會將資料複製到一個私有緩衝區,然後才執行任何原地操作,從而防止修改原始的 page cache
[2]
。
這些漏洞的共同特徵凸顯了 kernel 網路堆疊處理中一類更廣泛的問題:當 zero-copy 最佳化與原地加密操作結合時,如果沒有嚴格落實 COW 語意,就可能導致安全繞過。
6. 緩解與防禦
解決 CVE-2026-31635 需要多管齊下的策略,重點在於修補、應急措施與主動偵測。主要的緩解措施是套用 kernel 修補程式。針對 DirtyDecrypt 的有效上游修補是 commit
aa54b1d27fe0
(2026年5月10日),它修改了 kernel,讓它在執行原地解密之前,先複製帶有共享片段的封包。這能確保 page cache 不會在加密操作過程中被意外修改
[1]
。
對於無法立即套用修補程式的系統,可以實施應急措施。其中一個應急措施是將
rxrpc
與
rxgk
kernel 模組加入黑名單。這可以防止有漏洞的程式碼路徑被載入與執行,從而降低風險。然而,這種方法可能會影響依賴這些模組的功能,例如 AFS。
執行時期的安全解決方案(如 Falco 與 Tetragon)在偵測漏洞利用企圖方面扮演著關鍵角色。第4節討論的 Falco 規則提供了一種機制,可以向管理員發出可疑活動的警報,例如載入
rxrpc
模組,或源自 RxGK 解密路徑的非預期權限變更。這些工具提供即時的 kernel 活動可視性,有助於識別並回應正在進行的攻擊。
7. 結論
DirtyDecrypt (CVE-2026-31635) 代表了 Linux kernel RxGK 子系統中一個重大的本機權限提升漏洞。其機制根源於在對 page-cache 別名的網路緩衝區進行原地解密時,缺少一個 Copy-on-Write 防護,這突顯了複雜 kernel 元件中效能最佳化與安全性之間的微妙平衡。此漏洞允許無特權使用者取得 root 存取權限的能力,再次強調了即時修補與強大的執行時期安全監控的重要性。透過了解 DirtyDecrypt 的技術細節及其與其他「Dirty」漏洞的相似之處,系統管理員與安全專業人員可以更好地防禦這類複雜的 kernel 漏洞,確保基於 Linux 之系統的完整性與安全性。