Skip to content
KitploitKITPLOIT
StrumentiBlog
Invia
StrumentiBlog
Invia

Strumenti di Hacking, PenTest e Cybersecurity per il tuo Arsenale di Sicurezza!

Kitploit è una directory di strumenti di hacking, cybersecurity e pentesting. Scopri gli ultimi aggiornamenti dei progetti per trovare vulnerabilità, analizzare sistemi, automatizzare i test e rafforzare la tua sicurezza.

··Feed·Contatto·Privacy·© 2026 Kitploit

Directory degli strumenti

Categorie

Vedi tutte le categorie
Loading categories
Strumenti/GitHubGitHub/bluedragonsecurity/cve-2026-31429-poc
Analisi delle VulnerabilitàExploitApprendimento e FormazioneBinary Exploitation
GitHubbluedragonsecurity/cve-2026-31429-poc

CVE-2026-31429-POC

POC per CVE-2026-31429 (Linux Kernel >= 6.3 < 6.12.82 Slab Cross-Cache Confusion) - vulnerabilità scoperta da Antonius - w1sdom - bluedragonsec.com

Vedi Repository
14 mesi faNon ancora revisionato

Più Popolari

Vedi tutti →

Scopri gli strumenti più utilizzati dalla nostra community.

Esplora tutti gli strumenti

Sfoglia la nostra collezione di strumenti

Vedi tutti gli strumenti →
Condividi

CVE-2026-31429 — Linux Kernel: Cross-Cache Free di SKB Head allocato da KFENCE tramite bpf_prog_test_run_skb

Gravità: Media (CWE-763: Rilascio di puntatore o riferimento non valido)
Pubblicato: 2026-04-20
Sottosistema interessato: net/core/skbuff.c — skb_kfree_head()
Ricercatore: Antonius / w1sdom — Blue Dragon Security
Contatto: [email protected]
Thread Lore: https://lore.kernel.org/netdev/CAK8a0jxC5L5N7hq-DT2_NhUyjBxrPocoiDazzsBk4TGgT1r4-A@mail.gmail.com/


Possibili Impatti sulla Sicurezza

  • bypass delle mitigazioni
  • disabilitazione di LSM
  • installazione di rootkit nel kernel
  • fuga dal container
  • denial of service

Panoramica

Questo repository contiene la proof-of-concept per CVE-2026-31429 (non un exploit funzionante, solo una POC), un bug di confusione cross-cache nello slab dello stack di rete del kernel Linux. Il bug viene attivato quando KFENCE è abilitato e un chiamante (in particolare bpf_test_init in net/bpf/test_run.c) alloca un buffer head SKB tramite kzalloc() con una dimensione che coincide con SKB_SMALL_HEAD_CACHE_SIZE. A causa della semantica di reporting della dimensione esatta di KFENCE, la funzione skb_kfree_head() del kernel libera erroneamente l'oggetto nella cache skb_small_head_cache invece della cache originale kmalloc-1k, corrompendo i metadati dello slab.


Versioni Interessate

StatoIntervallo
InteressateLinux >= 6.3 (introdotto da bf9f1baa279f)
Non interessate< 6.3
Corrette>= 6.12.82
Corrette>= 6.18.23
Corrette>= 6.19.13
Corrette>= 7.0 (mainline, commit 0f42e3f4fe2a)

La vulnerabilità è stata introdotta dal commit bf9f1baa279f ("net: add dedicated kmem_cache for typical/small skb->head"), che ha aggiunto skb_small_head_cache e la logica di liberazione condizionale in skb_kfree_head().


Analisi della Causa Radice

Contesto: Intento di Progettazione di skb_small_head_cache

SKB_SMALL_HEAD_CACHE_SIZE è impostato intenzionalmente a un valore non potenza di 2 (es. 704 byte su x86_64) per evitare collisioni con le dimensioni generiche dei bucket kmalloc (sempre potenze di 2: 512, 1024, ...). L'euristica in skb_kfree_head() sfrutta questa unicità per instradare le liberazioni usando solo skb_end_offset:

root@kitploit:~
// net/core/skbuff.c (VULNERABILE — pre-fix)
static void skb_kfree_head(void *head, unsigned int end_offset)
{
    if (end_offset == SKB_SMALL_HEAD_HEADROOM)
        kmem_cache_free(net_hotdata.skb_small_head_cache, head);
    else
        kfree(head);
}
  • end_offset == SKB_SMALL_HEAD_HEADROOM → si presume proveniente da skb_small_head_cache → kmem_cache_free()
  • altrimenti → kfree() generico

Questa euristica è valida solo con la normale semantica dello slab, dove ksize() restituisce la dimensione del bucket (1024 per una richiesta di 704 byte), che non è mai uguale a SKB_SMALL_HEAD_CACHE_SIZE.

L'Eccezione KFENCE

