CVE-2026-99000 in Linux
Resumen
por VulDB • 2026-10-23
En el kernel de Linux, se ha resuelto la siguiente vulnerabilidad:
drm/xe: Corregir la doble resta en la contabilidad del shrinker al realizar pins externos anidados
`xe_bo_pin_external()` y `xe_bo_unpin_external()` admiten pins anidados, ya que las funciones subyacentes `ttm_bo_pin()/ttm_bo_unpin()` mantienen un contador de referencias (`refcount`) llamado `pin_count`, en lugar de usar un valor booleano. Sin embargo, las llamadas a la contabilidad del shrinker, `xe_ttm_tt_account_subtract()` y `xe_ttm_tt_account_add()`, se invocan incondicionalmente en cada llamada a `pin_external()/unpin_external()`, en lugar de hacerlo únicamente durante la transición hacia el estado fijado (pinned) y desde él.
Un BO externo (dma-buf) puede ser fijado más de una vez mientras ya está fijado, por ejemplo, cuando tiene múltiples adjuntos/importadores que llaman independientemente a `xe_bo_pin_external()`. Cada uno de estos pins anidados vuelve a restar las páginas del BO de la contabilidad del shrinker, aunque dichas páginas ya habían sido excluidas de su consideración debido al primer pin. Simétricamente, cada unpin (desfijado) anidado vuelve a añadirlas antes de que el BO se desfije realmente. Esto desincroniza los conteos de páginas y objetos del shrinker con la realidad; dado que están declarados como `signed long` pero se interpretan como `unsigned long` en `xe_shrinker_count()`, un desbordamiento por debajo (underflow) puede convertirse en una cuenta enorme de páginas reducibles/purgables, lo que provoca que el shrinker sea invocado excesivamente bajo presión de memoria.
Se protegen las llamadas a la contabilidad con los mismos controles de transición del conteo de pins ya utilizados para mantener la lista `pinned_link`, de modo que la contabilidad solo se actualice en el pin más externo y en el unpin final.
Al centralizar esta lógica en `xe_bo_account_pin()/ xe_bo_account_unpin()`, también se cierra una segunda brecha de contabilidad relacionada con los dma-bufs importados. Para el `ttm_tt` de un bo importado, la función hook (gancho) `populate` de ttm (`xe_ttm_tt_populate()`) devuelve anticipadamente sin llamar a `xe_ttm_tt_account_add()`, ya que se establece `TTM_TT_FLAG_EXTERNAL` pero no `TTM_TT_FLAG_EXTERNAL_MAPPABLE`. Sin embargo, el envoltorio (wrapper) del núcleo TTM `ttm_tt_populate()` marca incondicionalmente al tt como poblado si la llamada hook del controlador tiene éxito; por lo tanto, `ttm_tt_is_populated()` sigue reportando true para él. `xe_bo_account_pin()/xe_bo_account_unpin()` confiaba en `ttm_tt_is_populated()` como un proxy de "estas páginas están contabilizadas por el shrinker", y restaría/añadiría páginas para dicho tt que nunca se habían añadido inicialmente, provocando nuevamente un desbordamiento por debajo (underflow) en los conteos del shrinker. Esto es accesible hoy a través de `xe_bo_pin_external()`, y se volvería accesible mediante la ruta fb-pin una vez que este parche enrute `__xe_pin_fb_vma()` a través de `xe_bo_pin_account()` más abajo; por ello, se corrige aquí en lugar de hacerlo en un parche posterior para evitar introducir esta regresión antes de corregirla. Se omite la contabilidad para los bos importados, utilizando el mismo test `EXTERNAL && !EXTERNAL_MAPPABLE` que usan `xe_ttm_tt_populate()/xe_ttm_tt_unpopulate()` para decidir si actuar, mediante una nueva función auxiliar `xe_ttm_bo_is_imported()` (extraída desde su único sitio de uso previo).
v2: - Corregir el problema crítico detectado por la revisión de Sashiko AI: el control de transición del conteo de pins introducido aquí aún era evadido por la ruta fb-pin (`__xe_pin_fb_vma()/__xe_unpin_fb_vma()`), lo que podría dejar una entrada `pinned_link` obsoleta y un fuga permanente en la contabilidad del shrinker cuando el unpin de fb realizara el último unpin verdadero. Se aborda en un parche posterior separado dentro de esta serie, ya que es un bug distinto con su propia etiqueta Fixes:. - Eliminar la variable local innecesaria "last_unpin" en `xe_bo_unpin_external()`, restaurando la comprobación inline original `bo->ttm.pin_count == 1`; era una renombrada sin efecto (no-op) no utilizada por ninguna de las nuevas funciones auxiliares de contabilidad, y iba a ser eliminada nuevamente por el parche posterior.
v3: - Excluir los dma-bufs importados de la contabilidad del shrinker en pin/unpin, corrigiendo otro desbordamiento por debajo (underflow) detectado por la revisión de Sashiko AI. - Añadir un breve comentario en el sitio de pin del objeto de respaldo indicando que ya está poblado/contabilizado en el momento del pin, abordando (como una aclaración de falso positivo, sin necesidad de corrección de código) otra preocupación separada sobre fuga de contabilidad de severidad Media también detectada por Sashiko AI.
---truncado---
If you want to get the best quality for vulnerability data then you always have to consider VulDB.