
patch per la vulnerabilità CVE-2026-53359
dump_tool.py è per trovare automaticamente gli offset, per come usarlo guarda il codice.
CVE-2026-53359 (Januscape) è una vulnerabilità use-after-free (UAF) nella MMU ombra KVM del kernel Linux.
La funzione kvm_mmu_get_page() quando cerca nella tabella hash pagine di tabella ombra riutilizzabili confronta solo il gfn (numero di frame della pagina fisica del guest) e non confronta il role (ruolo della tabella/ruolo MMU), causando il riutilizzo errato di una tabella con ruolo non corrispondente, scatenando UAF.
修复前(有漏洞):
┌──────────────────────────────────────┐
│ kvm_mmu_get_page() │
│ 遍历哈希表 │
│ if (child->gfn == gfn) │
│ return child ← 只比较gfn! │
│ 角色不匹配也复用 → UAF! │
│ 分配新页(安全) │
└──────────────────────────────────────┘
Nel commit 81ccda30b4e8 del kernel upstream è stata aggiunta una riga di confronto del role:
// 修复前
if (... && spte_to_child_sp(*sptep)->gfn == gfn)
// 修复后
if (... && spte_to_child_sp(*sptep)->gfn == gfn
&& spte_to_child_sp(*sptep)->role.word == role.word)
Non modifica il codice sorgente del kernel, non sostituisce funzioni, ma modifica direttamente le istruzioni vulnerabili nella memoria del kernel in esecuzione.
二进制层面:
偏移 0x104: 49 39 47 28 cmp %rax, 0x28(%r15) ← 比较 gfn
偏移 0x108: 0f 84 9f 01 00 00 je +0x19f ← 匹配就跳转复用
打补丁后:
偏移 0x108: 66 0f 1f 44 00 00 NOP × 6 ← 什么也不做
修复后:
┌──────────────────────────────────────┐
│ kvm_mmu_get_page() │
│ 遍历哈希表 │
│ if (child->gfn == gfn) │
│ NOP(跳转被抹掉,滑过去) │
│ 分配新页(强制走安全路径) │
│ → 不复用 = 不触发 UAF = 漏洞修复 │
└──────────────────────────────────────┘
kvm_mmu_get_page tramite kallsyms_lookup_nametext_poke tramite kallsyms_lookup_name (API di modifica a caldo del codice kernel)stop_machine per garantire una modifica sicuraje di 6 byte con un NOP di 6 byte usando text_poketext_poke| Soluzione | Problema |
|---|---|
| Aggiornare il kernel e riavviare | Richiede riavvio dell'host, tutte le VM si fermano |
| nested=0 (disabilita virtualizzazione annidata) | Perdita della funzionalità di virtualizzazione annidata, impossibile eseguire VM dentro VM |
| Metodo kpatch | Richiede kernel-debuginfo, compilazione richiede 10-20 minuti, dipendenze complesse |
| Sostituzione di funzione con ftrace | kvm_mmu_get_child_sp è inlined da GCC, nessun punto di ingresso indipendente |
| La mia soluzione text_poke | Compilazione in 10 secondi, un singolo file .c, modifica diretta delle istruzioni vulnerabili |
| Funzionalità | Impatto |
|---|---|
| Riavvio dell'host | Non necessario |
| Riavvio/migrazione VM | Non necessario |
| Virtualizzazione annidata (eseguire VM dentro VM) | Mantenuta, funzionamento normale |
| Creazione/avvio di VM | Normale |
| Unione memoria KSM | Nessun impatto, funzionalità indipendente |
| Prestazioni CPU | Quasi nessun impatto (NOP non consuma CPU) |
| Memoria | Le tabelle ombra non vengono più riutilizzate, ogni volta viene allocata una nuova pagina, occupa un po' più di memoria |
| Rimozione modulo KVM | Normale (rmmod ripristina automaticamente il codice originale) |
| Condizione | Descrizione |
|---|---|
| Versione kernel | Linux 4.18+ (CentOS 8 / RHEL 8 / Rocky 8, ecc.) |
| Ambiente di compilazione | kernel-devel + gcc + make |
| Riavvio host | Non necessario |
| Arresto VM | Non necessario |
| Virtualizzazione annidata | Mantenuta |
# 编译
make
# 加载热补丁
insmod KVM-XJ.ko
# 查看状态
dmesg | grep KVM-XJ
cat /sys/module/kvm_intel/parameters/nested # 应该还是 1
lsmod | grep KVM_XJ
# 卸载(恢复原始代码)
rmmod KVM_XJ
Ottimizzazioni di compilazione diverse tra versioni kernel, anche l'offset dell'istruzione je è diverso. Usa dump_tool.py per l'analisi automatica:
# 1. 从母鸡下载 kvm.ko
scp root@母鸡:/lib/modules/.../kvm.ko.xz .
xz -d kvm.ko.xz
# 2. 运行分析工具
python dump_tool.py kvm.ko
# 3. 工具会输出 patch 偏移,修改 KVM-XJ.c 中的 0x108
| Versione kernel | Offset je | Stato |
|---|---|---|
| 4.18.0-496.el8.x86_64 | 0x108 | Testato |
| 4.18.0-358.el8.x86_64 | 0xe8 | Testato |