🇰🇷 한글 설명
Linux 커널의 FUSE 파일 시스템에서 O_APPEND 모드로 직접 쓰기(Direct Write)를 수행할 때, 데이터 무결성 오류가 발생할 수 있는 취약점입니다. 쓰기 작업 후 잘못된 데이터 범위를 무효화(invalidate)하여, 파일 크기가 페이지 단위로 정렬되지 않은 경우 실제 데이터 대신 오래된(stale) 데이터를 읽게 될 수 있습니다.
💡 쉬운 설명
파일 끝에 데이터를 추가할 때, 컴퓨터가 데이터가 저장된 위치를 잘못 계산하여 실제 데이터가 아닌 옛날 데이터를 보여줄 수 있는 문제입니다. 이로 인해 파일 내용이 깨지거나 잘못된 정보가 읽힐 위험이 있습니다.
🇺🇸 원문 (English)
In the Linux kernel, the following vulnerability has been resolved:
fuse: invalidate the correct range after O_APPEND direct write
fuse_direct_write_iter() captures pos before generic_write_checks(),
which moves ki_pos to EOF for O_APPEND writes:
fuse_direct_write_iter()
{
pos = iocb->ki_pos; /* 0 (user-supplied) */
generic_write_checks(); /* ki_pos -> EOF */
fuse_direct_io(); /* writes at EOF, correct */
invalidate(pos, pos + res); /* [0, res) -- wrong */
}
The post-write invalidation targets a stale range instead of the
actual written range at EOF.
This can cause data inconsistency when the file size is not
page-aligned. The tail page straddling EOF has a valid portion
before EOF that concurrent readers can fault back in during the
DIO write window:
Tail page (file size X not page-aligned):
page_start X (EOF) page_end
|--- valid data ----|-- stale --|
CPU0 (O_APPEND DIO writer) CPU1 (buffered reader)
-------------------------- ----------------------
invalidate [X, X+len)
tail page evicted
FUSE_WRITE in flight ...
read [page_start, X)
tail page re-faulted
[X, page_end) = stale
FUSE_WRITE completes
i_size = X + len
invalidate [0, len) <- WRONG
tail page still cached
read [X, X+len)
hits stale tail page
returns old data
Fix by reading pos back from iocb->ki_pos after generic_write_checks(),
as generic_file_direct_write() does.
Also fix a typo in the comment ("may have" -> "may have competed").
📍 영향받는 시스템
FUSE를 사용하는 Linux 커널 버전 (패치 적용 전)
⚔️ 공격 벡터
O_APPEND 플래그를 사용한 직접 I/O 쓰기 작업을 통해 데이터 불일치 유도
🛡️ 대응 방법
Linux 커널을 최신 보안 패치가 적용된 버전으로 업데이트
🔧 검증 코드
출력된 커널 버전이 해당 취약점이 수정된 최신 패치 버전인지 확인