
pedit COW
CVE-2026-46331 (surnommé « pedit COW ») est une faille locale d'élévation de privilèges dans le noyau Linux, située dans le sous-système de contrôle de trafic. Un utilisateur non privilégié (dans un espace de noms réseau non privilégié) peut configurer le filtre act_pedit (éditeur de paquets) pour déclencher une écriture partielle par copie sur écriture (COW) dans le cache de pages. En pratique, le noyau écrit des données contrôlées par l'attaquant dans l'image en mémoire d'un fichier sans marquer la page comme privée, corrompant ainsi la copie mise en cache de ce fichier. Point crucial : l'exploitation nécessite uniquement CAP_NET_ADMIN (obtenable dans un espace de noms utilisateur) et ne modifie pas le fichier sur disque. Concrètement, une preuve de concept (PoC) fonctionnelle appelée packet_edit_meme a été publiée le 17 juin 2026, démontrant comment écraser l'image en cache d'un binaire setuid (par exemple /bin/su) pour obtenir un shell root. La vulnérabilité provient d'un calcul incorrect de la plage COW dans tcf_pedit_act() et a été corrigée en amont (4 juin 2026) en déplaçant la vérification de la zone accessible en écriture dans la boucle par clé.
act_pedit. Les versions stables non corrigées (y compris de nombreux noyaux de distributions) sont vulnérables.tc, puis écrase en mémoire le point d'entrée ELF d'un binaire setuid avec du shellcode.skb_ensure_writable() à l'intérieur de la boucle des clés). Comme solution de contournement, bloquer ou décharger le module act_pedit ou désactiver les espaces de noms utilisateur non privilégiés (par exemple sysctl user.max_user_namespaces=0). Après atténuation, vider les caches (echo 3 > /proc/sys/vm/drop_caches) pour expulser les pages empoisonnées.Ce rapport fournit une analyse technique détaillée de CVE-2026-46331 : sa cause, son exploitation, sa détection et les stratégies de correction, avec des références aux avis de l'éditeur, aux CVE et à l'exploit public.
Définition : CVE-2026-46331 est un bogue d'écriture hors limites dans le sous-système Contrôle de trafic (net/sched) du noyau Linux, plus précisément dans l'action act_pedit (éditeur de paquets). La fonction tcf_pedit_act() calcule une plage de « copie sur écriture » pour les opérations d'édition de paquets avant d'itérer sur les clés typées, en utilisant une indication statique tcfp_off_max_hint. Cependant, certaines clés (par exemple les modifications d'en-tête TCP/UDP) ne déterminent leur décalage final qu'à l'exécution. Le code ne revérifie jamais l'accessibilité en écriture pour ces décalages dynamiques. Par conséquent, des écritures peuvent se produire en dehors de la région pré-COW : une partie de l'écriture du paquet n'est jamais rendue privée, ce qui conduit à une COW partielle. Cette écriture erronée se propage dans la mémoire partagée du cache de pages d'un fichier (si les tampons de paquets référencent par hasard des pages de fichier), corrompant l'image du fichier en cache.
Contexte : L'action éditeur de paquets (pedit) de Linux permet aux administrateurs de réécrire des octets arbitraires dans les en-têtes de paquets (couches liaison, réseau ou transport) au fur et à mesure que les paquets traversent un filtre tc configuré. Elle fonctionne en spécifiant un décalage (éventuellement ancré à un en-tête) et une valeur/masque 32 bits. En interne, pedit opère sur les tampons de socket (sk_buff) et doit rendre la mémoire du paquet cible accessible en écriture avant de la modifier (via skb_ensure_writable() de manière COW). Idéalement, le noyau devrait cloner (copie privée) toute page partagée avant d'écrire pour éviter de modifier la mémoire utilisée ailleurs.
Cause racine : Dans tcf_pedit_act(), le code calcule par erreur la plage accessible en écriture une seule fois au début, en utilisant tcfp_off_max_hint (le décalage statique maximal). Cette indication n'inclut aucun décalage d'en-tête d'exécution que les clés typées ajoutent lors du traitement du paquet. Les clés comme TCP ou UDP peuvent calculer un décalage basé sur la position de l'en-tête IP à l'exécution (par exemple, si une clé précédente décale l'en-tête réseau). Ainsi, pendant la boucle par clé, le décalage réel d'une clé peut dépasser la plage pré-allouée comme accessible en écriture. Le code écrit alors dans la mémoire du paquet via skb_store_bits(), mais comme la page au-delà de la région pré-COW n'a pas été rendue privée, l'écriture corrompt une page toujours partagée avec le cache de pages. En bref, « calculer trop tôt la plage accessible en écriture du paquet » entraîne une écriture hors limites entre pages. Les décalages négatifs (par exemple lors de l'édition d'en-têtes Ethernet en entrée) sont également mal gérés, et même offset_valid() manquait d'une protection contre INT_MIN, aggravant la faille.
Pourquoi cela se produit : Ce bogue est essentiellement une erreur de logique dans le calcul de la plage de copie sur écriture. Le noyau supposait que le décalage statique maximal (connu au chargement) était suffisant pour toutes les modifications. Il n'a pas mis à jour la plage COW lorsque des clés avec des décalages dynamiques étaient réellement appliquées. Après une série de modifications en file d'attente, l'écriture finale pouvait se situer en dehors de la région pré-vérifiée. Comme les tampons de paquets peuvent référencer des pages de fichier mappées en mémoire (par exemple via des mécanismes de copie zéro), cette écriture « COW partielle » peut atteindre le cache de pages d'un fichier sur disque. En pratique, l'action de l'éditeur de paquets peut recevoir des pages provenant d'un sendfile ou d'un splice ; ainsi une simple opération de filtre de paquets peut écrire indirectement des données choisies par l'attaquant dans l'image mémoire d'un fichier, sans modifier le disque.
Composants et flux de données : Le code vulnérable réside dans le sous-système net/sched de Linux (act_pedit.c). Lorsqu'un paquet correspond à une règle pedit configurée, tcf_pedit_act() est invoquée. En interne, elle appelle skb_ensure_writable(skb, X) une seule fois, où X = tcfp_off_max_hint. Cela rend les premiers X octets du paquet privés (COW). Ensuite, dans une boucle sur chaque clé (opération d'édition), elle calcule le décalage réel d'écriture de la clé en ajoutant le décalage d'en-tête d'exécution au décalage spécifié de la clé, et écrit une valeur 32 bits dans le paquet. En pseudo-code :```c
u32 off_max = action->tcfp_off_max_hint;
skb_ensure_writable(skb, off_max);
for (i = 0; i < num_keys; i++) {
u32 hdr_off = compute_header_offset(skb, key[i].hdr_type);
u32 write_off = hdr_off + key[i].offset;
skb_store_bits(skb, write_off, &key[i].value, 4);
}
Parce que `hdr_off` n'est calculé qu'au moment du traitement de chaque clé, l'appel initial à `skb_ensure_writable()` n'en tenait pas compte. Si `hdr_off + key[i].offset` dépasse `off_max`, le code se rabat sur `skb_store_bits()` sur les fragments plutôt que sur la zone linéaire principale, ce qui signifie qu'il écrit dans une page qui n'a pas été rendue privée. C'est le point de défaillance.
**Surface d'attaque :** La seule interface nécessaire est le **tc filter** avec une action `pedit`, qui nécessite normalement la capacité **CAP_NET_ADMIN**. Cependant, les utilisateurs ordinaires peuvent obtenir CAP_NET_ADMIN au sein d'un espace de noms réseau privé (clonage d'espace de noms utilisateur) sans privilèges réels. Ainsi, un utilisateur non privilégié peut entrer dans un espace de noms utilisateur+réseau et créer une règle `tc pedit` sur loopback. L'écriture se produit lorsqu'un paquet est traité (l'attaquant génère généralement du trafic sur loopback pour la déclencher). La frontière de confiance (utilisateur vs noyau) est franchie car le noyau a fait confiance à sa propre configuration COW, mais les décalages fournis par l'utilisateur ont brisé cette hypothèse.
**Mécanisme interne :** Côté noyau, la vulnérabilité se manifeste comme une **écriture hors limites** (CWE-787). Elle corrompt la mémoire du noyau qui est mappée dans l'espace utilisateur (cache de pages de fichiers). Plus précisément, elle peut écraser le contenu de n'importe quelle page de fichier qui se trouve être mappée dans le tampon de socket. Dans la preuve de concept, `/bin/su` est mappé en mémoire en l'envoyant dans le tampon de socket, donc l'exploit modifie ses octets de point d'entrée en mémoire. Cela ne modifie pas le fichier sur disque, mais toute exécution ultérieure de ce binaire lit l'image empoisonnée depuis le cache. L'analyse du blog note :
> « Étant donné que le skb peut référencer des pages zero-copy apportées via sendfile, cette écriture hors limites peut atterrir dans la mémoire partagée du cache de pages qui soutient un fichier réel. Le noyau croit avoir rendu la mémoire du paquet sûre à modifier ; en réalité, l'écriture ultérieure atteint en dehors de la région qu'il a effectivement privatisée. »
**Frontières de confiance :** Le noyau a supposé à tort que `skb_ensure_writable()` (COW de chemin rapide) garantirait la sécurité pour toutes les écritures ultérieures. Il n'a pas revérifié pour chaque clé. L'utilisateur ne contrôle que la configuration du filtre de paquets et le contenu des paquets ; le noyau a accordé cela (via les espaces de noms réseau). Une fois cette confiance brisée, l'écriture s'est échappée dans la mémoire adossée à des fichiers qui aurait dû être protégée.
## Analyse de la cause racine
La cause racine est un **calcul incorrect de la plage COW dans l'action pedit**. En termes de code, un seul `skb_ensure_writable()` a été appelé avec une longueur basée sur `tcfp_off_max_hint`, puis à l'intérieur de la boucle, les décalages réels pouvaient dépasser cette valeur. Un petit correctif (mai 2026) le répare en déplaçant `skb_ensure_writable()` *à l'intérieur* de la boucle, après que le vrai décalage soit connu, et en ajoutant des vérifications et un traitement spécial pour les décalages négatifs. En d'autres termes :
- **Code bogué :** ```c
skb_ensure_writable(skb, action->tcfp_off_max_hint);
for each key:
// compute offset (hdr_off + key_offset)
skb_store_bits(skb, write_off, ...);
De plus, le correctif garantit que pour les décalages négatifs (éditions d'en-tête Ethernet), il utilise skb_cow() sur la marge de tête, et protège contre les cas INT_MIN. Le message de commit (résumé de stack.watch) indique : « Correction en déplaçant skb_ensure_writable() dans la boucle par clé où le décalage d'écriture réel est connu, et ajout de vérification de dépassement sur l'arithmétique du décalage. ».
Ainsi, pourquoi cela existe : lors de la revue de code ou de la conception, le recalcul par clé a été négligé. L'optimisation des indices statiques a contourné la nécessité de réévaluer par clé. Il semble s'agir d'un bogue honnête plutôt que d'un oubli malveillant, mais son effet est grave car il viole l'hypothèse de COW. Comme le note TuxCare, ce bogue a été fusionné sous couvert d'un correctif de routine pour « corruption de données », sans contexte de sécurité immédiat.
La vulnérabilité a été introduite par le commit noyau 8b796475fd78 (mai 2022) et est restée inaperçue jusqu'au début 2026. Selon les sources, le correctif (commit 899ee91156e5 du 31 mai 2026) a été soumis à la liste de diffusion netdev comme un correctif ordinaire de corruption de données. Les mainteneurs du noyau ont fusionné le correctif (net-7.1-rc7) le 4 juin 2026. Ce n'est que le 16 juin 2026 que le CVE-2026-46331 a été officiellement attribué (environ deux semaines après l'apparition du correctif). Un exploit public entièrement fonctionnel est apparu le 17 juin 2026 (le PoC packet_edit_meme).
Dans la pratique, la séquence était :
Plusieurs parties ont remarqué le bogue grâce au correctif ouvert. Par exemple, Massimiliano Oldani (chercheur en cybersécurité) a publié un article détaillé et un exploit peu après, notant que « un exploit de preuve de concept public et fonctionnel nommé packet_edit_meme est apparu sur GitHub dans les 24 heures suivant l'attribution du CVE ». CloudLinux, TuxCare et SentinelOne ont publié des analyses une fois le PoC public et les CVE attribués. Le tracker de sécurité Debian et PT DBugs ont également résumé le problème et les avis disponibles (voir Références).
Une attaque réaliste nécessite des préconditions minimales :
Capacités de l'attaquant : Un utilisateur local non privilégié sur la machine cible. L'utilisateur doit pouvoir créer un nouvel espace de noms utilisateur avec un espace de noms réseau (via unshare(CLONE_NEWUSER|CLONE_NEWNET)), ce qui accorde CAP_NET_ADMIN dans cet espace de noms sans privilèges root réels. Les espaces de noms utilisateur non privilégiés sont activés par défaut sur de nombreux noyaux (par ex. RHEL, Debian) et peuvent être réactivés sur Ubuntu avec une solution de contournement via aa-exec.
Conditions de la cible : La cible doit exécuter un noyau Linux vulnérable (environ 5.18–7.1-rc6) avec le module act_pedit disponible. Si act_pedit est intégré ou déjà chargé, il est immédiatement exploitable. S'il s'agit d'un module, il se charge automatiquement lorsqu'une règle tc pedit est configurée. La cible ne doit pas avoir appliqué le correctif amont. Notamment, il n'est pas nécessaire que l'attaquant ait un accès en écriture à un fichier ; l'exploit fonctionne en écrivant via des filtres de paquets.
Chaîne d'attaque :
unshare --map-root-user --net --pid bash pour créer un nouvel espace de noms utilisateur+réseau. Cela accorde CAP_NET_ADMIN dans cet espace de noms (utilisateur mappé à root à l'intérieur).ifconfig lo up) et éventuellement lance un écouteur (par ex. ). Cela fournit un flux de paquets pour les actions TC.Impact : En cas de succès, l'attaquant obtient tous les privilèges root localement. L'exploit peut être effectué en une seule commande et est déterministe. De plus, la corruption de pages arbitraires sauvegardées par fichier pourrait provoquer un déni de service (plantage système) si elle est utilisée différemment. Le PoC publié a spécifiquement écrasé le point d'entrée de /bin/su avec du shellcode, mais tout fichier que l'attaquant peut mapper pourrait être ciblé. La chaîne ne nécessite aucun timing spécial ni condition de concurrence et a été démontrée sur de nombreuses distributions (RHEL, Ubuntu, Debian, etc.).
Un exploit public, packet_edit_meme, est disponible sur GitHub (sgkdev/packet_edit_meme) et cible /bin/su. Nous décrivons sa logique essentielle sans charges utiles destructrices :```c
/* Pseudocode outline of the exploit (simplified) /
int main() {
/ 1. Identify a setuid binary (su) and its ELF entry offset */
int fd = open("/bin/su", O_RDONLY);
long entry = elf_entry_offset(fd);
if (entry < 0) abort();
printf("Target %s (UID=%d), entry offset 0x%lx\n", "/bin/su", getuid(), entry);
/* 2. Unshare user+net namespace to get CAP_NET_ADMIN locally */
if (unshare(CLONE_NEWUSER | CLONE_NEWNET) < 0) abort();
/* Map UID/GID to root (handled via /proc/self/uid_map, /gid_map) */
// (omit details: write "0 <uid> 1" to /proc/self/uid_map and gid_map, and deny setgroups)
/* 3. Setup environment: bring up loopback and listener */
if (system("ip link set lo up") < 0) abort();
if (system("nc -l 127.0.0.1 9999 &") < 0) abort();
/* 4. Configure a tc pedit action via netlink (simplified) */
// Assume 'pedit_write' sends a packet-edit command to the kernel.
// The key offsets below are chosen such that they exceed the initial COW range.
char shellcode[/*size=48*/] = {
// (assembly for setgid(0); setuid(0); execve("/bin/sh").., padded to 36 or 48 bytes)
};
size_t total = sizeof(shellcode), sent = 0;
while (sent < total) {
int chunk = min(PEDIT_MAX_WRITE, total - sent);
/* Issue TC pedit action to write next chunk */
if (pedit_write(fd, entry + sent, &shellcode[sent], chunk) != 0) {
fprintf(stderr, "pedit_write failed\n");
exit(1);
}
sent += chunk;
}
/* 5. Trigger execution of su (in original namespace) */
execl("/bin/su", "su", NULL); // This will run the poisoned binary as root
return 0;
}
Ce pseudocode illustre le flux : ouvrir `/bin/su`, délier les espaces de noms pour obtenir CAP_NET_ADMIN, configurer loopback et les règles TC pedit, puis appeler une fonction `pedit_write(fd, offset, data, len)` (dans le PoC réel, cela utilise des appels netlink en interne) pour écraser le cache de pages de la cible. Enfin, le binaire est exécuté, générant un shell root.
Le PoC réel est plus élaboré (gestion des mappages UID/GID, écoute réseau et octets de shellcode au niveau des appels système), mais le concept central est celui décrit ci-dessus. Nous insistons sur le fait de **ne pas exécuter cet exploit** sauf dans un environnement de test sécurisé, et de ne cibler aucun système réel. Ce qui précède est à titre de démonstration uniquement.
**Remarque :** Si aucun PoC public sûr n'existait, nous le dirions explicitement. Dans ce cas, le PoC est public et nous le décrivons conceptuellement. Nous avons omis les octets de shellcode bruts et les détails réels de netlink par souci de concision et de sécurité.
## Flux d'exploitation
1. **Point d'entrée :** L'attaquant doit d'abord obtenir CAP_NET_ADMIN. Typiquement, cela signifie créer un espace de noms utilisateur + réseau (`unshare`) à partir d'un processus non privilégié, ce qui accorde CAP_NET_ADMIN local à l'espace de noms.
2. **Accès initial :** Dans cet espace de noms, l'attaquant peut utiliser des outils normaux (`ip`, `tc`) pour configurer le contrôle de trafic. Le chemin de code `act_pedit` du noyau est désormais accessible pour les paquets.
3. **Déclencheur :** L'attaquant configure un `tc filter ... action pedit` sur l'interface loopback. Ce filtre correspond aux paquets (par exemple 0-match) et spécifie une ou plusieurs **clés typées** avec des types d'en-tête (IP, TCP) et des décalages. Les décalages sont choisis de sorte qu'*après que le noyau calcule la base d'en-tête dans la boucle*, le décalage d'écriture final dépasse la plage initiale de COW.
4. **Exploitation :** Lorsqu'un paquet correspondant au filtre est traité, le noyau appelle `tcf_pedit_act()`. Il effectue un `skb_ensure_writable()` *insuffisant* puis itère sur les clés. Pour au moins une clé, l'écriture atterrit sur une page qui *n'a pas été* clonée en copie privée. Cela provoque une **écriture hors limites** dans le cache de pages partagé. Si le tampon de socket a été préparé pour référencer des pages d'un fichier (via sendfile/splice), cette écriture corrompt ces pages de fichier.
5. **Post-exploitation :** Le shellcode de l'attaquant a été écrit dans le cache de pages du binaire cible (par exemple `/bin/su`). L'attaquant (dans l'espace de noms d'origine) exécute alors `/bin/su`. Le noyau lit l'image en mémoire (avec la charge utile injectée) et exécute le shellcode, donnant à l'attaquant un shell root. À ce stade, l'ensemble du système est compromis.
6. **Impact :** L'attaquant obtient les privilèges root. Les données confidentielles peuvent être écrasées mais pas divulguées directement. L'intégrité est complètement compromise (l'attaquant peut modifier l'image mémoire de n'importe quel fichier). La disponibilité peut également être affectée (une mauvaise écriture sur des pages critiques pourrait faire planter des processus ou le système). Métriques CVSS : Moyen global (CVSS 3.1=6.0), mais l'impact réel est un root local sévère.
Ce flux est résumé par un diagramme :```mermaid
flowchart LR
A[Attacker (unprivileged user)] --> B[Unshare into user+net namespace<br>(gains CAP_NET_ADMIN)]
B --> C[Configure TC pedit filter on lo]
C --> D{Packet processing by kernel}
D --> E[act_pedit computes wrong COW range]
E --> F[skb_store_bits writes beyond COW'd region]
F --> G[Page cache of target file is corrupted]
G --> H[Attacker executes poisoned setuid binary]
H --> I[Root shell obtained]
act_pedit apparaît dans lsmod de manière inattendue sur des systèmes qui n'utilisent normalement pas tc pedit. (Par exemple, lsmod | grep act_pedit non vide sur des serveurs web.)tc: Commandes tc inhabituelles ou messages netlink provenant de processus non privilégiés. Les journaux d'audit peuvent montrer CAP_NET_ADMIN accordé à un processus non root.netstat -tulnp affichant nc ou un écouteur personnalisé sur 127.0.0.1 peut être un signe.tcf_pedit_act, skb_ensure_writable, ou soft lockups lors d'un trafic intense sur loopback ou erreurs de traitement tc. (Ce serait inhabituel et indicatif d'une corruption.)Par exemple, un IAO est fichiers corrompus dans le cache de pages: une liste de contrôle de triage pourrait inclure la vérification du contenu des fichiers en mémoire par rapport au disque, en particulier pour les binaires setuid après une forte activité tc. Un autre est création d'un nouvel espace de noms: la surveillance des appels à unshare(CLONE_NEWUSER|CLONE_NEWNET) pourrait être signalée. En résumé, les défenseurs doivent surveiller tout élément parmi : utilisation de act_pedit, utilisation d'userns, et modifications soudaines d'exécutables en RAM.
Pour détecter les tentatives d'exploitation :
tc ou les messages netlink qui ajoutent un filtre act_pedit. Par exemple, les règles Sigma pourraient rechercher des événements contenant TCA_ACT_KIND: pedit ou similaire. Surveiller les journaux d'audit pour capset CAP_NET_ADMIN provenant de processus non root, ou des écritures dans /proc/*/uid_map./bin/su (ou d'autres binaires sensibles) et les exécutant soudainement en tandem avec des appels système d'espace de noms/unshare. Alerter sur tout processus qui ouvre à la fois un binaire setuid et crée un userns.skb_ensure_writable() ne peut pas être trompé (bien qu'aucune vérification intégrée connue n'existe).En résumé, les défenseurs doivent journaliser et auditer l'utilisation des espaces de noms utilisateur, les commandes tc et les chargements de modules. Une approche clé : rejeter ou journaliser toute invocation de tc pedit par des utilisateurs non fiables. Sur les hôtes compromis, vérifier si /etc/modprobe.d/disable-act_pedit.conf a été appliqué (il devrait l'être de manière préventive).
Appliquer les correctifs: La solution principale est une mise à jour du noyau. Toutes les distributions majeures ont publié des mises à jour en juin 2026. La mise à niveau vers un noyau corrigé (Linux 7.1.0 ou ultérieur, ou rétroportages de distribution) est la solution définitive.
Modifications de configuration: Si la correction n'est pas immédiatement possible, mettre en œuvre des atténuations :
act_pedit: Si vos charges de travail ne nécessitent pas tc pedit, mettre le module sur liste noire. Par exemple : ```
echo 'install act_pedit /bin/true' | sudo tee /etc/modprobe.d/disable-act_pedit.conf
lsmod | grep -w act_pedit && sudo rmmod act_pedit
Cela garantit que l'action ne peut pas être chargée. (Ceci est recommandé par CloudLinux et TuxCare.) Ne pas appliquer sur les hôtes qui utilisent légitimement tc pedit.
Sur Ubuntu 22.04+: ``` sudo sysctl -w kernel.unprivileged_userns_clone=0 echo 'kernel.unprivileged_userns_clone = 0' | sudo tee /etc/sysctl.d/99-pedit-cow.conf
Cela empêche les utilisateurs non privilégiés de créer l'espace de noms utilisateur nécessaire pour obtenir CAP_NET_ADMIN. Remarque : la désactivation des espaces de noms peut casser les conteneurs rootless et certaines applications en bac à sable.
- **Drop Page Cache (Containment) :** Si vous soupçonnez que l'exploit a été exécuté, les copies en mémoire des binaires peuvent être empoisonnées. Vide immédiatement les caches pour les évincer : ```
sudo sh -c "echo 3 > /proc/sys/vm/drop_caches"
Cela force le rechargement des pages depuis le disque. Attention : Si un attaquant avait déjà les droits root, vider les caches ne supprimera aucune persistance qu'il aurait installée. Traitez ces hôtes comme compromis.
Moindre privilège : Auditez et restreignez qui peut utiliser tc. L'exploit nécessite uniquement CAP_NET_ADMIN ; assurez-vous que seuls les administrateurs de confiance disposent de cette capacité. Utilisez RBAC ou la conteneurisation pour limiter les octrois de capacités.
Contrôles réseau : Bien que non directement accessible en réseau, assurez-vous que l'utilisation de la boucle locale est surveillée. Bloquer 127.0.0.1 via pare-feu est peu pratique, mais assurez-vous que seul le trafic localhost est utilisé pour les manipulations TC.
Avis des fournisseurs : Référez-vous aux avis officiels de votre OS. Red Hat a RHSA-2026:27354 (et connexes) pour RHEL 8/9/10, Debian a DSA-6355-1, la page CVE d'Ubuntu liste les noyaux corrigés, etc. (Voir Références.)
La correction à long terme consiste à s'assurer que tous les systèmes concernés sont sur des noyaux mis à jour. Les paquets de noyau contenant le correctif doivent être installés et les systèmes redémarrés. Pour les conteneurs ou systèmes ne pouvant pas redémarrer, envisagez des solutions de correctif en direct (par exemple KernelCare) qui ont préparé des correctifs.
De plus, la conception du système doit supposer que les interfaces du noyau accessibles depuis l'espace utilisateur peuvent évoluer avec le temps. Restreindre CAP_NET_ADMIN et filtrer l'utilisation de tc sont de bonnes pratiques au-delà de ce bogue.
En cas de compromission, reconstruisez le système. La vulnérabilité empoisonne uniquement le cache de pages, mais un attaquant avec droits root peut avoir effectué d'autres actions malveillantes ; une validation forensique est nécessaire. Ne vous fiez pas aux analyses d'intégrité des fichiers après l'exploit, car comme indiqué, la PoC laisse les fichiers sur disque intacts. Le redémarrage et l'application du correctif constituent la voie de correction sûre.
Compte tenu de ces facteurs, un vecteur CVSS v3.1 typique est AV:L/AC:L/PR:H/UI:N/S:U/C:N/I:H/A:H, donnant un Score de base de 6,0 (Moyen). Notez cependant que CVSS ne capture pas le fait que cette vulnérabilité accorde une élévation de privilèges à root, ce qui est en pratique critique. (Certaines sources ont calculé CVSSv4 pour des bugs similaires ; par exemple PT DBugs liste 8,5 sur CVSSv4.)
La sévérité est souvent évaluée comme Importante/Critique par les fournisseurs. L'avis de Red Hat pour ce CVE le qualifie d'Important, AWS le marque Moyen (CVSS 6,0). Dans tous les cas, comme le root est obtenu, le risque pratique est le plus élevé sur les systèmes multi-utilisateurs ou partagés.
Cette vulnérabilité appartient à une famille de bugs d'empoisonnement du cache de pages. D'autres CVE notables incluent :
splice() sur un tube pouvait écrire dans le cache de pages au-delà des limites de COW. Il permettait également d'écraser des fichiers en mémoire (sans modification du disque)./proc/self/mem de copy-on-write qui permettait une écriture locale dans des mappages en lecture seule.Chacun de ces bugs implique un chemin rapide du noyau écrivant dans une mémoire qu'il croyait posséder exclusivement, mais ce n'était pas le cas. CVE-2026-46331 est unique en ce qu'il se produit dans l'action net/sched pedit et exploite des espaces de noms utilisateur pour contourner les restrictions de privilèges. Contrairement à DirtyPipe ou Dirty COW, aucun processus privilégié auxiliaire (comme un système mal configuré) n'est nécessaire – un seul utilisateur non privilégié peut le déclencher.
Toutes les références proviennent de sources réputées (avis de fournisseurs, analyses publiées, entrées CVE/NVD).
act_pedit, le calcul trop précoce de la capacité d'écriture a permis la corruption du cache de pages.nc -l 127.0.0.1 9999tc ou netlink, l'attaquant crée une qdisc et un filtre sur lo qui correspond à tous les paquets (par ex. match u32 0 0) et attache une action pedit avec des clés spécialement conçues. Chaque clé a un type d'en-tête dynamique (par ex. en-tête IP pour un décalage L4) et un décalage choisi de sorte que la position d'écriture réelle (début de l'en-tête + décalage) se trouve juste au-delà de la plage couverte par skb_ensure_writable().echo '' > /dev/udp/127.0.0.1/53) pour déclencher le filtre. Le noyau appelle tcf_pedit_act(), alloue une plage COW, puis itère sur les clés. Au moins une écriture de clé tombe en dehors de la région pré-COW, ce qui fait que l'écriture va dans le cache de pages partagé./bin/su dans le socket via sendfile ou similaire, de sorte que le tampon de paquet référence les pages de ce fichier. L'écriture hors limites corrompt alors la copie en mémoire de /bin/su (en particulier le point d'entrée ELF)./bin/su). Parce que le noyau a injecté par inadvertance un shellcode qui fait setgid(0); setuid(0); execve("/bin/sh"), l'exécution de su donne un shell root. Le fichier sur disque n'a jamais été modifié, donc aucun outil d'intégrité de fichier sur disque ne montrera de changement.auditd) montrant des programmes obtenant CAP_NET_ADMIN via userns ou écrivant dans /proc/[pid]/uid_map.