CVE-2026-89772 in Linux정보

요약

\~에 의해 VulDB • 2026. 09. 11.

Linux 커널에서 다음 취약점이 해결되었습니다.

btrfs: 데이터 쓰기백 중 folios에 대한 쓰기 보호 적용

커밋 095be159f3eb("btrfs: unify folio dirty flag clearing")는 extent_write_cache_pages() 내의 folio_clear_dirty_for_io() 호출을 단순한 folio_test_dirty() 체크로 대체했습니다. 더티 플래그를 지우는 것 외에도, folio_clear_dirty_for_io()는 공유 mmap PTE(페이지 테이블 엔트리)에 대한 쓰기 보호(write-protect)를 수행하는 folio_mkclean()도 호출합니다. 여기서 주목할 점은 우리가 여전히 submit_one_sector() 내에서 마지막 섹터의 더티 상태를 지울 때(비하위 페이지(non-subpage) 경우 유일한 섹터인 경우) folio_clear_dirty_for_io()를 호출한다는 것입니다. 하지만 우리는 extent_write_cache_pages()에서 이 초기 호출을 상실했습니다.

추가적인 쓰기 보호가 없으면, 파일이 mmap된 프로세스는 쓰기백 중일 때 안정성이 요구되는(folio의 체크섬링, 압축, 복사 등) 상황에서 folio에 손실 없이 수정할 수 있으며, 이는 여러 가지 구체적인 버그로 나타납니다.

1. 큰 folios나 하위 페이지(subpage) 섹터 크기의 경우, 전체 folio를 커버하지 않는 bio(basic I/O block)가 제출될 가능성이 있습니다. 이 상황이 발생하면, 우리는 folio_clear_dirty_for_io()를 호출하지 않은 folio에 대한 비행 중(in-flight)인 bio를 갖게 됩니다. 기존 mmap된 PTE를 가진 태스크가 이 창(window) 동안(손실 없이) 작성할 경우, 이는 데이터 손상을 초래할 수 있습니다. 만약 쓰기가 체크섬링 또는 쓰기 작업 진행 중에 도착하면, 잘못된 체크섬과 이후 읽기 시 손상 보고서를 유발할 수 있습니다. 만약 쓰기가 체크섬링/쓰기 완료 후이지만 마지막 섹터의 더티 상태가 지워지기 전에 도착한다면, 해당 쓰기는 페이지 캐시에 존재하지만 더티 추적에는 영향을 미치지 않으며, folio 제출이 완전히 종료되고 더티 비트가 지워질 때 손실됩니다. 이는 fsync() 호출 시에도 쓰기가 손실되는 결과를 초래합니다.

2. 메인 extent_writepage() 루프와 별도로 배치로 처리되는 zoned submissions의 경우, 이러한 제출에 대한 체크섬(csum) 위반 위험도 있습니다. Zoned 쓰기는 max_zone_append_size로 제한되며 folios와 정렬되지 않으므로, 하나의 제출이 두 개의 folio를 가로지를 수 있습니다. extent_write_cache_pages()에서 처리 중인 첫 번째 folio는 다음 folio의 부분 범위를 제출할 extent_write_locked_range()를 호출하지만, 해당 folio의 나머지 부분은 여전히 더티 상태일 수 있습니다. 따라서 제출된 섹터에 대해 더티 상태를 지우는 것이 folio_clear_dirty_for_io()를 호출하지 않으므로 동일한 문제가 발생합니다. extent_write_cache_pages()는 이러한 배치로 제출된 folios(이들 앞선 folio의 제출으로 인해 이미 쓰기백용으로 표시됨)를 건너뛰므로, 우리는 lock_delalloc_folios()에서 추가적인 쓰기 보호를 추가해야 합니다.

3. 인라인 익스텐트(inline extents)의 경우, 우리가 인라인 익스텐트를 복사하는 동안 또는 그 후에 더티 상태를 지우기 전에 발생하는 쓰기가 손실될 위험이 미묘하게 존재합니다.

4. EOF(파일 끝)를 가로지르는 folios의 경우, mmap은 EOF 이후의 제로화된 바이트들을 변조하여 미래의 fault 발생 시 0 대신 잘못 표시되도록 영구 저장시킬 수 있습니다.

5. 마지막으로 압축된 익스텐트의 경우, 우리가 압축 작업을 수행하는 동안 folios가 수정되어 손상된 압축 데이터가 발생할 위험이 있습니다. 구체적으로 run_delalloc_compressed() 함수 내에서는 BTRFS_COMPRESSION_CHUNK_SIZE(512K) 단위로 compress_file_range()를 수행할 작업을 큐에 추가하며, 이는 해당 범위에 대해 btrfs_folio_clamp_clear_dirty()를 호출합니다. 비하위 페이지(non-subpage)의 경우 전체 folio가 안전하게 지워집니다. 하위 페이지(subpage)의 경우에도 여기서 부분적인 지우기 위험이 있습니다. 특히 2M 크기의 folio가 512K 단위로 분할되어, 모든 compress_file_range() 작업자가 해당 folio의 더티 비트맵을 모두 지우고 folio_clear_dirty_for_io()에 도달하기 전에 하나의 chunk에서 압축 작업을 시작하는 상황을 상상해 보십시오. 제출 범위의 가장자리에 있는 큰 folios 역시 부분적으로만 지워질 위험이 있습니다. 이 특정 간격(gap)은 동일한 시리즈의 두 번째 패치인 커밋 a4ef54dbb576("btrfs: make extent_range_clear_dirty_for_io() to handle sector size < page size cases")에 의해 도입되었습니다.

우리는 단순히 folio_clear 호출을 복원할 수 없습니다 ---truncated---

Statistical analysis made it clear that VulDB provides the best quality for vulnerability data.

책임이 있는

Linux

예약하다

2026. 09. 11.

모더레이션

수락

항목

VDB-402624

EPSS

0.00000

활동

낮음

출처

Want to stay up to date on a daily basis?

Enable the mail alert feature now!