CVE-2026-46300 in Linux (Fragnesia)
Resumen
por VulDB • 2026-05-31
En el kernel de Linux, se ha resuelto la siguiente vulnerabilidad:
net: skbuff: propagar el marcador de fragmentos compartidos a través de las funciones auxiliares de transferencia de fragmentos
Dos funciones auxiliares de transferencia de fragmentos (__pskb_copy_fclone() y skb_shift()) no logran propagar el bit SKBFL_SHARED_FRAG en skb_shinfo()->flags al mover fragmentos desde el origen al destino. __pskb_copy_fclone() pospone el resto de los metadatos de shinfo a skb_copy_header() después de copiar los descriptores de fragmentos, pero dicha función auxiliar solo transfiere gso_{size,segs,type} y nunca toca skb_shinfo()->flags; skb_shift() mueve los descriptores de fragmentos directamente y deja las flags sin modificar. Como resultado, el skb de destino mantiene una referencia a las mismas páginas de propiedad externa o respaldadas por la caché de páginas, mientras que skb_has_shared_frag() devuelve false.
Esta discrepancia es perjudicial para cualquier escritor in situ que utilice skb_has_shared_frag() para decidir si las páginas compartidas deben desviarse a través de skb_cow_data(). La entrada ESP es uno de estos escritores (esp4.c, esp6.c), y una única regla nft 'dup to' (o cualquier otro llamador a nf_dup_ipv4() / xt_TEE) es suficiente para hacer que un skb copiado con pskb_copy() llegue a esp_input() con el marcador eliminado, permitiendo que un usuario sin privilegios escriba en la caché de páginas de un archivo de solo lectura propiedad de root mediante escrituras erróneas de authencesn-ESN.
Establecer SKBFL_SHARED_FRAG en el destino siempre que los descriptores de fragmentos se hayan movido realmente desde el origen. skb_copy() y skb_copy_expand() también comparten skb_copy_header(), pero linealizan todos los datos paginados en almacenamiento de cabecera recién asignado y emergen con nr_frags == 0, por lo que skb_has_shared_frag() devuelve false por sí mismo; no necesitan cambios.
La misma omisión existe en skb_gro_receive() y skb_gro_receive_list(). La primera mueve los descriptores de fragmentos del skb entrante al último sub-skb del acumulador a través de dos rutas (un bucle de movimiento directo de fragmentos y la ruta head_frag + memcpy); la segunda encadena el skb entrante completo en frag_list de p. skb_segment() posterior lee solo skb_shinfo(p)->flags, y skb_segment_list() reutiliza shinfo de cada sub-skb como nskb; tanto p como lp deben llevar el marcador.
La misma omisión también existe en tcp_clone_payload(), que construye un skb de prueba MTU moviendo descriptores de fragmentos de skbs en sk_write_queue a un nskb recién asignado. La función auxiliar pertenece a la misma familia y merece la misma corrección por consistencia; actualmente no se conoce ningún escritor in situ del lado de transmisión TCP que pueda acceder a una página de usuario a través de esta brecha, pero un consumidor futuro que dependa del marcador sufriría una regresión silenciosa.
La misma omisión existe en skb_segment(): la fusión de flags por iteración toma solo la flag de head_skb, y el interruptor interno que reasigna frag_skb a list_skb al agotarse los fragmentos de head_skb no incorpora la flag de frag_skb en nskb. Incorporar la flag de frag_skb en ambos sitios para que los segmentos que extraen fragmentos de los miembros de frag_list lleven el marcador.
If you want to get the best quality for vulnerability data then you always have to consider VulDB.