Skip to content
KitploitKITPLOIT
HerramientasBlog
Enviar
HerramientasBlog
Enviar

¡Herramientas de Hacking, PenTest y Ciberseguridad para tu Arsenal de Seguridad!

Kitploit es un directorio de herramientas de hacking, ciberseguridad y pentesting. Descubre las últimas actualizaciones de proyectos para encontrar vulnerabilidades, analizar sistemas, automatizar pruebas y fortalecer tu seguridad.

··Feeds·Contacto·Privacidad·© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
CVE-2026-31429-POC — POC para CVE-2026-31429 (Linux Kernel >= 6.3 < 6.12.82 Confusión Cross-Cache de Slab) - vulnerabilidad descubierta por Antonius - w1sdom - bluedragonsec.com | Kitploit
Herramientas/GitHubGitHub/bluedragonsecurity/cve-2026-31429-poc
Análisis de VulnerabilidadesExplotaciónAprendizaje y EducaciónExplotación de Binarios
GitHubbluedragonsecurity/cve-2026-31429-poc

CVE-2026-31429-POC

POC para CVE-2026-31429 (Linux Kernel >= 6.3 < 6.12.82 Confusión Cross-Cache de Slab) - vulnerabilidad descubierta por Antonius - w1sdom - bluedragonsec.com

Ver Repositorio
1hace 4 mesesAún no revisado

Más Populares

Ver todos →

Descubre las herramientas más usadas por nuestra comunidad.

Explora todas las herramientas

Explora nuestra colección de herramientas

Ver todas las herramientas →
Compartir

CVE-2026-31429 — Linux Kernel: Liberación Cross-Cache de Cabeza SKB Asignada por KFENCE mediante bpf_prog_test_run_skb

Gravedad: Media (CWE-763: Liberación de Puntero o Referencia Inválida)
Publicado: 2026-04-20
Subsistema afectado: net/core/skbuff.c — skb_kfree_head()
Investigador: Antonius / w1sdom — Blue Dragon Security
Contacto: [email protected]
Hilo de lore: https://lore.kernel.org/netdev/CAK8a0jxC5L5N7hq-DT2_NhUyjBxrPocoiDazzsBk4TGgT1r4-A@mail.gmail.com/


Posibles Impactos de Seguridad

  • evasión de mitigaciones
  • desactivación de LSM
  • implantación de rootkits en el kernel
  • escape de contenedores
  • denegación de servicio

Resumen

Este repositorio contiene la prueba de concepto para CVE-2026-31429 (no es un exploit funcional, solo un POC), un error de confusión cross-cache de slabs en la pila de red del kernel Linux. El error se desencadena cuando KFENCE está habilitado y un llamador (específicamente bpf_test_init en net/bpf/test_run.c) asigna un búfer de cabeza SKB mediante kzalloc() con un tamaño que coincide con SKB_SMALL_HEAD_CACHE_SIZE. Debido a la semántica de reporte de tamaño exacto de KFENCE, la función skb_kfree_head() del kernel libera incorrectamente el objeto de vuelta a skb_small_head_cache en lugar de la caché original kmalloc-1k, corrompiendo los metadatos del slab.


Versiones Afectadas

EstadoRango
AfectadoLinux >= 6.3 (introducido por bf9f1baa279f)
No afectado< 6.3
Corregido>= 6.12.82
Corregido>= 6.18.23
Corregido>= 6.19.13
Corregido>= 7.0 (mainline, commit 0f42e3f4fe2a)

La vulnerabilidad fue introducida por el commit bf9f1baa279f ("net: add dedicated kmem_cache for typical/small skb->head"), que añadió skb_small_head_cache y la lógica de liberación condicional en skb_kfree_head().


Análisis de Causa Raíz

Antecedentes: Intención de Diseño de skb_small_head_cache

SKB_SMALL_HEAD_CACHE_SIZE se establece intencionalmente a un valor que no es potencia de 2 (p. ej. 704 bytes en x86_64) para evitar colisiones con los tamaños genéricos de buckets de kmalloc (siempre potencias de 2: 512, 1024, ...). La heurística en skb_kfree_head() explota esta unicidad para enrutar las liberaciones usando solo skb_end_offset:

root@kitploit:~
// net/core/skbuff.c (VULNERABLE — 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 → se asume de skb_small_head_cache → kmem_cache_free()
  • de lo contrario → kfree() genérico

Esta heurística es válida solo bajo semántica normal de slabs, donde ksize() devuelve el tamaño del bucket (1024 para una solicitud de 704 bytes), que nunca es igual a SKB_SMALL_HEAD_CACHE_SIZE.

La Excepción de KFENCE

KFENCE (Kernel Electric-Fence) intercepta un subconjunto de asignaciones del kernel y las sirve desde memoria con páginas de guarda. Su diferencia de comportamiento crítica: kfence_ksize() devuelve el tamaño solicitado exacto, no el tamaño del bucket del slab.

Cadena de Llamadas Vulnerable

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 en x86_64)
                    │       KFENCE intercepta → objeto servido desde la región kmalloc-1k
                    │
                    └─> slab_build_skb(data, NULL, size)
                          └─> ksize(data)
                                └─> kfence_ksize()   ← devuelve 704 (¡exacto!)
                          └─> skb_end_offset
                                = ksize(data) - sizeof(skb_shared_info)
                                = 704 - 320
                                = 384
                                = SKB_SMALL_HEAD_HEADROOM  ← ¡coincidencia falsa!

  [En la ruta de liberación de 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)
                                      ↑ ERROR: head proviene de kmalloc-1k, ¡no de skb_small_head_cache!
                                      → warn_free_bad_obj() → corrupción de SLUB

