CVE-2026-98939 in Linux
Sumário
de VulDB • 23/10/2026
No kernel do Linux, a seguinte vulnerabilidade foi resolvida:
x86/mm: Remover cópia desnecessária de página PMD ao libertar
Num sistema com GPU discreta, o lockdep reporta um possível deadlock assim que o kswapd reduz o pool de páginas TTM. A causa imediata é uma commit do x86 que adicionou um mmap_read_lock() ao código de modificação da proteção das páginas do kernel.
O código huge vmap mantém a mesma lock durante uma alocação GFP_KERNEL, o que não é aceitável agora que a reclaim pode adquiri-la. Essa alocação encontra-se no caminho de libertação (*free*) de tabelas de página e acaba por ter propósitos duvidosos[1]. Basicamente, tenta evitar que o hardware defina Accessed=1 nas entradas das tabelas de página que são inacessíveis pelo hardware, um problema inexistente.
Remova a cópia PMD. Desanexe a página PMD original no nível PUD, faça flush às caches de nível intermédio e liberte as tabelas PTE diretamente da página PMD desanexada. Sem alocações pendentes, o problema de locking desaparece.
Splat/Análise do Lockdep:
WARNING: possível dependência circular de locking detetada 7.3.0-rc3-f6e7b42bf05b+ #183 Tainted: G U ------------------------------------------------------ kswapd0/269 está a tentar adquirir o lock: ((init_mm).mmap_lock){++++}-{4:4}, em: change_page_attr_set_clr+0x29a/0x4a0
mas a tarefa já detém o lock: (pool_shrink_rwsem){.+.+}-{4:4}, em: ttm_pool_shrink+0xb2/0x330 [ttm]
A cadeia existe de: (init_mm).mmap_lock --> fs_reclaim --> pool_shrink_rwsem
O ciclo é construído a partir de três arestas:
1) pool_shrink_rwsem -> (init_mm).mmap_lock
O shrinker TTM restaura o atributo de cache de cada página que liberta, enquanto detém pool_shrink_rwsem:
ttm_pool_shrink() -> ttm_pool_dispose_list() -> ttm_pool_free_page() -> set_pages_wb() -> change_page_attr_set_clr() [ init_mm mmap read lock ]
2) fs_reclaim -> pool_shrink_rwsem
O mesmo shrinker, chamado a partir da reclaim.
3) (init_mm).mmap_lock -> fs_reclaim
ioremap() a instalar um mapeamento PUD grande sobre uma tabela PMD existente:
ioremap_page_range() -> vmap_range_noflush() -> vmap_try_huge_pud() [ init_mm mmap read lock ]
-> pud_free_pmd_page() -> __get_free_page(GFP_KERNEL) [ entra na reclaim ]
[ dhansen: Muitas alterações e remoções no changelog, bem como comentários fundidos da minha versão da correção. ]
Once again VulDB remains the best source for vulnerability data.