
Repositorio de investigación para CVE-2025-38502, un acceso fuera de límites en el almacenamiento local del cgroup BPF del kernel de Linux mediante tail calls que permite la escalada de privilegios local.

Abraxas Labs · abraxaslabs.tech · github.com/abraxas · @abraxas_null
Acceso fuera de límites al almacenamiento local de cgroup de BPF del kernel de Linux mediante tail calls
| CVE | CVE-2025-38502 |
| CWE | CWE-125 — Lectura fuera de límites |
| Fabricante | Linux kernel |
| Componente | kernel/bpf/core.c, include/linux/bpf.h (almacenamiento local de cgroup + tail calls) |
| Impacto | Corrupción de memoria del kernel local; la escalada de privilegios está dentro del alcance en kernels sin parchear |
| Vector de ataque | Local (AV:L) |
| Privilegios | Bajos (PR:L) — un proceso que puede cargar programas BPF de tipo CGROUP_SKB (o programas equivalentes adjuntos a cgroup) |
| Interacción del usuario | Ninguna |
| CVSS 3.1 (kernel.org CNA) | 7.8 ALTO — CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H |
| CVSS 3.1 (NVD) | 7.1 ALTO — CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:H |
| Público | 16 de agosto de 2025 |
| Corrección upstream | abad3d0 en 6.17-rc1; retroportado a 6.16.1, 6.12.46, 6.6.105, 6.1.151, 5.15.192 |
Solo para investigación / uso educativo. No ejecute, despliegue ni utilice el material de este repositorio contra ningún host a menos que tenga permiso escrito explícito tanto de la parte que aloja este repositorio como del propietario de los sistemas objetivo. Encontrado en estado salvaje.
El nombre del archivo fuente CVE-2025-3850-Linux-LPE-Abaraxas-Labs.c trunca el identificador. El registro publicado es CVE-2025-38502. No existe un CVE de Linux CVE-2025-3850.
Lonial informó que el almacenamiento local de BPF de cgroup puede ser accedido fuera de límites a través de una tail call.
El verificador de eBPF comprueba los tipos de cada programa de forma aislada. En tiempo de ejecución, bpf_get_local_storage() no busca el mapa del programa que se está ejecutando actualmente. Lee el puntero del almacenamiento de cgroup desde current->bpf_ctx → bpf_cg_run_ctx → prog_item->cgroup_storage[]. Esa ranura se rellena desde el programa originalmente adjunto, no desde el programa al que se hizo la tail call.
Si el programa A (tamaño de valor pequeño de BPF_MAP_TYPE_CGROUP_STORAGE) hace una tail call al programa B (tamaño de valor grande), el bpf_get_local_storage() de B sigue devolviendo el búfer más pequeño de A. Los accesos que el verificador permitió contra el mapa de B entonces se salen del final de la asignación de A.
El defecto se introdujo en Linux 5.9 mediante 7d9c342 (bpf: Make cgroup storages shared between programs on the same cgroup). Se corrigió extendiendo bpf_map_owner con un storage_cookie[] para que las combinaciones de tail call solo se acepten cuando el destinatario usa los mismos mapas de almacenamiento de cgroup que el llamador, o no usa ninguno.
Este es un acceso fuera de límites al heap del kernel local. La puntuación de severidad varía según el proveedor porque no coinciden en si la primitiva es un "DoS de solo lectura" o una corrupción de memoria completa:
Qué significa esto en la práctica:
struct bpf_array rociado en el mismo slab/orden) pueden corromperse.map->ops, secuestrar un helper, commit_creds / cambio de namespace). Por eso este árbol etiqueta el problema como LPE. La puntuación más baja de Red Hat refleja su evaluación específica del producto, no la ausencia del fallo.El fallo no requiere un servicio expuesto a la red. Es local. No requiere una TTY, un helper setuid ni interacción del usuario.
Dos programas BPF de cgroup, cada uno con su propio BPF_MAP_TYPE_CGROUP_STORAGE (variante compartida, BPF_CGROUP_STORAGE_SHARED):
| Programa | Rol | Tamaño del valor de almacenamiento |
|---|---|---|
| A | adjunto / llamador de tail call | pequeño (p. ej., cabe en un orden de kmalloc dado) |
| B | objetivo de tail call | grande (el verificador permite accesos hasta este tamaño) |
El verificador comprueba A contra el mapa de A y B contra el mapa de B. Ambos pasan.
En tiempo de ejecución el helper hace:
ctx = container_of(current->bpf_ctx, struct bpf_cg_run_ctx, run_ctx);
storage = ctx->prog_item->cgroup_storage[stype];
if (stype == BPF_CGROUP_STORAGE_SHARED)
ptr = &READ_ONCE(storage->buf)->data[0];
else
ptr = this_cpu_ptr(storage->percpu_buf);
prog_item es la entrada del array para el programa que inició la ejecución del cgroup, no el programa que se está ejecutando actualmente tras bpf_tail_call. Por lo tanto, B opera sobre el objeto de almacenamiento de A.
bpf_cgroup_storage_alloc() dimensiona el búfer de respaldo a partir del value_size del mapa. El búfer de A es demasiado pequeño para los accesos verificados de B. El resultado es una clásica confusión de tipos de la identidad del mapa a través de una transferencia de control — la misma familia de fallos que otros problemas de BPF en los que "el helper ve un mapa diferente al que vio el verificador".
El commit 7d9c342 hizo que los almacenamientos de cgroup fueran compartidos entre programas adjuntos al mismo cgroup. Esa compartición es lo que hace que la ranura del contexto de ejecución sea un único puntero en lugar de una búsqueda por programa, y es por lo que los kernels anteriores a 5.9 no se ven afectados.
BPF_PROG_TEST_RUN sobre un programa BPF_PROG_TYPE_CGROUP_SKB asigna almacenamiento de cgroup durante la duración de la prueba. Esa asignación se sitúa en el heap del kernel junto a cualquier otra cosa liberada recientemente en la misma clase de tamaño — incluidos mapas struct bpf_array cuyo value_size se eligió para caer en el mismo orden de kmalloc. Por lo tanto, un OOB desde el búfer de almacenamiento puede alcanzar campos de bpf_map (ops, lista RCU, value[]) de un mapa de array vecino.
Ese detalle del diseño del heap es la razón por la que un aviso de "mera lectura OOB" y un informe de LPE pueden describir el mismo CVE.
Introducido: Linux 5.9 (7d9c3427894fe70d1347b4820476bf37736d2ff0)
No afectados: todos los kernels anteriores a 5.9
En una línea:
/* CVE-2025-38502: affected 5.9–5.15.191, 5.16–6.1.150, 6.2–6.6.104, 6.7–6.12.45, 6.13–6.16.0; fixed in 5.15.192, 6.1.151, 6.6.105, 6.12.46, 6.16.1, 6.17-rc1 */
Todavía abierto en algunos stables: el rastreador de kernels de Debian listaba 5.10 upstream-stable / bullseye 5.10 como needed. No asuma que todos los 5.10.y están parcheados.
Los números de ABI de las distros mienten. Ubuntu 5.15.0-163 es un 5.15 parcheado aunque 5.15.0 parezca más antiguo que el upstream 5.15.192. Compare el changelog del paquete / USN / DSA / ALAS / RHSA, no uname -r contra la tabla anterior.
Cualquier distribución que haya enviado un kernel en los rangos anteriores estaba dentro del alcance hasta que retroportara abad3d0 (o el commit estable correspondiente). Este es código BPF genérico, no un parche específico de una distro.
Ubuntu 26.04 / 25.10 están listados como no afectados (se ramificaron después de la corrección). Ubuntu 25.04 alcanzó EOL todavía needed.
Un host puede coincidir con una versión afectada y aun así no ser alcanzable. Comprobaciones útiles:
unprivileged_bpf_disabled=1 no es una corrección completa — un usuario con capacidad BPF todavía puede alcanzar el fallo — pero elimina la ruta sin privilegios.
Commit upstream abad3d0bad72a52137e0c350c59542d75ae4f513 (bpf: Fix oob access in cgroup local storage, Daniel Borkmann).
struct bpf_map_owner gana un array storage_cookie[]. En la actualización del objetivo de tail call, el kernel ahora:
bpf_get_local_storage() — exige que los mapas de almacenamiento de cgroup del destinatario sean exactamente los mapas del llamador (mismas cookies).Los tamaños de valor que no coinciden ya no pueden componerse a espaldas del verificador. Cada programa sigue verificándose por separado; la nueva comprobación está en el borde entre ellos.
No haga cherry-pick del commit sobre un árbol arbitrario sin los helpers de propietario/cookie de BPF que lo rodean. Use el retroporte estable para su serie.
uname -r
# Compare against the table above, then against your distro advisory —
# Ubuntu/Debian ABI numbers are not upstream stable numbers.
grep -E 'CONFIG_BPF_SYSCALL|CONFIG_CGROUP_BPF' \
/boot/config-$(uname -r) /proc/config.gz 2>/dev/null
sysctl kernel.unprivileged_bpf_disabled
# 0 = unprivileged bpf allowed (widest exposure)
# 1 = disabled after first privileged use, or fully disabled depending on kernel
# 2 = disabled (admin can re-enable)
Confirme el paquete, no solo la cadena de versión:
# Debian / Ubuntu
apt changelog linux-image-$(uname -r) 2>/dev/null | grep -i 38502
# RHEL family
rpm -q --changelog kernel | grep -i 38502
Un kernel ≥ 6.17, o un estable listado en la columna "primera corrección", o un paquete de distro de la tabla de avisos, es el cierre real.
abad3d0 / el equivalente estable. Esta es la única corrección completa.kernel.unprivileged_bpf_disabled=1 (o 2) para eliminar los cargadores sin privilegios.CAP_BPF, CAP_PERFMON y CAP_SYS_ADMIN a usuarios y contenedores no confiables.seccomp, LSM, o eliminando esas capacidades en el runtime).BPF_PROG_TEST_RUN es suficiente para ejercitar la ruta de asignación; un atacante local proporciona los programas.CVE-2025-38502/
├── README.md
├── banner.png
├── CVE-2025-3850-Linux-LPE-Abaraxas-Labs.c
└── ebpf_lpe.h
| Archivo | Qué es |
|---|---|
banner.png | Banner del README (Abraxas Labs / CVE-2025-38502) |
CVE-2025-3850-Linux-LPE-Abaraxas-Labs.c | Código fuente de investigación recuperado en estado salvaje (el nombre del archivo trunca el id del CVE) |
ebpf_lpe.h | Constructores de instrucciones BPF compartidos, helpers de mapas y macros de desplazamiento del kernel usados por ese código fuente |
Este directorio documenta la vulnerabilidad y contiene el árbol de investigación correspondiente. No es un kit de exploit listo para usar: los símbolos de gadgets del kernel (ARRAY_MAP_OPS_OFF, COMMIT_CREDS, …) son entradas en tiempo de compilación para un vmlinux específico, y ejecutar el programa contra un kernel en vivo está fuera del alcance de este README.
CVE / NVD
Upstream
7d9c342 — bpf: Make cgroup storages shared between programs on the same cgroupabad3d0 — bpf: Fix oob access in cgroup local storageRetroportes estables
Distros
Abraxas Labs — solo investigación / pruebas autorizadas
| Sitio web | https://abraxaslabs.tech |
| GitHub | https://github.com/abraxas |
| X | @abraxas_null |
Este repositorio es para investigación y educación.
No compile, ejecute, despliegue ni utilice de otro modo el código aquí contra ningún sistema a menos que tenga autorización escrita explícita tanto de la parte que aloja este repositorio como del propietario del objetivo. El acceso no autorizado a sistemas informáticos es un delito.
Los autores y Abraxas Labs proporcionan este material tal cual, sin garantía de que sea completo, correcto o seguro de ejecutar. La investigación de explotación del kernel puede provocar un pánico de la máquina, corromper sistemas de archivos y perder datos. Usted asume ese riesgo.
Encontrado en estado salvaje.
| Fuente | Puntuación | Integridad | Notas |
|---|
| kernel.org CNA / cve.org | 7.8 ALTO | Alta | C:H/I:H/A:H — trata el fallo como impacto local completo |
| NVD | 7.1 ALTO | Ninguna | C:H/I:N/A:H — confidencialidad + disponibilidad |
| Ubuntu | Medio (7.1) | — | USN-7909 |
| Red Hat | 4.0 BAJO | Ninguna | C:N/I:N/A:L — calificado como disponibilidad limitada |
| Amazon Linux | 4.0 Medio | Ninguna | mismo vector que Red Hat |
| SUSE | 6.1 Moderado | Ninguna | algunos flujos de SLE 15 marcados como WONTFIX |
| Serie | Afectados | Primera corrección |
|---|
| 5.9 – 5.15 | 5.9 hasta 5.15.191 | 5.15.192 (c1c74584…) |
| 5.16 – 6.1 | 5.16 hasta 6.1.150 | 6.1.151 (66da7cee…) |
| 6.2 – 6.6 | 6.2 hasta 6.6.104 | 6.6.105 (7acfa07c…) |
| 6.7 – 6.12 | 6.7 hasta 6.12.45 | 6.12.46 (41688d1f…) |
| 6.13 – 6.16 | 6.13 hasta 6.16.0 | 6.16.1 (19341d5c…) |
| mainline | hasta que llegó la corrección | 6.17-rc1 (abad3d0b…) |
| Distro | Versiones / kernels que estaban en rango |
|---|
| Ubuntu | 22.04 LTS (5.15), 24.04 LTS (6.8), 25.04 (EOL todavía needed). 20.04 HWE 5.15. |
| Debian | 11 bullseye (5.10), 12 bookworm (6.1), 13 trixie (6.12) |
| RHEL 9 / 10, Rocky, Alma, Fedora | RHEL 9 ≈ 5.14; RHEL 10 ≈ 6.12; Fedora rolling 5.9–6.16 |
| SUSE / openSUSE | SLE Micro 5.3/5.4; algunos flujos de SLE 15 WONTFIX |
| Amazon Linux 2023 | kernel predeterminado y kernel6.12 |
| Amazon Linux 2 extras | 5.10 extra (sin corrección planificada) y 5.15 extra |
| Arch, Gentoo, Tumbleweed | kernels rolling entre 5.9 y la corrección 6.16.1 / 6.17-rc1 |
| Distro | Paquete corregido (indicativo) | Aviso |
|---|
| Ubuntu 22.04 | linux 5.15.0-163.173 | USN-7909 |
| Ubuntu 24.04 | linux 6.8.0-106.106 | mismo |
| Debian 12 | linux 6.1.153-1 | DSA-6009-1 |
| Debian 13 | linux 6.12.48-1 | DSA-6008-1 |
| Debian 11 (retroporte 6.1) | linux-6.1 6.1.153-1~deb11u1 | DLA-4328-1 |
| Amazon Linux 2023 | kernel / kernel6.12, 2025-09-29 | ALAS2023-2025-1210 / 1208 |
| Amazon Linux 2 5.15 extra | 2025-09-29 | ALAS2KERNEL-5.15-2025-091 |
| Condición | Por qué importa |
|---|
CONFIG_BPF_SYSCALL=y | bpf(2) debe existir |
CONFIG_CGROUP_BPF=y | programas adjuntos a cgroup y almacenamiento local de cgroup |
kernel.unprivileged_bpf_disabled | 0 permite la carga de programas sin privilegios; 1/2 requieren CAP_BPF / CAP_PERFMON / CAP_SYS_ADMIN |
| Lockdown / LSM / seccomp | pueden bloquear BPF_PROG_LOAD o BPF_PROG_TEST_RUN |
BPF_PROG_TYPE_CGROUP_SKB (u otros tipos de programa de cgroup que llevan almacenamiento local) | el contexto de ejecución que contiene cgroup_storage[] |