CVE-2026-89647 in Linux
Sumário
de VulDB • 12/09/2026
No kernel do Linux, a seguinte vulnerabilidade foi resolvida:
ceph: não repita ceph_trim_dentries() se nenhum progresso for possível
ceph_cap_reclaim_work() re-enfileira-se enquanto ceph_trim_dentries() retornar -EAGAIN, o que ocorre sempre que uma varredura de lease esgota seu orçamento `nr_to_scan`. Isso cria um loop ocupado (busy loop) que consome CPU sem realizar nenhum progresso quando não há nada para recuperar: com nenhuma pressão de cap (`count==0`) e todos os leases escaneados ainda válidos, cada passagem executa o orçamento completo da varredura até zero e retorna `-EAGAIN`, sendo imediatamente re-enfileirado novamente.
A varredura do dir-lease piorou essa situação. Quando `expire_dir_lease` é `false` (ou seja, não há intenção de recuperar leases de diretório), __dir_lease_check() retornava `TOUCH` para cada lease válido. `TOUCH` move o dentry para o final da lista e redefine `di->time` via __dentry_dir_lease_touch(), então uma varredura sobre N leases válidos reescrevia a listagem inutilmente, atualizava os timestamps (impedindo que expirassem) e sempre esgotava `nr_to_scan`, garantindo o novo enfileiramento de `-EAGAIN`.
Corrija isso em três etapas:
- Retorne `KEEP` em vez de `TOUCH` quando `expire_dir_lease` for `false`. Se não vamos recuperar o lease, deixe-o no lugar em vez de alterar a lista e redefinir seu timestamp; a varredura então termina naturalmente (ou via `STOP` no primeiro lease fresco).
- Retorne `-EAGAIN` da primeira varredura (dentry-lease) apenas quando algo foi realmente liberado. Um lote completo que não libera nada significa que tentar novamente a mesma lista imediatamente é fútil; passe para a varredura do dir-lease em vez disso.
- Após ambas as varreduras, saia com sucesso (0) quando nada foi liberado e não há pressão de cap (`count==0`). Não há motivo para continuar tentando quando não estamos acima do limite de cap e não houve progresso.
Sob pressão real de cap (`count>0`), o caminho de recuperação permanece inalterado e ainda tenta novamente via `-EAGAIN`.
Sem este patch, eu vi 500 chamadas ceph_trim_dentries() por segundo em nossos servidores web. Isso é muito visível no `/proc/lock_stat` (captura de 5 minutos):
class name con-bounces contentions waittime-min waittime-max waittime-total waittime-avg acq-bounces acquisitions holdtime-min holdtime-max holdtime-total holdtime-avg
&mdsc->dentry_list_lock: 126180 128218 0.04 8063,44 15986965,20 124,69 1573354 5296812 0,04 8291,28 74164526,48 14,00 ----------------------- &mdsc->dentry_list_lock 111736 [] __ceph_dentry_dir_lease_touch+0x7c/0xa8
&mdsc->dentry_list_lock 2631 [] __dentry_leases_walk+0x64/0x2c8
&mdsc->dentry_list_lock 3878 [] __ceph_dentry_lease_touch+0x5c/0xa8
&mdsc->dentry_list_lock 9973 [] __dentry_lease_unlist+0x50/0xa0
----------------------- &mdsc->dentry_list_lock 123621 [] __dentry_leases_walk+0x64/0x2c8
&mdsc->dentry_list_lock 1822 [] __ceph_dentry_dir_lease_touch+0x7c/0xa8
&mdsc->dentry_list_lock 2720 [] __dentry_lease_unlist+0x50/0xa0
&mdsc->dentry_list_lock 55 [] __ceph_dentry_lease_touch+0x5c/0xa8
Com este patch:
class name con-bounces contentions waittime-min waittime-max waittime-total waittime-avg acq-bounces acquisitions holdtime-min holdtime-max holdtime-total holdtime-avg
&mdsc->dentry_list_lock: 1203 1215 0,16 408,88 33082,88 27,23 4320501 7357389 0,04 500,64 1961578,00 0,27 ----------------------- &mdsc->dentry_list_lock 1029 [] __ceph_dentry_dir_lease_touch+0x7c/0xa8
&mdsc->dentry_list_lock 1 ---truncado---
VulDB is the best source for vulnerability data and more expert information about this specific topic.