
pedit COW
CVE-2026-46331 (apodado “pedit COW”) es una falla local de escalada de privilegios en el kernel de Linux en el subsistema de control de tráfico. Un usuario no privilegiado (en un espacio de nombres de red no privilegiado) puede configurar el filtro act_pedit (editor de paquetes) para desencadenar una escritura parcial de copia en escritura (COW) en la caché de páginas. En efecto, el kernel escribe datos controlados por el atacante en la imagen en memoria de un archivo sin marcar la página como privada, corrompiendo la copia en caché de ese archivo. Críticamente, el exploit solo requiere CAP_NET_ADMIN (obtenible en un espacio de nombres de usuario) y no modifica el archivo en disco. En la práctica, una prueba de concepto (PoC) funcional llamada packet_edit_meme fue publicada el 17 de junio de 2026, demostrando cómo sobrescribir la imagen en caché de páginas de un binario setuid (por ejemplo, /bin/su) para generar un shell de root. La vulnerabilidad se origina en un cálculo incorrecto del rango COW en tcf_pedit_act() y ha sido corregida en upstream (4 de junio de 2026) moviendo la verificación de la región escribible al bucle por clave.
act_pedit. Las versiones estables sin parche (incluyendo muchos kernels de distribuciones) son vulnerables.tc pedit y sobrescribe el punto de entrada ELF de un binario setuid en memoria con shellcode.skb_ensure_writable() dentro del bucle por clave). Como solución alternativa, bloquee o descargue el módulo act_pedit o deshabilite los espacios de nombres de usuario no privilegiados (por ejemplo, sysctl user.max_user_namespaces=0). Después de la mitigación, vacíe las cachés (echo 3 > /proc/sys/vm/drop_caches) para eliminar cualquier página envenenada.Este informe proporciona un análisis técnico detallado de CVE-2026-46331: su causa, explotación, detección y estrategias de remediación, con referencias a avisos de proveedores, CVEs y el exploit público.
Definición: CVE-2026-46331 es un error de escritura fuera de límites en el subsistema Traffic Control (net/sched) del kernel de Linux, específicamente en la acción act_pedit (editor de paquetes). La función tcf_pedit_act() calcula un rango de “copia en escritura” para operaciones de edición de paquetes antes de iterar sobre las claves tipificadas, utilizando una pista estática tcfp_off_max_hint. Sin embargo, algunas claves (por ejemplo, ediciones de cabecera TCP/UDP) determinan su desplazamiento de bytes final solo en tiempo de ejecución. El código nunca vuelve a verificar la capacidad de escritura para estos desplazamientos dinámicos. Como resultado, las escrituras pueden ocurrir fuera de la región pre-COW: parte de la escritura del paquete nunca se hace privada, lo que lleva a un COW parcial. Esta escritura errónea se propaga a la memoria compartida de la caché de páginas de un archivo (si los buffers del paquete hacen referencia a páginas del archivo), corrompiendo la imagen del archivo en caché.
Antecedentes: La acción editor de paquetes (pedit) de Linux permite a los administradores reescribir bytes arbitrarios dentro de las cabeceras de los paquetes (capas de enlace, red o transporte) a medida que los paquetes atraviesan un filtro tc configurado. Funciona especificando un desplazamiento (posiblemente anclado a una cabecera) y un valor/máscara de 32 bits. Internamente, pedit opera sobre socket-buffers (sk_buff) y debe hacer que la memoria del paquete de destino sea escribible antes de modificarlo (a través de skb_ensure_writable() de manera COW). Idealmente, el kernel debería clonar (copia privada) cualquier página compartida antes de escribir para evitar alterar la memoria utilizada en otro lugar.
Causa Raíz: En tcf_pedit_act(), el código calcula erróneamente el rango escribible solo una vez al inicio, utilizando tcfp_off_max_hint (el desplazamiento estático máximo). Esta pista no incluye ningún desplazamiento de cabecera en tiempo de ejecución que las claves tipificadas añaden cuando se procesa el paquete. Claves como TCP o UDP pueden calcular un desplazamiento basado en la posición de la cabecera IP en tiempo de ejecución (por ejemplo, si una clave anterior desplaza la cabecera de red). Por lo tanto, durante el bucle por clave, el desplazamiento real de una clave puede exceder el rango que fue pre-asignado como escribible. El código entonces escribe en la memoria del paquete a través de skb_store_bits(), pero como la página más allá de la región pre-COW no se hizo privada, la escritura corrompe una página que todavía está compartida con la caché de páginas. En resumen, “calcular el rango del paquete escribible demasiado pronto” causa una escritura fuera de límites y entre páginas. Los desplazamientos negativos (por ejemplo, editar cabeceras Ethernet en ingreso) también se manejan incorrectamente, e incluso offset_valid() carecía de una guardia para INT_MIN, agravando la falla.
Por Qué Ocurre: Este error es esencialmente un error de lógica en el cálculo del rango de copia en escritura. El kernel asumió que el desplazamiento máximo estático (conocido en tiempo de carga) era suficiente para todas las ediciones. No actualizó el rango COW cuando se aplicaron claves con desplazamientos dinámicos. Después de una serie de ediciones en cola, la escritura final podría quedar fuera de la región preverificada. Debido a que los buffers de paquetes pueden hacer referencia a páginas de archivos mapeados en memoria (por ejemplo, a través de mecanismos de copia cero), esta escritura “COW parcial” puede alcanzar la caché de páginas de un archivo en disco. En la práctica, la acción del editor de paquetes puede recibir páginas de un sendfile o splice; por lo tanto, una única operación de filtro de paquetes puede escribir indirectamente datos elegidos por el atacante en la imagen en memoria de un archivo, sin alterar el disco.
Componentes y Flujo de Datos: El código vulnerable reside en el subsistema net/sched de Linux (act_pedit.c). Cuando un paquete coincide con una regla pedit configurada, se invoca tcf_pedit_act(). Internamente, llama a skb_ensure_writable(skb, X) exactamente una vez, donde X = tcfp_off_max_hint. Esto hace que los primeros X bytes del paquete sean privados (COW). Luego, en un bucle sobre cada clave (operación de edición), calcula el desplazamiento de escritura real de la clave sumando el desplazamiento de cabecera en tiempo de ejecución al desplazamiento especificado de la clave, y escribe un valor de 32 bits en el paquete. En pseudocódigo:```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);
}
Debido a que `hdr_off` solo se calcula al procesar cada clave, la llamada inicial a `skb_ensure_writable()` no lo tuvo en cuenta. Si `hdr_off + key[i].offset` supera `off_max`, el código recurre a `skb_store_bits()` en fragmentos en lugar del área lineal principal, lo que significa que escribe en una página no hecha privada. Ese es el punto de fallo.
**Superficie de ataque:** La única interfaz necesaria es el **filtro tc** con una acción `pedit`, que normalmente requiere la capacidad **CAP_NET_ADMIN**. Sin embargo, los usuarios comunes pueden obtener CAP_NET_ADMIN dentro de un espacio de nombres de red privado (clonación de espacio de nombres de usuario) sin privilegios reales. Por lo tanto, un usuario no privilegiado puede ingresar a un espacio de nombres de usuario+red y crear una regla `tc pedit` en loopback. La escritura ocurre cuando se procesa un paquete (el atacante normalmente genera tráfico en loopback para activarlo). El límite de confianza (usuario vs. kernel) se cruza porque el kernel confió en su propia configuración de COW, pero los desplazamientos proporcionados por el usuario rompieron esa suposición.
**Mecanismo interno:** Del lado del kernel, la vulnerabilidad se manifiesta como una **escritura fuera de los límites** (CWE-787). Corrompe la memoria del kernel que está mapeada en el espacio de usuario (caché de páginas de archivos). Específicamente, puede sobrescribir el contenido de cualquier página de archivo que esté mapeada en el búfer de socket. En la prueba de concepto, `/bin/su` se mapea mediante mmap al enviarlo al búfer de socket, por lo que el exploit cambia los bytes de su punto de entrada en la memoria. Esto no modifica el archivo en disco, pero cualquier ejecución posterior de ese binario lee la imagen envenenada de la caché. El análisis del blog señala:
> “Debido a que el skb puede hacer referencia a páginas de copia cero introducidas mediante sendfile, esa escritura fuera de los límites puede aterrizar en la memoria compartida de la caché de página que respalda un archivo real. El kernel cree que ha hecho que la memoria del paquete sea segura para modificar; en realidad, la escritura posterior alcanza una región fuera de la que realmente privatizó.”
**Límites de confianza:** El kernel asumió erróneamente que `skb_ensure_writable()` (COW de ruta rápida) garantizaría la seguridad para todas las escrituras posteriores. No volvió a verificar cada clave. El usuario solo controla la configuración del filtro de paquetes y el contenido del paquete; el kernel lo concedió (a través de espacios de nombres de red). Una vez que se violó esa confianza, la escritura escapó a la memoria respaldada por archivos que debería haber estado protegida.
## Análisis de causa raíz
La causa raíz es **el cálculo incorrecto del rango de COW en la acción pedit**. En términos de código, se llamó a un único `skb_ensure_writable()` con una longitud basada en `tcfp_off_max_hint`, luego, dentro del bucle, los desplazamientos reales podían exceder esto. Un pequeño parche (mayo de 2026) lo corrige moviendo `skb_ensure_writable()` *dentro* del bucle, después de que se conoce el desplazamiento real, y agregando comprobaciones y manejo especial para desplazamientos negativos. En otras palabras:
- **Código con error:** ```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, ...);
Additionally, the fix ensures that for negative offsets (Ethernet header edits) it uses skb_cow() on headroom, and guards against INT_MIN cases. The commit message (stack.watch summary) states: “Fix by moving skb_ensure_writable() inside the per-key loop where the actual write offset is known, and add overflow checking on the offset arithmetic.”.
Thus, why it exists: during code review or design, the per-key re-calculation was overlooked. The static hint optimization bypassed the need to re-evaluate per key. It appears to be an honest bug rather than a malicious oversight, but its effect is severe because it violates the COW assumption. As TuxCare notes, this bug was merged under the guise of a routine “data corruption” fix, without immediate security context.
The vulnerability was introduced by kernel commit 8b796475fd78 (May 2022) and remained unnoticed until early 2026. According to sources, the fix (commit 899ee91156e5 on May 31, 2026) was submitted to the netdev mailing list as an ordinary data-corruption patch. The kernel maintainers merged the fix (net-7.1-rc7) on June 4, 2026. Only on June 16, 2026 was CVE-2026-46331 formally assigned (about two weeks after the patch appeared). A fully weaponized public exploit appeared on June 17, 2026 (the packet_edit_meme PoC).
In practice, the sequence was:
Multiple parties noticed the bug by the open patch. For example, Massimiliano Oldani (cybersecurity researcher) published a detailed write-up and exploit shortly after, noting that “a public, working proof-of-concept exploit named packet_edit_meme appeared on GitHub within 24 hours of CVE assignment”. CloudLinux, TuxCare, and SentinelOne published analyses once the PoC was public and CVEs assigned. The Debian security tracker and PT DBugs also summarized the issue and available advisories (see References).
A realistic attack requires minimal preconditions:
Attacker capabilities: A local unprivileged user on the target machine. The user must be able to create a new user namespace with network namespace (via unshare(CLONE_NEWUSER|CLONE_NEWNET)), which grants CAP_NET_ADMIN inside that namespace without real root privileges. Unprivileged user namespaces are enabled by default on many kernels (e.g. RHEL, Debian) and can be re-enabled on Ubuntu with an aa-exec workaround.
Target conditions: The target must be running a vulnerable Linux kernel (approx. 5.18–7.1-rc6) with the act_pedit module available. If act_pedit is built-in or already loaded, it is immediately exploitable. If it is a module, it auto-loads when a tc pedit rule is configured. The target should not have applied the upstream patch. Notably, it is not necessary for the attacker to have write access to any file; the exploit works by writing through packet filters.
Attack chain:
unshare --map-root-user --net --pid bash to create a new user+net namespace. This grants CAP_NET_ADMIN in that namespace (user mapped to root inside).ifconfig lo up) and optionally spawns a listener (e.g. nc -l 127.0.0.1 9999). This provides a packet flow to use for TC actions.Impact: If successful, the attacker gains full root privileges locally. The exploit can be done in one command and is deterministic. Additionally, corruption of arbitrary file-backed pages could cause denial-of-service (system crash) if used differently. The published PoC specifically overwrote /bin/su’s entrypoint with shellcode, but any file the attacker can map could be targeted. The chain requires no special timing or race and has been demonstrated on many distros (RHEL, Ubuntu, Debian, etc.).
A public exploit, packet_edit_meme, is available on GitHub (sgkdev/packet_edit_meme) and targets /bin/su. We describe its essential logic without destructive payloads:```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;
}
Este pseudocódigo ilustra el flujo: abrir `/bin/su`, descompartir espacios de nombres (unshare) para obtener CAP_NET_ADMIN, configurar loopback y reglas TC pedit, luego llamar a una función `pedit_write(fd, offset, data, len)` (en el PoC real esto usa llamadas netlink internamente) para sobrescribir la caché de páginas del objetivo. Finalmente, se ejecuta el binario, generando un shell root.
El PoC real es más elaborado (manejo de mapas UID/GID, escucha de red y bytes de shellcode a nivel de syscall), pero el concepto central es el anterior. Enfatizamos **no ejecutar este exploit** excepto en un entorno de pruebas seguro, y no apuntar a ningún sistema real. Lo anterior es solo para demostración.
**Nota:** Si no existiera un PoC público y seguro de usar, lo diríamos explícitamente. En este caso, el PoC es público, y lo describimos conceptualmente. Hemos omitido los bytes de shellcode sin procesar y los detalles reales de netlink por brevedad y seguridad.
## Flujo de Explotación
1. **Punto de entrada:** El atacante debe primero obtener CAP_NET_ADMIN. Típicamente, esto significa crear un espacio de nombres de usuario+red (`unshare`) desde un proceso no privilegiado, lo que otorga CAP_NET_ADMIN local al espacio de nombres.
2. **Acceso inicial:** Dentro de este espacio de nombres, el atacante puede usar herramientas normales (`ip`, `tc`) para configurar el control de tráfico. La ruta de código `act_pedit` del kernel ahora es alcanzable para los paquetes.
3. **Desencadenante:** El atacante configura un `tc filter ... action pedit` en la interfaz loopback. Este filtro coincide con paquetes (por ejemplo, coincidencia 0) y especifica una o más **claves tipadas** con tipos de cabecera (IP, TCP) y desplazamientos. Los desplazamientos se eligen de modo que *después de que el kernel calcule la base de la cabecera dentro del bucle*, el desplazamiento final de escritura supere el rango inicial de COW.
4. **Explotación:** Cuando se procesa un paquete que coincide con el filtro, el kernel llama a `tcf_pedit_act()`. Realiza un `skb_ensure_writable()` *insuficiente* y luego itera sobre las claves. Para al menos una clave, la escritura aterriza en una página que *no* fue clonada en una copia privada. Esto causa una **escritura fuera de los límites** en la caché de páginas compartida. Si el búfer de socket fue preparado para referenciar páginas de un archivo (mediante sendfile/splice), esa escritura corrompe esas páginas del archivo.
5. **Post-explotación:** El shellcode del atacante ha sido escrito en la caché de páginas del binario objetivo (por ejemplo, `/bin/su`). El atacante (en el espacio de nombres original) ejecuta entonces `/bin/su`. El kernel lee la imagen en memoria (con la carga útil inyectada) y ejecuta el shellcode, otorgándole al atacante un shell root. En este punto, se ha producido un compromiso total del sistema.
6. **Impacto:** El atacante obtiene privilegios de root. Los datos confidenciales podrían sobrescribirse pero no filtrarse directamente. La integridad se rompe por completo (el atacante puede cambiar la imagen en memoria de cualquier archivo). La disponibilidad también puede verse afectada (escribir incorrectamente páginas críticas podría bloquear procesos o el sistema). Métricas CVSS: Medio en general (CVSS 3.1=6.0), pero el impacto real es root local severo.
Este flujo se resume diagramáticamente:```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 aparece en lsmod inesperadamente en sistemas que normalmente no usan tc pedit. (Ej: lsmod | grep act_pedit no está vacío en servidores web.)tc: Comandos tc inusuales o mensajes netlink de procesos sin privilegios. Los registros de auditoría pueden mostrar CAP_NET_ADMIN otorgado a un proceso no root.netstat -tulnp que muestra nc o un listener personalizado en 127.0.0.1 podría ser una señal.tcf_pedit_act, skb_ensure_writable, o soft lockups durante tráfico intenso en loopback o errores en el procesamiento de tc. (Estos serían inusuales e indicativos de corrupción.)Por ejemplo, un IOA son archivos corruptos en la caché de página: una lista de verificación de triaje podría incluir verificar el contenido del archivo en memoria vs disco, especialmente para binarios setuid después de una intensa actividad de tc. Otro es creación de nuevos namespaces: monitorear llamadas a unshare(CLONE_NEWUSER|CLONE_NEWNET) podría marcarse. En resumen, los defensores deben vigilar cualquier: uso de act_pedit, uso de userns y modificaciones repentinas de ejecutables en RAM.
Para detectar intentos de explotación:
tc o mensajes netlink que añadan un filtro act_pedit. Por ejemplo, las reglas Sigma podrían buscar eventos que contengan TCA_ACT_KIND: pedit o similar. Monitorear registros de auditoría para capset CAP_NET_ADMIN de procesos no root, o escrituras en /proc/*/uid_map./bin/su (u otros binarios sensibles) y de repente los ejecutan en conjunto con llamadas al sistema namespace/unshare. Alertar sobre cualquier proceso que abra un binario setuid y cree un userns.skb_ensure_writable() (aunque no existe una verificación incorporada conocida).En resumen, los defensores deben registrar y auditar el uso de namespaces de usuario, comandos tc y cargas de módulos. Un enfoque clave: rechazar o registrar cualquier invocación de tc pedit por usuarios no confiables. En hosts comprometidos, verificar si se ha aplicado /etc/modprobe.d/disable-act_pedit.conf (debería hacerse de forma preventiva).
Aplicar parches: La solución principal es una actualización del kernel. Todas las distribuciones principales han lanzado actualizaciones en junio de 2026. Actualizar a un kernel parcheado (Linux 7.1.0 o posterior, o backports de la distribución) es la solución definitiva.
Cambios de configuración: Si no es posible parchear de inmediato, implementar mitigaciones:
act_pedit: Si sus cargas de trabajo no requieren tc pedit, incluya el módulo en la lista negra. Por ejemplo:
echo 'install act_pedit /bin/true' | sudo tee /etc/modprobe.d/disable-act_pedit.conf
lsmod | grep -w act_pedit && sudo rmmod act_pedit
Esto asegura que la acción no se pueda cargar. (Esto es recomendado por CloudLinux y TuxCare.) No aplicar en hosts que usen legítimamente tc pedit.
En 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
Esto evita que los usuarios sin privilegios creen el espacio de nombres de usuario necesario para obtener CAP_NET_ADMIN. Nota: deshabilitar los espacios de nombres puede romper los contenedores sin raíz y algunas aplicaciones en entorno de pruebas.
- **Eliminar la caché de páginas (Contención):** Si sospecha que el exploit se ejecutó, las copias en memoria de los binarios pueden estar envenenadas. Inmediatamente elimine las cachés para desalojarlos: ```
sudo sh -c "echo 3 > /proc/sys/vm/drop_caches"
Esto fuerza la recarga de páginas desde el disco. Precaución: Si un atacante ya tenía acceso root, borrar los cachés no eliminará ninguna persistencia que haya instalado. Trate dichos sistemas como comprometidos.
Mínimo privilegio: Audite y restrinja quién puede usar tc. El exploit solo necesita CAP_NET_ADMIN; asegúrese de que solo administradores de confianza tengan esta capacidad. Use RBAC o contenerización para limitar las concesiones de capacidad.
Controles de red: Aunque no es directamente explotable a través de la red, asegúrese de que el uso de loopback esté monitorizado. Bloquear 127.0.0.1 con un firewall no es práctico, pero asegúrese de que solo el tráfico de localhost se use para las manipulaciones de TC.
Avisos de proveedores: Consulte los avisos oficiales de su sistema operativo. Red Hat tiene RHSA-2026:27354 (y relacionados) para RHEL 8/9/10, Debian tiene DSA-6355-1, la página de CVE de Ubuntu enumera los kernels corregidos, etc. (Ver Referencias).
La mitigación a largo plazo implica asegurarse de que todos los sistemas afectados tengan kernels actualizados. Se deben instalar los paquetes de kernel que contienen la corrección y reiniciar los sistemas. Para contenedores o sistemas que no puedan reiniciarse, considere soluciones de actualización en vivo (ej., KernelCare) que tienen parches preparados.
Además, el diseño del sistema debe asumir que las interfaces de kernel accesibles desde el espacio de usuario pueden cambiar con el tiempo. Restringir CAP_NET_ADMIN y filtrar el uso de tc son buenas prácticas más allá de este error.
Si se produjo un compromiso, reconstruya el sistema. La vulnerabilidad envenena solo el caché de páginas, pero un atacante con root puede haber realizado otras acciones maliciosas; es necesario realizar una validación forense. No confíe en los escaneos de integridad de archivos después del exploit, porque como se mencionó, el PoC deja intactos los archivos en el disco. Reiniciar y aplicar parches es la vía de mitigación segura.
Dados estos factores, un vector CVSS v3.1 típico es AV:L/AC:L/PR:H/UI:N/S:U/C:N/I:H/A:H, lo que da una Puntuación Base de 6.0 (Medio). Sin embargo, tenga en cuenta que CVSS no captura que esta vulnerabilidad otorga escalada de privilegios a root, lo que en la práctica es crítico. (Algunas fuentes calcularon CVSSv4 para errores similares; ej., PT DBugs lista 8.5 en CVSSv4).
La gravedad suele calificarse como Importante/Crítica por los proveedores. El aviso de Red Hat para este CVE lo etiqueta como Importante, y AWS lo marca como Medio (CVSS 6.0). En cualquier caso, debido a que se obtiene acceso root, el riesgo práctico es mayor en sistemas multiusuario o compartidos.
Esta vulnerabilidad pertenece a una familia de errores de envenenamiento del caché de páginas. Otros CVEs notables incluyen:
splice() en una tubería podía escribir en el caché de páginas más allá de los límites de COW. También permitía sobrescribir archivos en memoria (sin cambio en disco)./proc/self/mem copy-on-write que permitía escritura local en mapeos de solo lectura.Cada uno de estos implica una ruta rápida del kernel escribiendo en memoria que creía poseer exclusivamente, pero no era así. CVE-2026-46331 es único en que ocurre en net/sched pedit action y aprovecha los espacios de nombres de usuario para eludir las restricciones de privilegios. A diferencia de DirtyPipe o Dirty COW, no se necesita ningún proceso privilegiado auxiliar (como un sistema mal configurado): un solo usuario no privilegiado puede desencadenarlo.
Todas las referencias provienen de fuentes confiables (avisos de proveedores, análisis publicados, entradas CVE/NVD).
act_pedit, calcular la posibilidad de escritura demasiado pronto permitió la corrupción del caché de páginas.tc command or netlink, the attacker creates a qdisc and filter on lo that matches all packets (e.g. match u32 0 0) and attaches a pedit action with specially crafted keys. Each key has a dynamic header type (e.g. IP header for an L4 offset) and an offset chosen so that the actual write position (header start + offset) lies just beyond the range skb_ensure_writable() covered.echo '' > /dev/udp/127.0.0.1/53) to trigger the filter. The kernel calls tcf_pedit_act(), allocates a COW range, then iterates the keys. At least one key’s write falls outside the pre-COW’d region, causing the write to go into the shared pagecache./bin/su into the socket via sendfile or similar, so the packet buffer references that file’s pages. The out-of-bounds write then corrupts the in-memory copy of /bin/su (specifically the ELF entry point)./bin/su). Because the kernel has inadvertently injected shellcode that does setgid(0); setuid(0); execve("/bin/sh"), running su drops a root shell. The file on disk was never altered, so no on-disk file integrity tools will show a change.auditd) que muestran programas obteniendo CAP_NET_ADMIN a través de userns o escribiendo en /proc/[pid]/uid_map.