KFENCE (Kernel Electric-Fence) intercetta un sottoinsieme delle allocazioni del kernel e le serve da memoria con pagine guardia. La sua differenza comportamentale critica: kfence_ksize() restituisce la dimensione esatta richiesta, non la dimensione del bucket dello slab.

Catena di Chiamate Vulnerabile

root@kitploit:~
BPF_PROG_TEST_RUN  (syscall 321, cmd BPF_PROG_TEST_RUN=10)
  └─> __sys_bpf()
        └─> bpf_prog_test_run_skb()
              └─> bpf_test_init()
                    └─> kzalloc(size, GFP_USER)
                    │       size == SKB_SMALL_HEAD_CACHE_SIZE (704 su x86_64)
                    │       KFENCE intercetta → oggetto servito dalla regione kmalloc-1k
                    │
                    └─> slab_build_skb(data, NULL, size)
                          └─> ksize(data)
                                └─> kfence_ksize()   ← restituisce 704 (esatto!)
                          └─> skb_end_offset
                                = ksize(data) - sizeof(skb_shared_info)
                                = 704 - 320
                                = 384
                                = SKB_SMALL_HEAD_HEADROOM  ← falso positivo!

  [Nel percorso di liberazione SKB:]
  └─> sk_skb_reason_drop()
        └─> skb_release_data()
              └─> skb_free_head()
                    └─> skb_kfree_head(head, skb->end)
                          └─> (end_offset == SKB_SMALL_HEAD_HEADROOM) == TRUE
                                └─> kmem_cache_free(skb_small_head_cache, head)
                                      ↑ BUG: head proviene da kmalloc-1k, non da skb_small_head_cache!
                                      → warn_free_bad_obj() → corruzione SLUB

Perché skb_end_offset = 384?

Su x86_64:

root@kitploit:~
SKB_SMALL_HEAD_CACHE_SIZE  = 704 byte
sizeof(skb_shared_info)    = 320 byte
SKB_SMALL_HEAD_HEADROOM    = 704 - 320 = 384

Quando KFENCE intercetta la kzalloc() da 704 byte, kfence_ksize() restituisce esattamente 704. L'aritmetica produce skb_end_offset = 384 = SKB_SMALL_HEAD_HEADROOM, soddisfacendo la condizione in skb_kfree_head() — attivando il percorso di liberazione errato.

La Correzione

La correzione a monte di Jiayuan Chen (revisionata da Eric Dumazet, integrata da Jakub Kicinski) elimina completamente l'euristica:

root@kitploit:~
// net/core/skbuff.c (CORRETTO)
static void skb_kfree_head(void *head, unsigned int end_offset)
{
    kfree(head);   // sempre generico; funziona per entrambi i casi
}

kfree() è sicuro sia per la memoria allocata tramite kmalloc sia per quella allocata tramite skb_small_head_cache perché kmem_cache_free() su skb_small_head_cache non è più necessario — il kfree() generico risolve internamente la cache corretta tramite il puntatore kmem_cache della pagina dello slab.


Output dmesg (Prova di Riproduzione)

Il riproduttore (repro_bpf.c) è stato eseguito su Linux 7.0.0-rc5 in un ambiente QEMU (i440FX, BIOS 1.17.0-debian). È stata osservata la seguente cascata di WARNING del kernel:

root@kitploit:~
[ 3065.322973] ------------[ cut here ]------------
[ 3065.322990] kmem_cache_free(skbuff_small_head, ffff888186d6e000): object belongs to different cache kmalloc-1k
[ 3065.323005] WARNING: mm/slub.c:6258 at warn_free_bad_obj+0x91/0xc0, CPU#0: repro_bpf/2167
[ 3065.323061] CPU: 0 UID: 0 PID: 2167 Comm: repro_bpf Not tainted 7.0.0-rc5 #1 PREEMPT(lazy)
[ 3065.323098] RIP: 0010:warn_free_bad_obj+0x98/0xc0
...
[ 3065.323231] Call Trace:
[ 3065.323247]  skb_free_head+0x1ec/0x290
[ 3065.323267]  skb_release_data+0x7a6/0x9d0
[ 3065.323308]  bpf_prog_test_run_skb+0x14f8/0x3410
[ 3065.323510]  __sys_bpf+0x769/0x4b60
[ 3065.323763]  __x64_sys_bpf+0x78/0xc0
[ 3065.323794]  do_syscall_64+0x111/0x690
[ 3065.323813]  entry_SYSCALL_64_after_hwframe+0x77/0x7f

La cascata di WARNING produce 4 splat separati per attivazione:

  1. warn_free_bad_obj — rilevamento primario del cross-cache free (mm/slub.c:6258)
  2. depot_fetch_stack — indice del pool dello stack depot fuori dai limiti (lib/stackdepot.c:506) sul tracciamento Allocated
  3. stack_depot_print — handle corrotto rilevato (lib/stackdepot.c:780)
  4. depot_fetch_stack + stack_depot_print — stessa coppia ripetuta per il tracciamento Freed

