[하루한줄] CVE-2024-44068: Samsung Exynos UAF 취약점
URL
https://googleprojectzero.github.io/0days-in-the-wild//0day-RCAs/2024/CVE-2024-44068.html
Target
- Samsung Exynos (9820, 9825, 980, 990, 850, W920) < SMR-Oct-2024
Explain
삼성의 모바일 및 웨어러블 프로세서인 Exynos에서 UAF 취약점이 발견되어 Google Project Zero의 세부 분석 정보가 공개되었습니다.
취약점은 미디어의 하드웨어 가속을 제공하는 m2m 드라이버의 M2M1SHOT_IOC_PROCESS
IOCTL 루틴에 존재합니다. 해당 루틴은 유저랜드 페이지를 I/O 페이지에 매핑 및 매핑 해제하고, 펌웨어 명령을 실행합니다.
I/O 메모리 매핑 시 m2m1shot_dma_addr_map → exynos_iovmm_map_userptr → exynos_iommu_map_userptr → sysmmu_map_pud 호출 체인을 통해 sysmmu_map_pte 함수가 호출됩니다.
참조된 Github 링크는 설명을 위한 예시이며, exploit 및 분석 환경과 일치하지 않을 수 있습니다.
static int sysmmu_map_pte(struct mm_struct *mm,
pmd_t *pmd, unsigned long addr, unsigned long end,
struct exynos_iommu_domain *domain, sysmmu_iova_t iova, int prot)
{
pte_t *pte;
int ret = 0;
spinlock_t *ptl;
bool write = !!(prot & IOMMU_WRITE);
bool pfnmap = !!(prot & IOMMU_PFNMAP); // [1] If vma->vm_flags & VM_PFNMAP is true, exynos_iovmm_map_userptr appends the IOMMU_PFNMAP flag to prot.
bool shareable = !!(prot & IOMMU_CACHE);
unsigned int fault_flag = write ? FAULT_FLAG_WRITE : 0;
sysmmu_pte_t *ent, *ent_beg;
pte = pte_alloc_map_lock(mm, pmd, addr, &ptl);
if (!pte)
return -ENOMEM;
ent = alloc_lv2entry_userptr(domain, iova);
if (IS_ERR(ent)) {
ret = PTR_ERR(ent);
goto err;
}
ent_beg = ent;
do {
if (pte_none(*pte) || !pte_present(*pte) ||
(write && !pte_write(*pte))) {
int cnt = 0;
int maxcnt = 1;
if (pfnmap) {
ret = -EFAULT;
goto err;
}
while (cnt++ < maxcnt) {
spin_unlock(ptl);
/* find_vma() always successes */
ret = handle_mm_fault(find_vma(mm, addr),
addr, fault_flag);
spin_lock(ptl);
if (ret & VM_FAULT_ERROR) {
ret = mm_fault_translate(ret);
goto err;
} else {
ret = 0;
}
[...]
}
}
BUG_ON(!lv2ent_fault(ent));
*ent = mk_lv2ent_spage(pte_pfn(*pte) << PAGE_SHIFT);
if (!pfnmap)
get_page(pte_page(*pte));
else
mk_lv2ent_pfnmap(ent); // [2] For PFNMAP pages, the page reference count is not elevated.
[...]
} while (pte++, addr += PAGE_SIZE, addr != end);
pgtable_flush(ent_beg, ent);
err:
pte_unmap_unlock(pte - 1, ptl);
return ret;
}
해당 함수는 FNMAP 페이지에 대한 referece count를 증가시키지 않으며, 호출 체인 중exynos_iommu_unmap_userptr 함수에서 non-PFNMAP 페이지에 대한 reference count만 감소시킵니다.
따라서 PFNMAP 페이지를 할당하고, 이를 I/O Virtual Memory에 매핑한 뒤 참조된 상태의 페이지를 munmap
을 통해 해제할 수 있습니다. 매핑되어있는 I/O Virtual Memory는 여전히 해제된 페이지에 접근이 가능하므로 UAF가 트리거됩니다.
해당 취약점은 In-The-Wild에서 악용된 취약점이며, 공격자는 해당 취약점을 악용해 권한있는 프로세스인 cameraserver
프로세스에서 임의 코드를 실행한 것으로 알려졌습니다.
본 글은 CC BY-SA 4.0 라이선스로 배포됩니다. 공유 또는 변경 시 반드시 출처를 남겨주시기 바랍니다.