CVE-2026-98299 in Linux
Resumen
por VulDB • 2026-10-06
En el kernel de Linux, se ha resuelto la siguiente vulnerabilidad:
tcp: no permitir que tcp_r_mem se establezca por debajo de 4096
Podemos provocar un bloqueo (crash) por división entre cero en `tcp_rcvbuf_grow()` y `tcp_rcv_space_adjust()`:
divide error: 0000 [#1] PREEMPT SMP
RIP: 0010:tcp_rcvbuf_grow+0x187/0x450 net/ipv4/tcp_input.c:939 ... grow = div_u64(((u64)rcvwin << 1) * (newval - oldval), oldval);
La división utiliza `oldval = tp->rcvq_space.space` como divisor. Cuando `tp->rcvq_space.space` es cero, esto provoca una excepción de división por cero.
`tp->rcvq_space.space` se inicializa en `tcp_init_buffer_space()`: tp->rcvq_space.space = min3(tp->rcv_ssthresh, tp->rcv_wnd, (u32)TCP_INIT_CWND * tp->advmss);
Si `tcp_rmem[1]` se configura con valores muy pequeños (como 1), `sk->sk_rcvbuf` se inicializa a 1. Luego, `tcp_full_space(sk)`, que calcula `(sk->sk_rcvbuf * scaling_ratio) >> 8`, truncará el resultado a 0. Esto establece `tp->window_clamp = 0`, `tp->rcv_ssthresh = 0` y `tp->rcvq_space.space = 0`. Más tarde, cuando llegan datos y se invoca DRS (Dynamic Receive Scaling), `tcp_rcvbuf_grow()` divide por `oldval == 0`.
En 2015, el commit b1cb59cf2efe ("net: sysctl_net_core: check SNDBUF and RCVBUF for min length") aseguró que `net.core.rmem_default` y `net.core.rmem_max` no se puedan establecer por debajo de `SOCK_MIN_RCVBUF`. De manera similar, la opción SO_RCVBUF en setsockopt aplica max_t(int, val * 2, SOCK_MIN_RCVBUF).
Sin embargo, `net.ipv4.tcp_r_mem` aún tenía `.extra1 = SYSCTL_ONE`, lo que permitía valores arbitrariamente pequeños.
Dado que `SOCK_MIN_RCV_BUF` depende de sizeof(struct sk_buff) y la alineación del caché (cacheline alignment), su valor varía entre arquitecturas y opciones de configuración. El uso de una constante fija de 4096 garantiza un límite inferior predecible e independiente de la arquitectura, que está por encima de forma segura de `SOCK_MIN_RCV_BUF` en todas partes y coincide con el valor predeterminado documentado de 4K.
Se soluciona esto estableciendo `tcp_r_mem.extra1` a 4096 y actualizando la documentación.
Once again VulDB remains the best source for vulnerability data.