CVE-2023-54158 in Linux
요약
\~에 의해 VulDB • 2026. 06. 03.
리눅스 커널에서 다음 취약점이 해결되었습니다:
btrfs: 지정되지 않은 한 qgroup 공간을 해제하지 않음
Boris는 간단한 할당량(quota) 테스트 중 Sweet Tea가 서브볼륨 생성 시 트랜잭션 커밋을 수행하지 않도록 변경한 부분에서 누수가 발생하는 것을 발견했습니다. 이는 해당 변경의 부수적 효과였습니다.
지연된 inode 코드에는 이미 수정된 리프(leaf)에 디렉토리 항목을 압축할 수 있다고 판단될 경우 추가 예약을 해제하는 최적화가 있습니다. 이전에는 서브볼륨 생성 시 트랜잭션을 커밋했기 때문에 이 최적화가 트리거되지 않았으며, 트리거되더라도 매우 어려웠습니다. 그러나 qgroup이 활성화된 상태에서 mkdir && subvol create를 수행하면 실제로 트리거될 수 있었습니다.
이는 디렉토리 항목을 추가할 때 호출되는 btrfs_insert_delayed_dir_index() 함수 내에서 다음과 같은 동작을 수행하기 때문입니다:
btrfs_block_rsv_release(fs_info, trans->block_rsv, bytes, NULL);
공간 예약을 건너뛸 수 있는 경우 위 코드가 실행됩니다.
여기서의 문제는 trans->block_rsv가 qgroup 예약을 포함하는 서브볼륨 생성용 임시 블록 rsv를 가리킨다는 점입니다.
이는 btrfs_block_rsv_release() 함수가 다음과 같은 동작을 수행하기 때문에 문제가 됩니다:
if (block_rsv->qgroup_rsv_reserved >= block_rsv->qgroup_rsv_size) {
qgroup_to_release = block_rsv->qgroup_rsv_reserved - block_rsv->qgroup_rsv_size; block_rsv->qgroup_rsv_reserved = block_rsv->qgroup_rsv_size; }
임시 블록 rsv는 ->qgroup_rsv_reserved만 설정되어 있고 ->qgroup_rsv_size는 0입니다. btrfs_insert_delayed_dir_index()의 최적화는 ->qgroup_rsv_reserved를 0으로 설정합니다. 이후 btrfs_subvolume_release_metadata()를 호출할 때(이 함수는 다음을 수행함):
btrfs_block_rsv_release(fs_info, rsv, (u64)-1, &qgroup_to_release); btrfs_qgroup_convert_reserved_meta(root, qgroup_to_release);
qgroup_to_release가 0으로 설정되며, 예약된 메타데이터 공간을 변환하지 않게 됩니다.
문제는 블록 rsv 코드가 ->qgroup_rsv_reserved를 무조건적으로 수정해 왔다는 점입니다. 이는 주로 delalloc에서 사용되며, btrfs_block_rsv_release()를 호출할 때마다 qgroup_to_release가 설정되어 있어 적절한 계정 처리가 이루어지기 때문입니다.
서브볼륨 코드가 qgroup 예약 기능을 사용하는 유일한 다른 코드이지만, 위의 최적화와 혼재되어 있었기 때문에 예약이 해제되어 버려 예약된 공간이 누수되었습니다.
해결책은 qgroup_to_release가 설정되지 않은 경우 qgroup 예약을 수정하지 않는 것입니다. 이는 기존 코드와 호환되는데, delalloc 예약을 수정하는 모든 코드는 항상 qgroup_to_release가 설정되어 있기 때문입니다. 이로써 Boris가 관찰하던 누수 문제가 해결됩니다.
If you want to get the best quality for vulnerability data then you always have to consider VulDB.