
Dépôt de recherche pour CVE-2025-38502, une vulnérabilité de type accès hors limites dans le stockage local du cgroup BPF du noyau Linux via des tail calls permettant une élévation de privilèges locale.

Abraxas Labs · abraxaslabs.tech · github.com/abraxas · @abraxas_null
Accès hors limites au stockage local de cgroup BPF du noyau Linux via des tail calls
| CVE | CVE-2025-38502 |
| CWE | CWE-125 — Lecture hors limites |
| Éditeur | Noyau Linux |
| Composant | kernel/bpf/core.c, include/linux/bpf.h (stockage local de cgroup + tail calls) |
| Impact | Corruption de mémoire du noyau locale ; l'élévation de privilèges est dans le périmètre sur les noyaux non corrigés |
| Vecteur d'attaque | Local (AV:L) |
| Privilèges | Faibles (PR:L) — un processus capable de charger des programmes BPF de type CGROUP_SKB (ou des programmes équivalents attachés à un cgroup) |
| Interaction utilisateur | Aucune |
| CVSS 3.1 (kernel.org CNA) | 7.8 ÉLEVÉ — 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 ÉLEVÉ — CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:H |
| Public | 16 août 2025 |
| Correctif amont | abad3d0 dans 6.17-rc1 ; rétroporté vers 6.16.1, 6.12.46, 6.6.105, 6.1.151, 5.15.192 |
Usage recherche / éducatif uniquement. N'exécutez, ne déployez et n'utilisez le contenu de ce dépôt contre aucun hôte sans autorisation écrite explicite de la part à la fois de la partie hébergeant ce dépôt et du propriétaire des systèmes cibles. Trouvé dans la nature.
Le nom de fichier source CVE-2025-3850-Linux-LPE-Abaraxas-Labs.c tronque l'identifiant. L'enregistrement publié est CVE-2025-38502. Il n'existe pas de CVE Linux CVE-2025-3850.
Lonial a signalé que le stockage local de cgroup BPF peut être accédé hors limites à travers un tail call.
Le vérificateur eBPF effectue la vérification de type de chaque programme isolément. À l'exécution, bpf_get_local_storage() ne recherche pas la map du programme en cours d'exécution. Il lit le pointeur de stockage de cgroup depuis current->bpf_ctx → bpf_cg_run_ctx → prog_item->cgroup_storage[]. Cet emplacement est rempli à partir du programme initialement attaché, et non du programme vers lequel un tail call a été effectué.
Si le programme A (petite taille de valeur BPF_MAP_TYPE_CGROUP_STORAGE) effectue un tail call vers le programme B (grande taille de valeur), le bpf_get_local_storage() de B renvoie toujours le plus petit tampon de A. Les accès que le vérificateur a autorisés par rapport à la map de B dépassent alors la fin de l'allocation de A.
Le défaut a été introduit dans Linux 5.9 par 7d9c342 (bpf: Make cgroup storages shared between programs on the same cgroup). Il a été corrigé en étendant bpf_map_owner avec un storage_cookie[] afin que les combinaisons de tail calls ne soient acceptées que lorsque le programme appelé utilise les mêmes maps de stockage de cgroup que l'appelant, ou n'en utilise aucune.
Il s'agit d'un accès hors limites au tas du noyau local. Le score de gravité varie selon l'éditeur car ils ne sont pas d'accord sur le fait que la primitive soit un « DoS en lecture seule » ou une corruption mémoire complète :
Ce que cela signifie en pratique :
struct bpf_array pulvérisé dans le même slab/ordre) peuvent être corrompus.map->ops, détournement d'un helper, commit_creds / changement d'espace de noms). C'est pourquoi cette arborescence étiquette le problème comme LPE. Le score plus faible de Red Hat reflète leur évaluation spécifique au produit, et non l'absence du bug.Le bug ne nécessite pas de service exposé au réseau. Il est local. Il ne nécessite pas de TTY, d'helper setuid, ni d'interaction utilisateur.
Deux programmes BPF de cgroup, chacun avec son propre BPF_MAP_TYPE_CGROUP_STORAGE (variante partagée, BPF_CGROUP_STORAGE_SHARED) :
| Programme | Rôle | Taille de valeur du stockage |
|---|---|---|
| A | attaché / appelant du tail call | petite (par ex. tient dans un ordre kmalloc donné) |
| B | cible du tail call | grande (le vérificateur autorise les accès jusqu'à cette taille) |
Le vérificateur vérifie A par rapport à la map de A et B par rapport à la map de B. Les deux passent.
À l'exécution, le helper fait :
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 est l'entrée de tableau du programme qui a démarré l'exécution du cgroup, et non du programme en cours d'exécution après bpf_tail_call. B opère donc sur l'objet de stockage de A.
bpf_cgroup_storage_alloc() dimensionne le tampon sous-jacent à partir du value_size de la map. Le tampon de A est trop petit pour les accès vérifiés de B. Le résultat est une confusion de type de l'identité de la map à travers un transfert de contrôle — la même famille de bugs que les autres problèmes BPF où « le helper voit une map différente de celle vue par le vérificateur ».
Le commit 7d9c342 a rendu les stockages de cgroup partagés entre les programmes attachés au même cgroup. Ce partage est ce qui fait de l'emplacement du contexte d'exécution un pointeur unique plutôt qu'une recherche par programme, et c'est pourquoi les noyaux antérieurs à 5.9 ne sont pas affectés.
BPF_PROG_TEST_RUN sur un programme BPF_PROG_TYPE_CGROUP_SKB alloue un stockage de cgroup pour la durée du test. Cette allocation se trouve sur le tas du noyau à côté de tout ce qui a été récemment libéré dans la même classe de taille — y compris les maps struct bpf_array dont le value_size a été choisi pour atterrir dans le même ordre kmalloc. Un dépassement hors limites depuis le tampon de stockage peut donc atteindre les champs bpf_map (ops, liste RCU, value[]) d'une map de tableau voisine.
Ce détail de disposition du tas est pourquoi un avis de « simple lecture hors limites » et une analyse LPE peuvent décrire le même CVE.
Introduit : Linux 5.9 (7d9c3427894fe70d1347b4820476bf37736d2ff0)
Non affectés : tous les noyaux antérieurs à 5.9
En une ligne :
/* 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 */
Encore ouvert dans certains stables : le tracker de noyau de Debian listait 5.10 upstream-stable / bullseye 5.10 comme needed. Ne présumez pas que chaque 5.10.y est corrigé.
Les numéros ABI des distributions mentent. Ubuntu 5.15.0-163 est un 5.15 corrigé même si 5.15.0 semble plus ancien que l'amont 5.15.192. Comparez le changelog du paquet / USN / DSA / ALAS / RHSA, et non uname -r par rapport au tableau ci-dessus.
Toute distribution ayant livré un noyau dans les plages ci-dessus était dans le périmètre jusqu'à ce qu'elle rétroporte abad3d0 (ou le commit stable correspondant). Il s'agit de code BPF générique, et non d'un correctif spécifique à une distribution.
Ubuntu 26.04 / 25.10 sont listés non affectés (ils ont divergé après le correctif). Ubuntu 25.04 a atteint sa fin de vie encore needed.
Un hôte peut correspondre à une version affectée et rester néanmoins non atteignable. Vérifications utiles :
unprivileged_bpf_disabled=1 n'est pas un correctif complet — un utilisateur disposant de la capacité BPF peut toujours déclencher le bug — mais cela supprime le chemin non privilégié.
Commit amont abad3d0bad72a52137e0c350c59542d75ae4f513 (bpf: Fix oob access in cgroup local storage, Daniel Borkmann).
struct bpf_map_owner gagne un tableau storage_cookie[]. Lors de la mise à jour de la cible d'un tail call, le noyau désormais :
bpf_get_local_storage() — exige que les maps de stockage de cgroup du programme appelé soient exactement celles de l'appelant (mêmes cookies).Des tailles de valeur incompatibles ne peuvent plus être composées dans le dos du vérificateur. Chaque programme est toujours vérifié seul ; la nouvelle vérification porte sur l'arête entre eux.
Ne cherry-pickez pas le commit sur une arborescence arbitraire sans les helpers environnants de propriétaire/cookie BPF. Utilisez le rétroportage stable pour votre série.
uname -r
# Comparez par rapport au tableau ci-dessus, puis par rapport à l'avis de votre distribution —
# les numéros ABI Ubuntu/Debian ne sont pas les numéros stables amont.
grep -E 'CONFIG_BPF_SYSCALL|CONFIG_CGROUP_BPF' \
/boot/config-$(uname -r) /proc/config.gz 2>/dev/null
sysctl kernel.unprivileged_bpf_disabled
# 0 = bpf non privilégié autorisé (exposition la plus large)
# 1 = désactivé après la première utilisation privilégiée, ou entièrement désactivé selon le noyau
# 2 = désactivé (l'administrateur peut le réactiver)
Confirmez le paquet, pas seulement la chaîne de version :
# Debian / Ubuntu
apt changelog linux-image-$(uname -r) 2>/dev/null | grep -i 38502
# Famille RHEL
rpm -q --changelog kernel | grep -i 38502
Un noyau ≥ 6.17, ou un stable listé dans la colonne « première correction », ou un paquet de distribution issu du tableau des avis, constitue la véritable clôture.
abad3d0 / l'équivalent stable. C'est le seul correctif complet.kernel.unprivileged_bpf_disabled=1 (ou 2) pour supprimer les chargeurs non privilégiés.CAP_BPF, CAP_PERFMON et CAP_SYS_ADMIN pour les utilisateurs et conteneurs non fiables.seccomp, LSM, ou en retirant ces capacités dans le runtime).BPF_PROG_TEST_RUN suffit à exercer le chemin d'allocation ; un attaquant local fournit les programmes.CVE-2025-38502/
├── README.md
├── banner.png
├── CVE-2025-3850-Linux-LPE-Abaraxas-Labs.c
└── ebpf_lpe.h
| Fichier | Ce que c'est |
|---|---|
banner.png | Bannière du README (Abraxas Labs / CVE-2025-38502) |
CVE-2025-3850-Linux-LPE-Abaraxas-Labs.c | Source de recherche récupérée dans la nature (le nom de fichier tronque l'identifiant CVE) |
ebpf_lpe.h | Constructeurs d'instructions BPF partagés, helpers de map et macros d'offsets du noyau utilisés par cette source |
Ce répertoire documente la vulnérabilité et contient l'arborescence de recherche correspondante. Ce n'est pas un kit d'exploitation prêt à l'emploi : les symboles de gadgets du noyau (ARRAY_MAP_OPS_OFF, COMMIT_CREDS, …) sont des entrées à la compilation pour un vmlinux spécifique, et exécuter le programme contre un noyau en production sort du périmètre de ce README.
CVE / NVD
Amont
7d9c342 — bpf: Make cgroup storages shared between programs on the same cgroupabad3d0 — bpf: Fix oob access in cgroup local storageRétroportages stables
Distributions
Abraxas Labs — recherche / tests autorisés uniquement
Ce dépôt est destiné à la recherche et à l'éducation.
Ne compilez, n'exécutez, ne déployez et n'utilisez pas autrement le code présent ici contre un système quelconque sans autorisation écrite explicite à la fois de la partie hébergeant ce dépôt et du propriétaire de la cible. L'accès non autorisé à des systèmes informatiques est un crime.
Les auteurs et Abraxas Labs fournissent ce matériel tel quel, sans garantie qu'il soit complet, correct ou sûr à exécuter. La recherche sur l'exploitation du noyau peut provoquer un panic de la machine, corrompre des systèmes de fichiers et entraîner une perte de données. Vous assumez ce risque.
Trouvé dans la nature.
| Source | Score | Intégrité | Notes |
|---|
| kernel.org CNA / cve.org | 7.8 ÉLEVÉ | Élevée | C:H/I:H/A:H — traite le bug comme un impact local complet |
| NVD | 7.1 ÉLEVÉ | Aucune | C:H/I:N/A:H — confidentialité + disponibilité |
| Ubuntu | Moyen (7.1) | — | USN-7909 |
| Red Hat | 4.0 FAIBLE | Aucune | C:N/I:N/A:L — évalué comme disponibilité limitée |
| Amazon Linux | 4.0 Moyen | Aucune | même vecteur que Red Hat |
| SUSE | 6.1 Modéré | Aucune | certains flux SLE 15 marqués WONTFIX |
| Série | Affectée | Première correction |
|---|
| 5.9 – 5.15 | 5.9 jusqu'à 5.15.191 | 5.15.192 (c1c74584…) |
| 5.16 – 6.1 | 5.16 jusqu'à 6.1.150 | 6.1.151 (66da7cee…) |
| 6.2 – 6.6 | 6.2 jusqu'à 6.6.104 | 6.6.105 (7acfa07c…) |
| 6.7 – 6.12 | 6.7 jusqu'à 6.12.45 | 6.12.46 (41688d1f…) |
| 6.13 – 6.16 | 6.13 jusqu'à 6.16.0 | 6.16.1 (19341d5c…) |
| mainline | jusqu'à l'arrivée du correctif | 6.17-rc1 (abad3d0b…) |
| Distribution | Versions / noyaux qui étaient dans la plage |
|---|
| Ubuntu | 22.04 LTS (5.15), 24.04 LTS (6.8), 25.04 (EOL encore 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 ; certains flux SLE 15 WONTFIX |
| Amazon Linux 2023 | noyau par défaut et kernel6.12 |
| Amazon Linux 2 extras | 5.10 extra (aucun correctif prévu) et 5.15 extra |
| Arch, Gentoo, Tumbleweed | noyaux rolling entre 5.9 et le correctif 6.16.1 / 6.17-rc1 |
| Distribution | Paquet corrigé (indicatif) | Avis |
|---|
| Ubuntu 22.04 | linux 5.15.0-163.173 | USN-7909 |
| Ubuntu 24.04 | linux 6.8.0-106.106 | idem |
| Debian 12 | linux 6.1.153-1 | DSA-6009-1 |
| Debian 13 | linux 6.12.48-1 | DSA-6008-1 |
| Debian 11 (rétroportage 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 |
| Condition | Pourquoi c'est important |
|---|
CONFIG_BPF_SYSCALL=y | bpf(2) doit exister |
CONFIG_CGROUP_BPF=y | programmes attachés à un cgroup et stockage local de cgroup |
kernel.unprivileged_bpf_disabled | 0 autorise le chargement de programmes non privilégiés ; 1/2 exigent CAP_BPF / CAP_PERFMON / CAP_SYS_ADMIN |
| Lockdown / LSM / seccomp | peut bloquer BPF_PROG_LOAD ou BPF_PROG_TEST_RUN |
BPF_PROG_TYPE_CGROUP_SKB (ou d'autres types de programmes de cgroup qui portent un stockage local) | le contexte d'exécution qui contient cgroup_storage[] |