Questa cascata indica che i metadati di tracciamento SLUB dell'oggetto (alloc_track / free_track) fanno riferimento a un handle dello stack depot che viene corrotto dopo la liberazione nella cache errata.


Riproduttore

Prerequisiti

root@kitploit:~
Kernel:  Linux >= 6.3, compilato con:
           CONFIG_KFENCE=y
           CONFIG_BPF_SYSCALL=y
           CONFIG_NET_SCH_INGRESS=y  (o qualsiasi driver compatibile con SCHED_CLS)
           CONFIG_SLUB_DEBUG=y       (per la visibilità di warn_free_bad_obj)
           CONFIG_STACKDEPOT=y       (per la cascata completa)

Privilegi: root (uid=0) — richiesti per BPF_PROG_LOAD

Compilazione

root@kitploit:~
gcc -O2 -o cve-2026-31429-poc-only cve-2026-31429-poc-only.c

Esecuzione

root@kitploit:~
sudo ./cve-2026-31429-poc-only
root@kitploit:~
dmesg | grep -E "warn_free_bad_obj|Wrong slab cache|cross-cache"

Meccanismo di Attivazione

La PoC carica un programma BPF minimale di 3 istruzioni (tipo BPF_PROG_TYPE_SCHED_CLS):

root@kitploit:~
ld_imm64 r0, 0    ; 2 insn (wide)
exit              ; 1 insn

Successivamente chiama BPF_PROG_TEST_RUN (cmd=10) con:

  • data_size_in = 284 byte di dati di pacchetto derivati da Syzkaller
  • flags = BPF_F_TEST_RUN_ON_CPU (0x4) — blocca l'esecuzione sulla CPU 0
  • repeat = 4
  • Seguito da un ciclo di 50 chiamate aggiuntive per affidabilità

I 284 byte di dati di input esercitano il percorso di allocazione di bpf_test_init in modo che la dimensione del buffer richiesto sia uguale a SKB_SMALL_HEAD_CACHE_SIZE, colpendo probabilisticamente la finestra di intercettazione di KFENCE.


Commit di Correzione

CommitTreeIntegrato daData
0f42e3f4fe2amainlineJakub Kicinski2026-04-06
60313768a8edlinux-stableGreg Kroah-Hartman2026-04-18
2d64618ea846linux-stableGreg Kroah-Hartman2026-04-18
474e00b935dblinux-stableGreg Kroah-Hartman2026-04-18

Catena Signed-off: Jiayuan Chen → Reviewed-by Eric Dumazet (Google) → Jakub Kicinski → Greg Kroah-Hartman
Credito Reported-by: Antonius <[email protected]> in tutti e 4 i commit
Introdotto da: bf9f1baa279f ("net: add dedicated kmem_cache for typical/small skb->head")


Riferimenti

  • Voce NVD / CVE: https://www.cve.org/CVERecord?id=CVE-2026-31429
  • Patch a monte (mainline): https://git.kernel.org/stable/c/0f42e3f4fe2a58394e37241d02d9ca6ab7b7d516
  • Stable 6.12.x: https://git.kernel.org/stable/c/60313768a8edc7094435975587c00c2d7b834083
  • Stable 6.18.x: https://git.kernel.org/stable/c/2d64618ea846d8d033477311f805ca487d6a6696
  • Stable 6.19.x: https://git.kernel.org/stable/c/474e00b935db250cac320d10c1d3cf4e44b46721
  • Report Lore: https://lore.kernel.org/netdev/CAK8a0jxC5L5N7hq-DT2_NhUyjBxrPocoiDazzsBk4TGgT1r4-A@mail.gmail.com/
  • Blue Dragon Security: https://bluedragonsec.com

Contenuto del Repository

root@kitploit:~
.
├── README.md         		    — questo file
├── cve-2026-31429-poc-only.c       — solo proof-of-concept (non un exploit)
└── dmesg.txt                       — splat grezzo del kernel da riproduzione riuscita

Cronologia della Divulgazione

DataEvento
~Inizio 2026Bug scoperto tramite fuzzing Syzkaller su Linux 7.0-rc5
2026-04-03Patch scritta da Jiayuan Chen, credito Reported-by ad Antonius
2026-04-06Commit mainline 0f42e3f4fe2a integrato da Jakub Kicinski
2026-04-18Backport stable integrati da Greg Kroah-Hartman (6.12.x, 6.18.x, 6.19.x)
2026-04-20Pubblicazione di CVE-2026-31429

Autore

Antonius (soprannome: w1sdom)
Fondatore e Ricercatore Senior — Blue Dragon Security
Indonesia
[email protected]


Note Legali

Questa PoC è rilasciata per scopi educativi e di ricerca dopo che la patch a monte era disponibile. Non utilizzarla su sistemi di cui non si è proprietari o per i quali non si ha esplicita autorizzazione al test. L'autore non si assume alcuna responsabilità per un uso improprio.

Scarica lo strumento