🔍 CVE-2024-26960

7.0
CVSS Score
HIGH
2024-05-01
2026-10-15 01:17
✅ 완료

🇰🇷 한글 설명

리눅스 커널의 메모리 관리(mm) 서브시스템에서 free_swap_and_cache()와 swapoff() 함수 간의 레이스 컨디션 취약점이 발견되었습니다. 이로 인해 swapoff()가 swap_info_struct를 해제하는 동안 다른 스레드가 해제된 메모리에 접근하여 시스템 불안정성을 초래할 수 있습니다.

💡 쉬운 설명

컴퓨터가 메모리를 정리하는 과정에서 두 작업이 동시에 충돌하여 이미 삭제된 메모리 영역을 건드릴 수 있는 문제입니다. 이로 인해 시스템이 멈추거나 예기치 않은 오류가 발생할 수 있습니다.

🇺🇸 원문 (English)

In the Linux kernel, the following vulnerability has been resolved: mm: swap: fix race between free_swap_and_cache() and swapoff() There was previously a theoretical window where swapoff() could run and teardown a swap_info_struct while a call to free_swap_and_cache() was running in another thread. This could cause, amongst other bad possibilities, swap_page_trans_huge_swapped() (called by free_swap_and_cache()) to access the freed memory for swap_map. This is a theoretical problem and I haven't been able to provoke it from a test case. But there has been agreement based on code review that this is possible (see link below). Fix it by using get_swap_device()/put_swap_device(), which will stall swapoff(). There was an extra check in _swap_info_get() to confirm that the swap entry was not free. This isn't present in get_swap_device() because it doesn't make sense in general due to the race between getting the reference and swapoff. So I've added an equivalent check directly in free_swap_and_cache(). Details of how to provoke one possible issue (thanks to David Hildenbrand for deriving this): --8<----- __swap_entry_free() might be the last user and result in "count == SWAP_HAS_CACHE". swapoff->try_to_unuse() will stop as soon as soon as si->inuse_pages==0. So the question is: could someone reclaim the folio and turn si->inuse_pages==0, before we completed swap_page_trans_huge_swapped(). Imagine the following: 2 MiB folio in the swapcache. Only 2 subpages are still references by swap entries. Process 1 still references subpage 0 via swap entry. Process 2 still references subpage 1 via swap entry. Process 1 quits. Calls free_swap_and_cache(). -> count == SWAP_HAS_CACHE [then, preempted in the hypervisor etc.] Process 2 quits. Calls free_swap_and_cache(). -> count == SWAP_HAS_CACHE Process 2 goes ahead, passes swap_page_trans_huge_swapped(), and calls __try_to_reclaim_swap(). __try_to_reclaim_swap()->folio_free_swap()->delete_from_swap_cache()-> put_swap_folio()->free_swap_slot()->swapcache_free_entries()-> swap_entry_free()->swap_range_free()-> ... WRITE_ONCE(si->inuse_pages, si->inuse_pages - nr_entries); What stops swapoff to succeed after process 2 reclaimed the swap cache but before process1 finished its call to swap_page_trans_huge_swapped()? --8<-----

📍 영향받는 시스템

Linux Kernel (swap 관련 메모리 관리 기능이 활성화된 버전)

⚔️ 공격 벡터

특정 타이밍에 swapoff()와 free_swap_and_cache()를 동시에 유도하는 정교한 레이스 컨디션 공격

🛡️ 대응 방법

get_swap_device() 및 put_swap_device()를 사용하여 참조 카운트를 관리하도록 커널을 최신 보안 패치 버전으로 업데이트

🔧 검증 코드

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

Shell / Script
uname -r

📊 CVSS Vector String

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

💻 영향받는 소프트웨어

Linux Kernel