
摘要
本技術報告深入分析 CVE-2024-50264 ,一個存在於 Linux Kernel AF_VSOCK 子系統的嚴重 race condition 漏洞。該漏洞允許 use-after-free (UAF) 攻擊,導致權限提升。本分析報告探討此漏洞的技術基礎、攻擊限制以及潛在的緩解策略,並僅專注於技術層面。

1 簡介
Kernel 子系統中的 Race Condition 屬於一類重大的漏洞,由於其時序限制與不穩定性,使其特別難以攻擊。在 Linux Kernel AF_VSOCK 子系統中發現的 CVE-2024-50264 就是其中一個,在2025年的一場主要資安會議上,它被認為是一個特別複雜的攻擊手法 [1] 。
AF_VSOCK 子系統為虛擬機器與其 hosts 之間提供 socket 式的通訊。此漏洞存在於
connect()
系統呼叫和 POSIX 訊號處理之間的 race condition,導致 use-after-free 寫入原語 (primitive)。值得注意的是,此漏洞
不需使用者命名空間 (namespaces)
即可觸發,這使其在受限的環境中更具危險性。
本報告探討 CVE-2024-50264 的技術細節、攻擊挑戰,以及研究人員為實現穩定攻擊所開發的創新方法。
2 漏洞分析
2.1 根本原因與簡介
此漏洞在2016年8月隨 Linux Kernel 4.8 版的 commit 06a8fc78367d 引入。它長達約八年未被發現,直到透過針對 AF_VSOCK 子系統的客製化模糊測試技術才被識別出來 [1] 。
核心問題源於 VSOCK socket 上的
connect()
系統呼叫與 POSIX 訊號傳遞之間的
race condition
。當成功攻擊時,此 race condition 會導致 use-after-free 條件,使得 Kernel 對一個已釋放的
virtio_vsock_sock
物件進行操作。
2.2 技術機制
當一個訊號在有漏洞的 socket 處於
TCP_ESTABLISHED
狀態時中斷了
connect()
系統呼叫,漏洞就會顯現。此訊號中斷導致 socket 轉換到
TCP_CLOSING
狀態:
- if (signal_pending(current)) {
- err = sock_intr_errno(timeout);
- sk->sk_state = sk->sk_state == TCP_ESTABLISHED ? TCP_CLOSING : TCP_CLOSE;
- sock->state = SS_UNCONNECTED;
- vsock_transport_cancel_pkt(vsk);
- vsock_remove_connected(vsk);
- goto out_wait;
- }
隨後,使用不同的
svm_cid
(特別是
VMADDR_CID_HYPERVISOR
) 對同一個伺服器 VSOCK 進行第二次連線,會觸發記憶體損毀。
這個
connect()
呼叫執行
vsock_assign_transport()
,它將虛擬 socket 切換到新的傳輸機制並釋放與先前 VSOCK 傳輸機制相關的資源:
- if (vsk->transport) {
- if (vsk->transport == new_transport)
- return 0;
- vsk->transport->release(vsk);
- vsock_deassign_transport(vsk);
- }
由於錯誤的
TCP_CLOSING
狀態,
virtio_transport_close()
會啟動進一步的通訊,排程一個 Kernel worker (
kworker
),該 worker 最終呼叫
virtio_transport_space_update()
。此函數對已釋放的結構進行操作:
- static bool virtio_transport_space_update(struct sock *sk, struct sk_buff *skb)
- {
- struct virtio_vsock_hdr *hdr = virtio_vsock_hdr(skb);
- struct vsock_sock *vsk = vsock_sk(sk);
- struct virtio_vsock_sock *vvs = vsk->trans; /* UAF: ptr to freed object */
- bool space_available;
- if (!vvs)
- return true;
- spin_lock_bh(&vvs->tx_lock); /* UAF: requires 4 zero bytes */
- vvs->peer_buf_alloc = le32_to_cpu(hdr->buf_alloc); /* UAF write 4 bytes */
- vvs->peer_fwd_cnt = le32_to_cpu(hdr->fwd_cnt); /* UAF write 4 bytes */
- space_available = virtio_transport_has_space(vsk); /* UAF read */
- spin_unlock_bh(&vvs->tx_lock); /* UAF write: restores 4 zero bytes */
- return space_available;
- }
listening
VSOCK
server] --> B[Client
connect
attempt]; B --> C[Signal
interrupts
connect]; C --> D[Socket state:
TCP_CLOSING]; D --> E[Second
connect
with
different CID]; E --> F[Transport
switch
frees
virtio_vsock_sock]; F --> G[Kworker
schedules]; G --> H[UAF
write on
freed
object];
2.3 有漏洞物件的記憶體佈局
virtio_vsock_sock
物件大小為80位元組,從
kmalloc-96
slab 快取中分配。記憶體損毀是由 Kernel worker 執行的 UAF 寫入。攻擊涉及的關鍵欄位包括:
-
tx_lock
(4個位元組): 在嘗試取得自旋鎖 (spinlock) 時,必須包含零,否則 Kernel 會當掉。 -
peer_buf_alloc
(4個位元組): 可控制的4位元組寫入原語 (primitive)。 -
peer_fwd_cnt
(4個位元組): 可控制的4位元組寫入原語 (primitive)。
寫入
virtio_vsock_sock.peer_buf_alloc
的值可以透過 socket 選項從使用者空間控制:
- uaf_val_limit = 0x1lu; /* Cannot be zero */
- setsockopt(vsock1, PF_VSOCK, SO_VM_SOCKETS_BUFFER_MIN_SIZE,
- &uaf_val_limit, sizeof(uaf_val_limit));
- uaf_val_limit = 0xfffffffflu;
- setsockopt(vsock1, PF_VSOCK, SO_VM_SOCKETS_BUFFER_MAX_SIZE,
- &uaf_val_limit, sizeof(uaf_val_limit));
- /* Set the 4-byte value for UAF write */
- setsockopt(vsock1, PF_VSOCK, SO_VM_SOCKETS_BUFFER_SIZE,
- &uaf_val, sizeof(uaf_val));
3 攻擊挑戰與技術
3.1 攻擊限制
CVE-2024-50264 為攻擊開發者帶來了幾項重大挑戰,被研究人員描述為「the worst bug to exploit I've ever seen 」(我見過最難利用的 bug) [1] :
-
分配限制
: 有漏洞的
virtio_vsock_sock
用戶端物件與伺服器物件從同一個 slab 快取中分配,這為記憶體操作帶來困難。 -
時序敏感性
: race condition 需要
connect()
呼叫與訊號傳遞之間的精確時序,這使得穩定攻擊具有挑戰性。 -
狀態管理
: socket 必須在攻擊過程中的精確時刻處於特定狀態 (先是
TCP_ESTABLISHED
,接著是TCP_CLOSING
)。 - 記憶體損毀限制 : UAF 寫入原語 (primitive) 僅限於已釋放物件內的特定欄位,這限制了可能的記憶體修改類型。
3.2 訊號傳遞技術
研究人員沒有使用傳統訊號 (如
SIGKILL
,會終止攻擊程序),而是發現一種創新的方法,使用訊號33,該訊號由 Native POSIX Threads Library (NPTL) 保留用於內部操作:
- struct sigevent sev = {};
- timer_t race_timer = 0;
- sev.sigev_notify = SIGEV_SIGNAL;
- sev.sigev_signo = 33; /* NPTL internal signal */
- ret = timer_create(CLOCK_MONOTONIC, &sev, &race_timer);
此訊號非常適合攻擊,因為:
-
可以使用
timer_settime()
精確計時 - 對攻擊程序來說是隱形的
- 傳遞後不會終止攻擊程序
程式碼範例
以下程式碼範例說明了漏洞攻擊的關鍵層面:
為 Race Condition 設定訊號
- /* Setup signal 33 for interrupting connect() */
- struct sigevent sev = {};
- timer_t race_timer = 0;
- sev.sigev_notify = SIGEV_SIGNAL;
- sev.sigev_signo = 33; /* NPTL internal signal */
- ret = timer_create(CLOCK_MONOTONIC, &sev, &race_timer);
用於 UAF 控制的 Socket 選項操作
- /* Configure the value to be written during UAF */
- uaf_val_limit = 0x1lu; /* Minimum value (cannot be zero) */
- setsockopt(vsock1, PF_VSOCK, SO_VM_SOCKETS_BUFFER_MIN_SIZE,
- &uaf_val_limit, sizeof(uaf_val_limit));
- uaf_val_limit = 0xfffffffflu; /* Maximum value */
- setsockopt(vsock1, PF_VSOCK, SO_VM_SOCKETS_BUFFER_MAX_SIZE,
- &uaf_val_limit, sizeof(uaf_val_limit));
- /* Set specific value for UAF write */
- setsockopt(vsock1, PF_VSOCK, SO_VM_SOCKETS_BUFFER_SIZE,
- &uaf_val, sizeof(uaf_val));
3.3 攻擊策略
攻擊策略涉及幾個精確步驟:
- 設定 : 建立一個監聽的 VSOCK 伺服器 socket
- 觸發 Race Condition : 啟動連線嘗試,並以精確計時的訊號33中斷它
- 觸發 UAF : 使用不同的 CID 進行第二次連線嘗試以釋放目標物件
- 記憶體操作 : 使用 UAF 寫入原語 (primitive) 修改 Kernel 記憶體結構
- 權限提升 : 利用記憶體修改來獲得更高的權限
UAF 寫入原語 (primitive) 允許修改已釋放物件內特定偏移處的四位元組值,這可以用來劫持 (hijack) Kernel 控制流程或修改關鍵的安全變數。
4 緩解策略
4.1 修補與漏洞管理
根據漏洞管理最佳實踐,像 CVE-2024-50264 這樣的漏洞主要緩解措施是及時修補。Google 的漏洞分類系統根據其嚴重性與攻擊潛力對此類漏洞進行分類 [2,3] :
嚴重程度等級 | 描述 |
---|---|
關鍵 (Critical) | 存在於所有叢集 (cluster),且未經認證的遠端攻擊者可輕易利用並導致完整系統受損的漏洞 |
高 (High) | 存在於許多叢集 (cluster),且攻擊者可利用並導致機密性、完整性或可用性喪失的漏洞 |
中 (Medium) | 存在於部分叢集 (cluster),但因Configuration、攻擊難度、所需存取權限或使用者互動而使機密性、完整性或可用性喪失程度有限的漏洞 |
低 (Low) | 所有其他攻擊可能性極低且後果有限的漏洞 |
4.2 技術緩解
有幾種技術方法可以緩解此類漏洞:
- Use-After-Free 偵測器 : 增強的記憶體除錯器 (debugger) 工具,如 KASAN,有助於在開發與測試期間識別 UAF 條件。
- 引用計數 (Reference Counting) : 改善 Kernel 物件的引用計數機制,可防止過早釋放。
- 鎖定策略 : 在網路子系統的狀態轉換周圍使用更好的鎖定機制,可防止 race condition。
- 靜態分析 : 先進的靜態分析工具可以在程式碼審查程序中識別潛在的 race condition。
5 結論
CVE-2024-50264 代表了 Linux Kernel 中一類複雜的漏洞,需要深入的技術理解和創新的方法才能成功攻擊。它的發現與攻擊證明了 Kernel 漏洞研究的不斷發展,特別是在識別和利用像 AF_VSOCK 這樣複雜子系統中的 race condition 方面。
與攻擊此漏洞相關的技術挑戰—包括時序精確度、訊號處理的複雜性以及記憶體操作限制—突顯了成功攻擊所需的高級技能。同時,此漏洞在被發現前存在近八年的事實,強調了透過傳統測試方法識別此類 race condition 的困難。
從防禦角度來看,CVE-2024-50264 強調了全面模糊測試、先進靜態分析工具和及時修補程序的重要性。隨著 Kernel 安全的不斷演進,此類複雜的漏洞可能會持續成為高階攻擊者的重要目標,並為防禦者帶來挑戰。