CVE-2026-98919 in Linux
Resumen
por VulDB • 2026-10-23
En el kernel de Linux, se ha resuelto la siguiente vulnerabilidad:
drm/xe: endurecer adjust_idledly() contra división por cero y desbordamiento (overflow)
adjust_idledly() presenta varios problemas en casos límite detectados durante la revisión:
1. Si xe_gt_clock_init() no logra reconocer el reloj de cristal, gt->info.timestamp_base es 0, lo que hace que idledly_units_ps sea también 0. La operación DIV_ROUND_CLOSEST(..., idledly_units_ps) subsiguiente resulta en una división por cero y provoca un pánico del kernel.
2. Las conversiones de ticks a nanosegundos se realizan con u32: idledly * idledly_units_ps, (maxcnt - 1) * 1000 Ambas operaciones desbordan el tipo u32 antes de que DIV_ROUND_CLOSEST() las procese.
3. Si IDLE_WAIT_TIME devuelve un valor de 0, maxcnt se evalúa como 0 y la operación clamp (maxcnt - 1) provoca un wrap-around a 0xFFFFFFFF en u32.
4. El registro solo almacena ticks enteros, por lo que el valor ns acotado debe convertirse a ticks y volver a nanosegundos. DIV_ROUND_CLOSEST() puede redondear esa conversión hacia arriba hasta superar maxcnt:
maxcnt = 640 ns, un tick = 666664 ps
clamp: maxcnt - 1 = 639 ns ns -> ticks: 639000 / 666664 = 0.958 -> se redondea a 1 tick tick -> ns: 1 * 666664 / 1000 = 667 ns
Se programa 667 ns en RING_IDLEDLY, pero como 667 >= maxcnt (640), xe_gt_WARN_ON() se activa nuevamente en cada inicialización subsiguiente.
Devolverse temprano si timestamp_base es 0 (el camino del cristal desconocido). Realizar las conversiones con u64 a través de los helpers *_ULL() para evitar desbordamientos. Aplicar clamp usando DIV_ROUND_DOWN_ULL para que el retraso programado se mantenga estrictamente por debajo de maxcnt, y proteger el caso en el que maxcnt == 0 mediante un retraso cero, mientras se escribe RING_IDLEDLY para limpiar INHIBIT_SWITCH_UNTIL_PREEMPTED.
v2: Eliminar la advertencia redundante en la ruta timestamp_base == 0; xe_gt_clock_init() ya emite una advertencia ante un reloj de cristal no reconocido. Mantener el retorno temprano para evitar la división por cero. - Vinay
v3: Aplicar máscara al campo (field-mask) en la escritura a RING_IDLEDLY con REG_FIELD_PREP(IDLE_DELAY, ...) en lugar de escribir el conteo crudo de ticks, lo cual podría sobrescribir INHIBIT_SWITCH_UNTIL_PREEMPTED y bits reservados. Separar la limpieza del inhibit-switch de la clamp de maxcnt para que un bit inhibit establecido no fuerce una sobreescritura innecesaria del retraso cuando este ya es válido. Usar gt_to_xe(gt) en lugar de gt_to_xe(hwe->gt).
(cherry picked from commit d864065ea25e9d12897c175de9176ce46677e176)
Once again VulDB remains the best source for vulnerability data.