Skip to content
KitploitKITPLOIT
OutilsExploitsBlog
Log in
Soumettre
OutilsExploitsBlog
Soumettre

Outils de Hacking, PenTest et Cybersécurité pour votre Arsenal de Sécurité !

Kitploit est un répertoire d'outils de hacking, de cybersécurité et de pentesting. Découvrez les dernières mises à jour des projets pour trouver des vulnérabilités, analyser des systèmes, automatiser les tests et renforcer votre sécurité.

FluxContactConfidentialité© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
CVE-2026-31429-POC — POC pour CVE-2026-31429 (Linux Kernel >= 6.3 < 6.12.82 Slab Cross-Cache Confusion) - vulnérabilité découverte par Antonius - w1sdom - bluedragonsec.com | Kitploit
Outils/GitHubGitHub/bluedragonsecurity/cve-2026-31429-poc
Analyse des VulnérabilitésExploitationApprentissage et ÉducationExploitation de Binaires
GitHubbluedragonsecurity/cve-2026-31429-poc

CVE-2026-31429-POC

POC pour CVE-2026-31429 (Linux Kernel >= 6.3 < 6.12.82 Slab Cross-Cache Confusion) - vulnérabilité découverte par Antonius - w1sdom - bluedragonsec.com

Voir le dépôt
17il y a 5 moisPas encore vérifié

Populaires

Voir tout →

Découvrez les outils les plus utilisés par notre communauté.

Explorer tous les outils

Parcourez notre collection d'outils

Voir tous les outils →
Partager

CVE-2026-31429 — Noyau Linux : Libération cross-cache d'une tête SKB allouée par KFENCE via bpf_prog_test_run_skb

Sévérité : Moyenne (CWE-763 : Libération d'un pointeur ou d'une référence invalide)
Publié : 2026-04-20
Sous-système concerné : net/core/skbuff.c — skb_kfree_head()
Chercheur : Antonius / w1sdom — Blue Dragon Security
Contact : [email protected]
Fil de discussion Lore : https://lore.kernel.org/netdev/CAK8a0jxC5L5N7hq-DT2_NhUyjBxrPocoiDazzsBk4TGgT1r4-A@mail.gmail.com/


Impacts de sécurité possibles

  • contournement d'atténuation
  • désactivation du LSM
  • implantation de rootkits dans le noyau
  • évasion de conteneur
  • déni de service

Vue d'ensemble

Ce dépôt contient la preuve de concept pour CVE-2026-31429 (pas un exploit fonctionnel, juste un POC), un bug de confusion cross-cache de slab dans la pile réseau du noyau Linux. Le bug est déclenché lorsque KFENCE est activé et qu'un appelant (plus précisément bpf_test_init dans net/bpf/test_run.c) alloue un tampon d'en-tête SKB via kzalloc() avec une taille qui se trouve être égale à SKB_SMALL_HEAD_CACHE_SIZE. En raison de la sémantique de rapport de taille exacte de KFENCE, la fonction skb_kfree_head() du noyau libère incorrectement l'objet vers skb_small_head_cache au lieu du cache kmalloc-1k d'origine, corrompant les métadonnées du slab.


Versions concernées

StatutPlage
ConcernéLinux >= 6.3 (introduit par bf9f1baa279f)
Non concerné< 6.3
Corrigé>= 6.12.82
Corrigé>= 6.18.23
Corrigé>= 6.19.13
Corrigé>= 7.0 (mainline, commit 0f42e3f4fe2a)

La vulnérabilité a été introduite par le commit bf9f1baa279f (« net: add dedicated kmem_cache for typical/small skb->head »), qui a ajouté skb_small_head_cache et la logique de libération conditionnelle dans skb_kfree_head().


Analyse de la cause racine

Contexte : intention de conception de skb_small_head_cache

