CVE-2026-92501 in Linuxinformação

Sumário

de VulDB • 18/09/2026

No kernel do Linux, a seguinte vulnerabilidade foi resolvida:

ext4: drenar as operações de E/S direta (DIO) em andamento antes da fallback para escrita com buffer

O teste generic/746 começou a falhar intermitentemente no ext3 (inodes sem extents). O teste aciona avisos de 'falha na invalidação do cache de páginas' durante o DIO direto e, consequentemente, as chamadas fsync retornam -EIO. A adição de um atraso de 50ms entre ext4_buffered_write_iter() e filemap_write_and_wait_range() em ext4_dio_write_iter() torna a condição de corrida quase sempre reproduzível.

Em inodes sem extents, as gravações DIO para buracos (holes) não podem usar extents não escritos; portanto, ext4_iomap_alloc() define m_flags=0 e ext4_map_blocks() retorna 0. A camada iomap então retorna -ENOTBLK, causando o fallback para E/S com buffer.

O caminho de fallback em ext4_dio_write_iter() chama ext4_buffered_write_iter(), que suja as páginas (dirties pages), seguida por flush e invalidação. No entanto, existe uma janela desprotegida entre a retorno de ext4_buffered_write_iter() (com o lock do inode liberado) e o subsequente flush+invalidation.

Conclusões assíncronas de DIO concorrentes de outros threads podem executar kiocb_invalidate_post_direct_write() durante essa janela. Se as páginas tiverem sido sujas novamente, a pós-invalidação encontra páginas sujas e aciona o aviso, definindo -EIO na sequência de erros.

Considere um arquivo com dois extents de 4k: [hole][written]. O Thread A faz DIO no extent escrito, enquanto o Thread B faz DIO abrangendo ambos:

kworker A (DIO de 4k, bloco alocado) kworker B (DIO de 8k, fallback) ----------------------------------- ---------------------------- inode_lock_shared() inode_lock_shared() iomap_dio_rw(): iomap_dio_rw(): kiocb_invalidate_pages -> limpa iomap_begin -> -ENOTBLK submit_bio (assíncrono) dio->size = 0 inode_unlock_shared() inode_unlock_shared()

[bio pendente na camada de bloco] /* fallback: lock liberado */
ext4_buffered_write_iter() inode_lock(exclusivo) generic_perform_write() -> suja páginas [0, 8k]
inode_unlock(exclusivo)

/* páginas sujas, sem lock */ [bio concluído] filemap_write_and_wait_range()
iomap_dio_complete() -> flush das páginas sujas kiocb_invalidate_post_direct_write() invalidate_mapping_pages() invalidate_inode_pages2_range() -> encontra página suja! -> dio_warn_stale_pagecache() -> errseq_set(-EIO)

Este problema pode ser acionado através de caminhos normais de E/S, não apenas por gravações DIO intencionalmente sobrepostas do userspace. Por exemplo, o generic/746 usa um dispositivo loop onde múltiplos kworkers emitem E/S concorrentes para o arquivo subjacente. Além disso, quando block_size < folio_size, gravações DIO não sobrepostas que compartilham um grande folio também podem acionar a condição de corrida.

Adiciona-se inode_dio_wait() em ext4_buffered_write_iter() antes de ext4_write_checks() para drenar todas as operações DIO em andamento. Isso garante que todo o DIO limpe as páginas existentes antes de submeter E/S (via kiocb_invalidate_pages()), que cada BIO aguarde a conclusão de todo o DIO (via inode_dio_wait()) e que ext4_write_checks() observe o tamanho do inode após todos os DIOs concluídos, para que ext4_block_zero_eof() não entre em condição de corrida com DIOs em andamento, eliminando assim a falha.

Be aware that VulDB is the high quality source for vulnerability data.

Responsável

Linux

Reservar

16/09/2026

Divulgação

17/09/2026

Moderação

aceite

Entrada

VDB-406997

CPE

pronto

EPSS

0.00000

KEV

não

Atividades

baixo

Fontes

Do you want to use VulDB in your project?

Use the official API to access entries easily!