🔍 CVE-2021-46989

7.1
CVSS Score
HIGH
2024-02-28
2026-08-04 10:16
✅ 완료

🇰🇷 한글 설명

Linux 커널의 hfsplus 파일 시스템에서 파일 크기를 줄이는 truncate 작업 시 데이터 손상이 발생할 수 있는 취약점입니다. 특정 조건에서 extent 레코드가 잘못 삭제되어 파일 시스템의 데이터가 유실되거나 손상될 수 있습니다.

💡 쉬운 설명

파일의 크기를 줄이는 과정에서 컴퓨터가 실수로 파일의 중요한 정보를 통째로 지워버리는 버그입니다. 이로 인해 저장된 데이터가 사라지거나 파일 시스템이 망가질 수 있습니다.

🇺🇸 원문 (English)

In the Linux kernel, the following vulnerability has been resolved: hfsplus: prevent corruption in shrinking truncate I believe there are some issues introduced by commit 31651c607151 ("hfsplus: avoid deadlock on file truncation") HFS+ has extent records which always contains 8 extents. In case the first extent record in catalog file gets full, new ones are allocated from extents overflow file. In case shrinking truncate happens to middle of an extent record which locates in extents overflow file, the logic in hfsplus_file_truncate() was changed so that call to hfs_brec_remove() is not guarded any more. Right action would be just freeing the extents that exceed the new size inside extent record by calling hfsplus_free_extents(), and then check if the whole extent record should be removed. However since the guard (blk_cnt > start) is now after the call to hfs_brec_remove(), this has unfortunate effect that the last matching extent record is removed unconditionally. To reproduce this issue, create a file which has at least 10 extents, and then perform shrinking truncate into middle of the last extent record, so that the number of remaining extents is not under or divisible by 8. This causes the last extent record (8 extents) to be removed totally instead of truncating into middle of it. Thus this causes corruption, and lost data. Fix for this is simply checking if the new truncated end is below the start of this extent record, making it safe to remove the full extent record. However call to hfs_brec_remove() can't be moved to it's previous place since we're dropping ->tree_lock and it can cause a race condition and the cached info being invalidated possibly corrupting the node data. Another issue is related to this one. When entering into the block (blk_cnt > start) we are not holding the ->tree_lock. We break out from the loop not holding the lock, but hfs_find_exit() does unlock it. Not sure if it's possible for someone else to take the lock under our feet, but it can cause hard to debug errors and premature unlocking. Even if there's no real risk of it, the locking should still always be kept in balance. Thus taking the lock now just before the check.

📍 영향받는 시스템

hfsplus 파일 시스템을 사용하는 Linux 커널 버전

⚔️ 공격 벡터

로컬 사용자가 특정 조건(10개 이상의 extent를 가진 파일)을 충족하는 파일을 생성하고 크기를 줄이는 조작을 수행

🛡️ 대응 방법

Linux 커널을 최신 보안 패치가 적용된 버전으로 업데이트

🔧 검증 코드

출력된 커널 버전을 확인하여 해당 취약점이 해결된 패치 버전인지 확인합니다.

Shell / Script
uname -r

📊 CVSS Vector String

CVSS Vector
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:H

💻 영향받는 소프트웨어

Linux Kernel