Linux 資訊安全 CVE 虛擬化 KVM

Zapscape 把 KVM 的 shadow MMU 從冷路徑燒回主戰場:CVE-2026-64561 用 root 回收順序 UAF 讓開 nested 的 L1 客體踹進 host kernel

CVE-2026-64561(Zapscape)是潛伏近六年的 KVM/x86 shadow MMU use-after-free,L1 客體只要有 kernel 權限、host 開著 nested 虛擬化,AMD 無條件命中、Intel 在 Ice Lake-SP 之後也踩得到,攻擊者可以直接在 host 上拿 root。本文拆解 root 回收順序寫錯的技術根因、兩家 CPU 觸發條件差異,以及 VPS 主機商該不該繼續對外開放 nested。

Hyunwoo Kim(@v4bel)在 2026 年 8 月 6 日公開的 CVE-2026-64561——命名為 Zapscape——是一支潛伏近六年的 Linux KVM/x86 use-after-free 漏洞。攻擊者只要在 L1 客體裡拿到 kernel 權限、host 又剛好把 nested 虛擬化打開,就能踩著兩條 page fault 路徑對 shadow MMU root 的檢查順序寫錯,把 host kernel 的頁面對映拆掉、換成自己控制的內容。修補 commit 2abd5287f083 於 7 月 21 日進上游,第一批帶修法的穩定版是 6.6.148、6.12.101、6.18.42、7.1.6 與 7.2-rc5。研究者也一併釋出可運行的 PoC,能直接在 host 上取得 root,不是常見那種把整台實體機 panic 掉。

觸發條件表面看很窄:要 L1 客體 kernel 權限、要 nested 開著。但攤到多租戶 VPS 或雲主機環境,這兩個條件加起來的爆炸半徑一次滿版——只要一個租戶把 nested 打開跑自己的 workload,就等於把整台實體機的 host root 攤在攻擊者面前,同一台上的所有其他客戶跟著陪葬。

shadow MMU 在 EPT 時代原本應該沒人在跑

KVM 為每個客體維護一份 shadow page table,把客體眼裡的虛擬位址翻成 host 上的實體位址。早期 Intel 沒有硬體支援時,這件事完全靠 shadow MMU 用軟體模擬,代價非常重:每次客體改自己的頁表,host 都得跟著同步,效能痛到讓人記得。

Intel 從 Nehalem 世代開始加入 EPT(Extended Page Tables),AMD 更早就有 NPT(Nested Page Tables),本質是「客體有自己的頁表、host 有自己的頁表,硬體做兩次翻譯」。有了 EPT/NPT,shadow MMU 這條軟體路徑對非 nested 的一般 VM 幾乎不會被喚醒;KVM 內部有旗標判斷,能走硬體就絕不進 shadow 這條老路。

問題在 nested。當 L0(host)跑一台 L1 客體、L1 又要在自己裡面跑 L2 客體時,硬體只提供兩層 EPT 翻譯,L2 的頁表無法直接交給 CPU。KVM 的解法是把 L2 對 L1 的視角,用 shadow MMU 模擬回來——這時 shadow page 又活起來了。多租戶雲上開放 nested 的機器,等於把這條長期沒人跑的程式碼重新點燃,也就是 Zapscape 的舞台。

那條 root 回收順序寫反了

Zapscape 的核心是「檢查時機」錯位。KVM 在處理客體 page fault 時走兩條路徑:direct_page_fault() 給不需要 shadow 分頁的情況、FNAME(page_fault)() 給 shadow paging 需要重建的情況。兩條路徑都會呼叫 is_page_fault_stale(),確認目前使用的 shadow MMU root 是不是已經被作廢;如果是,就要放棄這次 fault、走 reload。

問題出在 is_page_fault_stale() 被放在 make_mmu_pages_available() 之前執行。後者這一步是回收記憶體——當 KVM 的 shadow page 配額用完,會強制清掉一批舊的,其中就包含 root 本身。原本的預期是「先確認 root 有效、才繼續建立 mapping」,但既然檢查發生在回收之前,只要在檢查通過後、還沒把 mapping 建到硬體暫存器之前,L0 這邊剛好把 root 回收掉,那條 fault 路徑仍會照原本的計畫繼續,把新的 shadow page 掛到已經被作廢的 root 底下。

shadow page 的 role 會繼承父節點狀態,被回收的 root 生下來的子頁面也帶著 invalid 旗標,這些 invalid page 又被丟回 active MMU pages 清單。接著 KVM 為了整理清單觸發 mmu_page_zap_pte() 的 recursive zap 路徑;這條路徑沒有 root_count guard,照樣讀寫已經被釋放的結構,UAF 就這樣落地。

寫出來像一堆流程細節,拆成一句話:兩個檢查函式的呼叫順序寫反,剩下的全都跟著沿路走進 UAF。修法 patch 只動了兩個檔案、大約十來行程式碼,做的事情就是把 is_page_fault_stale() 挪到 make_mmu_pages_available() 之後,順便補上該有的 guard。

AMD 中一次、Intel 要湊條件

兩家 x86 廠商對 nested EPT 的暴露規則不同,這是 Zapscape 表面上「AMD 全面命中、Intel 挑機器」的直接原因。

