CVE-2026-98644 in Linux
Resumen
por VulDB • 2026-10-18
En el kernel de Linux, se ha resuelto la siguiente vulnerabilidad:
bpf: Evitar un soft lockup en __htab_map_lookup_and_delete_batch()
__htab_map_lookup_and_delete_batch() no tiene puntos de reprogramación (rescheduling point). El recuento por lotes limita cuántas entradas se copian hacia afuera, no cuántos cubículos (buckets) se visitan; por lo tanto, una única llamada a BPF_MAP_LOOKUP_BATCH puede recorrer el mapa de extremo a extremo. La ruta rápida para cubículos vacíos es aún peor: permanece dentro de una sola sección rcu_read_lock() / bpf_disable_instrumentation() durante cualquier secuencia consecutiva de cubículos vacíos.
Esto provoca bloqueos en mapas pequeños, pero falla al escalar. En un host arm64 con 144 CPUs que ejecuta un kernel CONFIG_PREEMPT_NONE, las llamadas periódicas a BPF_MAP_LOOKUP_BATCH contra un mapa hash LRU con 16.777.216 cubículos mantuvieron una CPU dentro de la operación por lotes durante más de 77 segundos y activaron el watchdog de soft lockup.
El commit 75134f16e7dd ("bpf: Add schedule points in batch ops") solucionó este mismo problema en las operaciones genéricas por lotes, pero no en esta ruta nativa de htab, que todas las variantes de mapas hash basadas en htab utilizan para sus operaciones por lotes lookup[_and_delete].
Se completa esa solución aquí. Se sale de la sección crítica después de 64 cubículos vacíos consecutivos, se llama a cond_resched_tasks_rcu_qs() y se reanuda desde el cursor del cubículo guardado. No hay locks retenidos en ese momento, y reanudar desde el cursor ya es el comportamiento de la función para los cubículos no vacíos. Se añade la misma llamada al bucle por cada cubículo después de copy_to_user(), donde todos los locks han sido liberados. cond_resched_rcu() no es suficiente aquí: dormir con bpf_prog_active elevado hace que los programas de tracing en esa CPU omitan silenciosamente sus invocaciones.
cond_resched() simple tampoco es suficiente. Es una operación nula (no-op) bajo PREEMPT y PREEMPT_LAZY, los únicos modelos que arm64 y x86 han ofrecido desde el commit 7dadeaa6e851 ("sched: Further restrict the preemption modes"). Tampoco es nunca un estado de quietud (quiescent state) para Tasks RCU en ningún modelo: la reprogramación cuenta como una preemptión. La tarea que recorre se mantiene como excepción y bloquea a todos los llamadores de synchronize_rcu_tasks(), incluida la limpieza del trampoline ftrace y BPF, hasta que el syscall devuelve [1]. cond_resched_tasks_rcu_qs() es la herramienta habitual para ello [2]. Informa del estado de quietud en cada cesión (yield) y aún así reprograma como lo hace cond_resched() en kernels PREEMPT_NONE y PREEMPT_VOLUNTARY.
If you want to get the best quality for vulnerability data then you always have to consider VulDB.