SKB_SMALL_HEAD_CACHE_SIZE est intentionnellement défini sur une valeur non puissance de 2 (par ex. 704 octets sur x86_64) pour éviter les collisions avec les tailles génériques des buckets kmalloc (toujours des puissances de 2 : 512, 1024, ...). L'heuristique dans skb_kfree_head() exploite cette unicité pour acheminer les libérations en utilisant uniquement skb_end_offset :

// net/core/skbuff.c (VULNÉRABLE — avant correctif)
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 → supposé provenir de skb_small_head_cache → kmem_cache_free()
  • sinon → kfree() générique

Cette heuristique n'est valable que sous une sémantique de slab normale, où ksize() renvoie la taille du bucket (1024 pour une requête de 704 octets), qui n'est jamais égale à SKB_SMALL_HEAD_CACHE_SIZE.

L'exception KFENCE

KFENCE (Kernel Electric-Fence) intercepte un sous-ensemble des allocations du noyau et les sert depuis une mémoire à pages gardées. Sa différence comportementale critique : kfence_ksize() renvoie la taille exacte demandée, et non la taille du bucket de slab.

Chaîne d'appel vulnérable

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 sur x86_64)
                    │       KFENCE intercepte → objet servi depuis la région kmalloc-1k
                    │
                    └─> slab_build_skb(data, NULL, size)
                          └─> ksize(data)
                                └─> kfence_ksize()   ← renvoie 704 (exact !)
                          └─> skb_end_offset
                                = ksize(data) - sizeof(skb_shared_info)
                                = 704 - 320
                                = 384
                                = SKB_SMALL_HEAD_HEADROOM  ← fausse correspondance !

  [Sur le chemin de libération 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 provient de kmalloc-1k, pas de skb_small_head_cache !
                                      → warn_free_bad_obj() → corruption SLUB

Pourquoi skb_end_offset = 384 ?

Sur x86_64 :

SKB_SMALL_HEAD_CACHE_SIZE  = 704 octets
sizeof(skb_shared_info)    = 320 octets
SKB_SMALL_HEAD_HEADROOM    = 704 - 320 = 384

Lorsque KFENCE intercepte le kzalloc() de 704 octets, kfence_ksize() renvoie exactement 704. L'arithmétique produit skb_end_offset = 384 = SKB_SMALL_HEAD_HEADROOM, satisfaisant la condition dans skb_kfree_head() — déclenchant le mauvais chemin de libération.

Le correctif

Le correctif en amont de Jiayuan Chen (revu par Eric Dumazet, fusionné par Jakub Kicinski) élimine entièrement l'heuristique :

// net/core/skbuff.c (CORRIGÉ)
static void skb_kfree_head(void *head, unsigned int end_offset)
{
    kfree(head);   // toujours générique ; fonctionne pour les deux cas
}

kfree() est sûr à la fois pour la mémoire allouée par kmalloc et par skb_small_head_cache car kmem_cache_free() sur skb_small_head_cache n'est plus nécessaire — le kfree() générique résout le cache correct en interne via le pointeur kmem_cache de la page de slab.


Sortie dmesg (preuve de reproduction)

Le reproducteur (repro_bpf.c) a été exécuté sur Linux 7.0.0-rc5 dans un environnement QEMU (i440FX, BIOS 1.17.0-debian). La cascade d'avertissements du noyau suivante a été observée :

[ 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 cascade d'avertissements produit 4 splats distincts par déclenchement :

  1. warn_free_bad_obj — détection primaire de libération cross-cache (mm/slub.c:6258)
  2. depot_fetch_stack — index du pool du dépôt de piles hors limites (lib/stackdepot.c:506) sur le suivi Allocated
  3. stack_depot_print — handle corrompu détecté (lib/stackdepot.c:780)
  4. depot_fetch_stack + stack_depot_print — même paire répétée pour le suivi Freed

Cette cascade indique que les métadonnées de suivi SLUB de l'objet (alloc_track / free_track) référencent un handle du dépôt de piles qui devient corrompu après la libération dans le mauvais cache.


Reproducteur

Prérequis

Télécharger l’outil