AMD 的 SVM 加 NPT 沒有針對 nested 額外的暴露條件。只要 L0 允許 L1 客體看到 nested 能力(modprobe kvm_amd nested=1,多數 Linux 發行版預設就是這個值),L1 客體就能誘發 shadow MMU 進入 Zapscape 的 code path,把 host 拉下水。

Intel 的 EPT 情況比較複雜。要走到有 bug 的 shadow MMU 路徑,L0 得同時把 4 級與 5 級 EPT page-walk length 都攤給 L1;如果只暴露其中一種,L1 建 L2 的 shadow 時 KVM 會直接走硬體 EPT 或走純軟體 fallback,都不會踩到 recursive zap。這個條件在 Ice Lake-SP 之前的 Xeon 通常不會被觸發;Ice Lake-SP 開始,5 級分頁進到主流,只要 L0 沒特別關,L1 就會看到兩種都能用。

實務上這代表:AMD EPYC 系列 VPS 只要開啟 nested 就中;Intel Xeon Scalable 第三代(Ice Lake-SP)之後如果沒手動限制 EPT 暴露也會中;更舊的 Intel CPU 或 L0 端有把 5 級 EPT 藏起來的部署可以躲過。多租戶環境不能靠「這是 Intel 平台」當防禦,Ice Lake-SP 是 2021 年出貨的世代,在雲主機池裡早就是主流。

修補之外,nested 該不該繼續對外開放

第一步是打 kernel 修補:升到 6.6.148、6.12.101、6.18.42、7.1.6、7.2-rc5,或直接跟發行版的 CVE tracker 對版本。Debian 13、Ubuntu 24.04、Rocky 與 RHEL 9、Proxmox VE 8 都在公告後幾天內釋出對應 backport,正常補丁節奏跟上去就好。

真正需要重新想的是「nested 虛擬化該不該對外開放」。對 VPS 主機商而言,nested 是給少數客戶方便,例如客戶要在 VPS 裡跑 Docker in Docker、跑 CI runner、或做 kernel 開發測試。這批需求規模不大、但一旦開放,等於把 shadow MMU 這條非熱路徑的攻擊面全面打開;未來 KVM 在這塊冷路徑再爆一個類似 bug 的機率不低——Zapscape 本身就是潛伏近六年、上游 review 過的程式碼,被人重新看才發現的。

短期建議直接把 nested 關掉:

1
2
options kvm_amd nested=0
options kvm_intel nested=0

放進 /etc/modprobe.d/kvm-nested.conf,重載 kvm_* module 或重開機生效。想留給少數需要 nested 的客戶,比較穩的做法是把這批 workload 拉到獨立主機池,跟其他租戶物理隔離、獨立跟 kernel 更新節奏。這個切分邏輯在雲原生裡並不新,做法上很像資料庫跟前端分池,只是這次分池的軸線是安全屬性而不是資源屬性。

/dev/kvm 的權限也值得順手收一遍。這支節點檔案在許多發行版預設 group 是 kvm、mode 660,如果 host 上有非管理員能加入 kvm 群組(例如透過某些自動化腳本或不小心 chmod),本地帳號就能不透過 VM 直接觸發同一條路徑,等於把 guest-to-host 降級成 local-to-root。至少檢查一次 group 成員清單,確定裡頭只有真正需要跑 VM 的服務帳號。

冷路徑最容易養出老 bug

Zapscape 是很典型的漏洞形態:功能上「大部分時間沒人用到」的路徑,因為模糊測試、code review、實戰壓力都比熱路徑少,反而更容易累積年份夠深的 bug。同一週公開的 SCTPhantom(CVE-2026-64564)走的是一樣邏輯,SCTP 這個協定在 Linux 上長期是「有支援、幾乎沒人用」的狀態,藏了 18 年才被翻出來。

對開放 nested 的雲環境或 VPS 服務商而言,這意味著一件不太舒服的事實:只要開放 nested,就等於要把 shadow MMU 這整塊當熱路徑對待,每個新版本都要跟。這比一般認知的「打補丁」再多一層負擔,因為漏洞不會排隊出來,也不會挑你有空的時候才出現。過去十年 shadow MMU 在多數環境被視為 legacy code,維護節奏鬆散;當這塊 code 因為 nested 又活起來,開發者跟審查密度並沒有跟著提升,Zapscape 應該不會是這條路徑爆出來的最後一支 bug。

巢狀虛擬化本身是有價值的能力,CI 系統跑 KVM in KVM、開發者在雲環境測試自己的 hypervisor,這些用途都需要它。禁掉 nested 不是唯一解,但把它的成本攤開來看,答案很清楚——這是需要顯性資源保護的能力,不是應該預設全域開啟。

NCSE Network 在臺灣是方電訊機房營運搭載 Intel Xeon Gold 處理器與 NVMe SSD 的 VPS 主機,預設不對外開放 nested 虛擬化,對已知 KVM/x86 kernel 漏洞維持較嚴的補丁節奏,有 nested 需求的客戶可於諮詢時提出並安排到獨立環境。相關方案與 SLA 細節可以在 ncse.tw 查看。

需要穩定的雲端主機?

NCSE Network 提供企業級 VPS,7 天免費試用,臺灣是方電訊機房,99% SLA 保證。

查看 VPS 方案 →