🇰🇷 한글 설명
Linux 커널의 fs/proc/task_mmu 구성 요소에서 hugetlb VMA에 대해 PM_SCAN_WP_MATCHING을 요청하는 PAGEMAP_SCAN ioctl 호출 시 셀프 데드락이 발생합니다. 스캔 과정에서 비어 있는 영역(hole)을 만날 경우, 이미 보유한 읽기 잠금(read lock)을 쓰기 잠금(write lock)으로 전환하려 시도하면서 스레드가 무한 대기 상태에 빠지게 됩니다.
💡 쉬운 설명
리눅스 시스템의 메모리 관리 과정에서 특정 작업을 수행할 때, 프로그램이 자기 자신을 기다리느라 멈춰버리는 현상이 발생합니다. 이로 인해 시스템의 특정 프로세스가 응답하지 않고 영구적으로 중단될 수 있습니다.
🇺🇸 원문 (English)
In the Linux kernel, the following vulnerability has been resolved:
fs/proc/task_mmu: fix hugetlb self-deadlock in pagemap_scan_pte_hole()
A PAGEMAP_SCAN ioctl requesting PM_SCAN_WP_MATCHING on a hugetlb VMA hangs
the calling thread, unkillably, as soon as the scan reaches an unpopulated
part of the range:
do_pagemap_scan()
walk_page_range()
walk_hugetlb_range()
hugetlb_vma_lock_read() # take the vma lock for read ...
pagemap_scan_pte_hole() # ... ->pte_hole() for a hole
uffd_wp_range()
change_protection()
hugetlb_change_protection()
hugetlb_vma_lock_write() # ... and block taking it for write
walk_hugetlb_range() holds the hugetlb vma lock for read across the whole
walk. A present entry goes to ->hugetlb_entry(); an unpopulated one goes
to ->pte_hole(), i.e. pagemap_scan_pte_hole(). To write-protect the hole
that handler calls uffd_wp_range(), which on a hugetlb VMA reaches
hugetlb_change_protection() and takes the same vma lock for write. The
thread then blocks in down_write() waiting for the read lock it is itself
holding.
The populated path avoids this: pagemap_scan_hugetlb_entry()
write-protects the entry inline under the page-table lock and never enters
hugetlb_change_protection().
Do the same for holes. Fault in the page table and install the uffd-wp
marker directly with make_uffd_wp_huge_pte() under the page-table lock,
rather than routing through uffd_wp_range(). That is the same sequence
hugetlb_change_protection() runs for an unpopulated entry, minus the vma
write lock -- which is safe to skip because PMD sharing is disabled on
uffd-wp VMAs (hugetlb_unshare_all_pmds() runs at registration), leaving
nothing for that lock to serialise against.
📍 영향받는 시스템
Linux Kernel (hugetlb 및 PAGEMAP_SCAN ioctl을 사용하는 버전)
⚔️ 공격 벡터
로컬 권한을 가진 사용자가 특수하게 조작된 PAGEMAP_SCAN ioctl 요청을 통해 시스템의 특정 스레드를 중단시킬 수 있음
🛡️ 대응 방법
hugetlb VMA의 빈 영역 처리 시 VMA 쓰기 잠금을 거치지 않고 페이지 테이블 잠금 하에서 직접 처리하도록 수정된 최신 리눅스 커널로 업데이트
🔧 검증 코드
출력된 커널 버전이 해당 취약점이 패치된 최신 보안 업데이트 버전인지 확인