🇰🇷 한글 설명
리눅스 커널의 fsdax 구성에서 dax_unshare_iter 함수가 데이터 블록을 정렬되지 않은 상태로 복사하여 데이터 무결성을 파괴하고 잘못된 위치에 데이터를 기록할 수 있습니다. 또한, 페이지 경계 정렬 문제로 인해 전체 블록을 복사하지 못해 이전의 영구 메모리(pmem) 내용이 노출되는 데이터 기밀성 침해 문제가 발생합니다.
💡 쉬운 설명
파일의 데이터를 복사할 때 데이터의 위치를 정확히 맞추지 못해 엉뚱한 곳에 데이터를 쓰거나, 지워져야 할 옛날 데이터가 그대로 노출될 수 있는 보안 결함입니다. 이로 인해 중요한 정보가 유출되거나 파일 내용이 망가질 위험이 있습니다.
🇺🇸 원문 (English)
In the Linux kernel, the following vulnerability has been resolved:
fsdax: dax_unshare_iter needs to copy entire blocks
The code that copies data from srcmap to iomap in dax_unshare_iter is
very very broken, which bfoster's recent fsx changes have exposed.
If the pos and len passed to dax_file_unshare are not aligned to an
fsblock boundary, the iter pos and length in the _iter function will
reflect this unalignment.
dax_iomap_direct_access always returns a pointer to the start of the
kmapped fsdax page, even if its pos argument is in the middle of that
page. This is catastrophic for data integrity when iter->pos is not
aligned to a page, because daddr/saddr do not point to the same byte in
the file as iter->pos. Hence we corrupt user data by copying it to the
wrong place.
If iter->pos + iomap_length() in the _iter function not aligned to a
page, then we fail to copy a full block, and only partially populate the
destination block. This is catastrophic for data confidentiality
because we expose stale pmem contents.
Fix both of these issues by aligning copy_pos/copy_len to a page
boundary (remember, this is fsdax so 1 fsblock == 1 base page) so that
we always copy full blocks.
We're not done yet -- there's no call to invalidate_inode_pages2_range,
so programs that have the file range mmap'd will continue accessing the
old memory mapping after the file metadata updates have completed.
Be careful with the return value -- if the unshare succeeds, we still
need to return the number of bytes that the iomap iter thinks we're
operating on.
📍 영향받는 시스템
fsdax(Direct Access) 기능을 사용하는 리눅스 커널 시스템
⚔️ 공격 벡터
정렬되지 않은 파일 오프셋(pos)과 길이(len)를 이용한 dax_file_unshare 호출을 통한 데이터 오염 및 정보 유출
🛡️ 대응 방법
리눅스 커널을 최신 보안 패치가 적용된 버전으로 업데이트하여 dax_unshare_iter의 블록 정렬 및 페이지 무효화 로직을 수정해야 합니다.
🔧 검증 코드
출력된 커널 버전을 확인하여 해당 취약점이 해결된 패치 버전 이상인지 확인합니다.