¿Por qué skb_end_offset = 384?

En x86_64:

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

Cuando KFENCE intercepta el kzalloc() de 704 bytes, kfence_ksize() devuelve exactamente 704. La aritmética produce skb_end_offset = 384 = SKB_SMALL_HEAD_HEADROOM, satisfaciendo la condición en skb_kfree_head() — desencadenando la ruta de liberación incorrecta.

La Corrección

La corrección upstream de Jiayuan Chen (revisada por Eric Dumazet, fusionada por Jakub Kicinski) elimina la heurística por completo:

root@kitploit:~
// net/core/skbuff.c (CORREGIDO)
static void skb_kfree_head(void *head, unsigned int end_offset)
{
    kfree(head);   // siempre genérico; funciona para ambos casos
}

kfree() es seguro tanto para memoria asignada por kmalloc como para memoria asignada por skb_small_head_cache porque kmem_cache_free() en skb_small_head_cache ya no es necesario — el kfree() genérico resuelve la caché correcta internamente mediante el puntero kmem_cache de la página del slab.


Salida de dmesg (Evidencia de Reproducción)

El reproductor (repro_bpf.c) se ejecutó en Linux 7.0.0-rc5 en un entorno QEMU (i440FX, BIOS 1.17.0-debian). Se observó la siguiente cascada de 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 cascada de WARNING produce 4 splats separados por activación:

  1. warn_free_bad_obj — detección primaria de liberación cross-cache (mm/slub.c:6258)
  2. depot_fetch_stack — índice de pool del stack depot fuera de límites (lib/stackdepot.c:506) en el seguimiento Allocated
  3. stack_depot_print — handle corrupto detectado (lib/stackdepot.c:780)
  4. depot_fetch_stack + stack_depot_print — mismo par repetido para el seguimiento Freed

Esta cascada indica que los metadatos de seguimiento SLUB del objeto (alloc_track / free_track) referencian un handle del stack depot que se corrompe después de la liberación en la caché incorrecta.


Reproductor

Requisitos Previos

root@kitploit:~
Kernel:  Linux >= 6.3, compilado con:
           CONFIG_KFENCE=y
           CONFIG_BPF_SYSCALL=y
           CONFIG_NET_SCH_INGRESS=y  (o cualquier driver compatible con SCHED_CLS)
           CONFIG_SLUB_DEBUG=y       (para visibilidad de warn_free_bad_obj)
           CONFIG_STACKDEPOT=y       (para la cascada completa)

Privilegios: root (uid=0) — requerido para BPF_PROG_LOAD

Compilación

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

Ejecución

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

Mecanismo de Activación

El PoC carga un programa BPF mínimo de 3 instrucciones (tipo BPF_PROG_TYPE_SCHED_CLS):

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

Luego llama a BPF_PROG_TEST_RUN (cmd=10) con:

  • data_size_in = 284 bytes de datos de paquete derivados de Syzkaller
  • flags = BPF_F_TEST_RUN_ON_CPU (0x4) — fija la ejecución a la CPU 0
  • repeat = 4
  • Seguido de un bucle de 50 llamadas adicionales para mayor fiabilidad

Los 284 bytes de datos de entrada ejercitan la ruta de asignación de bpf_test_init de modo que el tamaño del búfer solicitado sea igual a SKB_SMALL_HEAD_CACHE_SIZE, alcanzando probabilísticamente la ventana de intercepción de KFENCE.


Commits de Corrección

CommitÁrbolFusionado porFecha
0f42e3f4fe2amainlineJakub Kicinski2026-04-06
60313768a8edlinux-stableGreg Kroah-Hartman2026-04-18
2d64618ea846linux-stableGreg Kroah-Hartman2026-04-18
474e00b935dblinux-stableGreg Kroah-Hartman2026-04-18

Cadena de firmas: Jiayuan Chen → Reviewed-by Eric Dumazet (Google) → Jakub Kicinski → Greg Kroah-Hartman
Crédito Reported-by: Antonius <[email protected]> en los 4 commits
Introducido por: bf9f1baa279f ("net: add dedicated kmem_cache for typical/small skb->head")


Referencias

  • Entrada NVD / CVE: https://www.cve.org/CVERecord?id=CVE-2026-31429
  • Parche upstream (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
  • Informe de Lore: https://lore.kernel.org/netdev/CAK8a0jxC5L5N7hq-DT2_NhUyjBxrPocoiDazzsBk4TGgT1r4-A@mail.gmail.com/
  • Blue Dragon Security: https://bluedragonsec.com

Contenido del Repositorio

root@kitploit:~
.
├── README.md         		    — este archivo
├── cve-2026-31429-poc-only.c       — solo prueba de concepto (no es un exploit)
└── dmesg.txt                       — splat crudo del kernel de la reproducción exitosa

Cronología de Divulgación

FechaEvento
~Principios de 2026Error descubierto mediante fuzzing con Syzkaller en Linux 7.0-rc5
2026-04-03Parche redactado por Jiayuan Chen, crédito Reported-by a Antonius
2026-04-06Commit mainline 0f42e3f4fe2a fusionado por Jakub Kicinski
2026-04-18Backports estables fusionados por Greg Kroah-Hartman (6.12.x, 6.18.x, 6.19.x)
2026-04-20CVE-2026-31429 publicado

Autor

Antonius (apodo: w1sdom)
Fundador e Investigador Senior — Blue Dragon Security
Indonesia
[email protected]


Legal

Este PoC se publica con fines educativos y de investigación después de que el parche upstream estuviera disponible. No lo utilice en sistemas que no le pertenezcan o para los que no tenga permiso explícito de prueba. El autor no se hace responsable del mal uso.

Descargar herramienta