🇰🇷 한글 설명
Linux 커널의 IOMMU DMA 구현에서 VFIO Type1 레거시 컨테이너 사용 시 msi_page_list에 대한 잠금(locking)이 누락되어 발생하는 취약점입니다. ARM SMMU와 같이 소프트웨어 MSI를 지원하는 IOMMU 환경에서 두 개 이상의 장치가 동일한 도메인을 공유할 경우, 병렬 MSI 할당 과정에서 데이터 구조가 손상될 수 있습니다.
💡 쉬운 설명
여러 개의 가상 장치가 하나의 통로를 공유해서 사용할 때, 동시에 데이터를 쓰려고 시도하다가 데이터가 엉키는 문제가 발생할 수 있습니다. 이로 인해 시스템이 불안정해지거나 보안 문제가 생길 수 있습니다.
🇺🇸 원문 (English)
In the Linux kernel, the following vulnerability has been resolved:
iommu/dma: Restore locking around msi_page_list
Unlike a group's default domain, which is always freshly allocated
and privately owned (iommu_group_alloc_default_domain()), VFIO type1's
legacy container merges any newly attached group into an existing
domain whenever their iommu_ops and cache-coherency enforcement match.
iommu_dma_get_msi_page() only asserts the caller's own group mutex is
held (iommu_group_mutex_assert()). On an IOMMU that publishes
IOMMU_RESV_SW_MSI, e.g. ARM SMMU, a VM with two such devices assigned
through the legacy container can have their guest drivers probe and
allocate MSIs in parallel; each host-side VFIO_DEVICE_SET_IRQS lands
on a different device fd and group mutex, but both devices' domains
are the same merged domain, so both can enter
iommu_dma_get_msi_page() concurrently and corrupt msi_page_list.
commit 288683c92b1a ("iommu: Make iommu_dma_prepare_msi() into a
generic operation") dropped the prior msi_prepare_lock on the
reasoning that "each iommu_domain is unique to a group," which holds
for default domains but not this VFIO type1 case. Restore the static
lock, since it's only guarding a corner case and will likely never
be contended.
iommufd avoids the equivalent problem by having its own callers
(iommufd_sw_map_msi()) take a ctx-wide sw_msi_lock before ever
reaching the shared list. VFIO type1 can't mirror that since it
dispatches to iommu_dma_sw_msi() which is outside VFIO's jurisdiction.
📍 영향받는 시스템
Linux kernel (VFIO Type1 legacy container 및 IOMMU_RESV_SW_MSI 지원 시스템)
⚔️ 공격 벡터
동일한 IOMMU 도메인을 공유하는 두 개 이상의 가상 장치에서 병렬로 MSI 할당을 시도하여 msi_page_list를 손상시킴
🛡️ 대응 방법
커널 패치를 통해 iommu_dma_prepare_msi() 호출 시 msi_prepare_lock을 다시 적용하여 동기화 보장
🔧 검증 코드
출력된 커널 버전이 해당 취약점이 수정된 패치 버전(commit 288683c92b1a 적용 이후)인지 확인하십시오.