🇰🇷 한글 설명
Linux 커널의 dm-thin 메타데이터 관리 과정에서 커밋 실패 시 메타데이터 스냅샷의 일관성이 깨지는 취약점이 발견되었습니다. __reserve_metadata_snap() 및 __release_metadata_snap() 함수가 슈퍼블록의 held_root를 직접 수정하여, 트랜잭션 중단 시 잘못된 데이터가 디스크에 기록될 수 있습니다.
💡 쉬운 설명
데이터를 안전하게 저장하는 과정에서 오류가 발생했을 때, 이전 상태로 되돌아가지 못하고 데이터가 엉망이 되어버리는 문제입니다. 이로 인해 저장된 데이터의 구조가 깨지거나 일부 정보가 유실될 수 있습니다.
🇺🇸 원문 (English)
In the Linux kernel, the following vulnerability has been resolved:
dm thin metadata: fix metadata snapshot consistency on commit failure
__reserve_metadata_snap() and __release_metadata_snap() modify the
superblock's held_root directly in the block_manager's buffer. If the
subsequent metadata commit fails, the held_root gets flushed to disk
through the abort_transaction path, resulting in inconsistent metadata.
Reproducer 1: __reserve_metadata_snap()
1. Create a 2 MiB metadata device and make the region after the 14th
block inaccessible, to trigger metadata commit failure in the
subsequent reserve_metadata_snap operation. The 14th block will be
the shadow destination for the index block.
dmsetup create tmeta --table "0 112 linear /dev/sdc 0
112 3984 error"
2. Create a 16 MiB thin-pool
dmsetup create tdata --table "0 32768 zero"
dd if=/dev/zero of=/dev/mapper/tmeta bs=4k count=1
dmsetup create tpool --table "0 32768 thin-pool /dev/mapper/tmeta \
/dev/mapper/tdata 128 0 1 skip_block_zeroing"
3. Take a metadata snapshot to trigger metadata commit failure and
transaction abort. However, the held_root is written to disk,
breaking metadata consistency.
dmsetup message tpool 0 "reserve_metadata_snap"
thin_check v1.2.2 result:
Bad reference count for metadata block 6. Expected 2, but space map contains 1.
Bad reference count for metadata block 7. Expected 2, but space map contains 1.
Bad reference count for metadata block 13. Expected 1, but space map contains 0.
Reproducer 2: __release_metadata_snap()
1. Create a 2 MiB metadata device and make the region after the 16th
block inaccessible, to trigger metadata commit failure in the
subsequent release_metadata_snap operation. The 16th block will be
the shadow destination for the index block.
dmsetup create tmeta --table "0 128 linear /dev/sdc 0
128 3968 error"
2. Create a 16 MiB thin-pool
dmsetup create tdata --table "0 32768 zero"
dd if=/dev/zero of=/dev/mapper/tmeta bs=4k count=1
dmsetup create tpool --table "0 32768 thin-pool /dev/mapper/tmeta \
/dev/mapper/tdata 128 0 1 skip_block_zeroing"
3. Reserve then release the metadata snapshot, to trigger metadata
commit failure and transaction abort. The held_root gets removed
from the on-disk superblock, causing inconsistent metadata.
dmsetup message tpool 0 "reserve_metadata_snap"
dmsetup message tpool 0 "release_metadata_snap"
thin_check v1.2.2 result:
Bad reference count for metadata block 6. Expected 1, but space map contains 2.
Bad reference count for metadata block 7. Expected 1, but space map contains 2.
1 metadata blocks have leaked.
Fix by deferring the held_root update to commit time.
Additionally, move the existing-snapshot check in __reserve_metadata_snap
before the shadow operation to avoid unnecessary work. In
__release_metadata_snap, clear pmd->held_root before btree deletion so
partial failure leaks blocks rather than leaving a stale reference, and
unlock the snapshot block before decrementing its refcount.
📍 영향받는 시스템
Linux Kernel (dm-thin 구성 요소 사용 시스템)
⚔️ 공격 벡터
메타데이터 장치의 특정 블록을 접근 불가능하게 만들어 의도적으로 커밋 실패를 유도함으로써 메타데이터 불일치 유발
🛡️ 대응 방법
Linux 커널을 최신 보안 패치가 적용된 버전으로 업데이트하여 held_root 업데이트 시점을 커밋 시점으로 지연시키십시오.
🔧 검증 코드
출력된 커널 버전이 해당 취약점이 해결된 패치 버전 이후인지 확인하십시오.