| DMGUARD: Safeguarding Kernels from Physical-Page Use-After-Free Vulnerabilities | |
|---|---|
| Author | Juhee Kim, Jaeyoung Chung, Dae R. Jeong, Byoungyoung Lee |
| Conference | USENIX Security |
| Year | 2026 |
개요
Physical-page use-after-free라는 Page table entry 수준에서 일어나는 Use-after-free를 새로운 Vulnerability domain으로 정의하고, 이를 막을 수 있는 Runtime mitigation인 DMGUARD를 제시하였다.
기존의 Use-after-free는 일반적으로 Virtual address space 안에서 Freed object를 가리키는 Dangling pointer 문제로 이해되었다. 반면 본 논문에서 정의하는 Physical-page use-after-free는 Virtual address가 Page table을 통해 이미 Free되었거나 Reallocation된 Physical page를 계속 가리키는 문제이다. 즉, Object pointer가 아니라 Virtual-to-physical address translation layer에서 발생하는 Use-after-free이다.
DMGUARD는 각 Physical page의 Lifecycle을 State machine으로 모델링하고, Page allocation, Mapping, Unmapping, Free 시점에서 Per-page metadata를 업데이트한다. 이를 통해 Page가 아직 Mapping된 상태에서 Free되는 Free-before-unmap과, 이미 Free된 Page reference를 다시 Mapping하는 Map-after-free를 탐지한다.
핵심 메커니즘은 두 가지이다. 첫째, MapCount를 이용해서 해당 Physical page가 User-space page table에 몇 번 Mapping되어 있는지를 추적한다. 둘째, PageTag와 RefTag를 이용해서 Page reference가 현재 Allocation cycle에 속한 유효한 Reference인지 확인한다. 이를 통해 CPU page table뿐 아니라 GPU page table, IOMMU page table처럼 여러 Translation domain에 걸친 Dangling mapping을 탐지하고 차단한다.
Motivation & Importance
현대 Kernel security mechanism들은 대부분 Page table의 정확성을 전제로 한다. 예를 들어 ASLR, CFI, DFI, PAC, MTE, MPK와 같은 방어 기법은 Virtual address가 올바른 Physical page로 Translation된다는 가정 위에서 동작한다. 그러나 Page table에 Dangling mapping이 남아 있으면, 공격자는 기존 방어 기법을 우회해서 Freed page 또는 Reallocated page를 User space에서 접근할 수 있다.
특히 Mobile/Embedded system에서는 CPU와 Integrated GPU가 같은 Physical memory를 공유하면서도 서로 다른 Page table을 사용한다. 예를 들어 Mali GPU나 Adreno GPU는 System DRAM을 공유하지만, GPU driver가 별도의 Page allocator와 GPU page table을 관리한다. 이 과정에서 CPU page table, GPU page table, IOMMU page table이 같은 Physical page를 가리킬 수 있다. Zero-copy memory sharing은 성능상 이점이 있지만, Page allocation과 Mapping/Unmapping의 책임이 여러 Subsystem에 분산되기 때문에 Page lifecycle 관리가 복잡해진다.
기존의 CONFIG_PAGE_TABLE_CHECK(ptcheck)는 CPU-side Page table mapping을 중심으로 관리한다. 따라서 GPU allocator가 할당한 Page가 CPU page table에 Mapping되거나, GPU page table/IOMMU page table에 Mapping되는 경우를 충분히 추적하지 못한다. 또한 ptcheck는 Mapping status는 일부 추적하지만 Allocation status를 추적하지 않기 때문에 Map-after-free를 근본적으로 탐지하기 어렵다.
또한 Page management는 Performance-sensitive path에 있다. Page fault, mmap, munmap, fork, GPU memory management 등은 자주 호출되기 때문에, 단순히 Global lock을 걸거나 Heavy synchronization을 추가하는 방식은 실용적이지 않다. 따라서 이 논문의 Motivation은 Heterogeneous translation domain 전체에서 Page lifecycle을 정확히 추적하면서도 낮은 Overhead를 유지하는 것이다.
Challenge
- Systems with multiple different page tables distribute lifecycle management across independent subsystems
- 현대 시스템에서는 CPU, GPU, IOMMU 등이 각각 독립적인 Page table 또는 Translation structure를 가질 수 있다.
- Page allocation은 GPU driver가 수행하고, CPU mapping은 Kernel이 수행하며, IOMMU mapping은 별도의 Subsystem이 수행할 수 있다.
- 이처럼 Page lifecycle이 여러 Subsystem에 분산되어 있기 때문에, 어떤 Physical page가 아직 Mapping되어 있는지 전역적으로 판단하기 어렵다.
- Page management resides in a performance-sensitive path where synchronization overhead across different subsystems is expensive
- Page table operation은 Page fault, fork, mmap/munmap, GPU memory operation 등 성능에 민감한 경로에서 수행된다.
- 따라서 CPU/GPU/IOMMU 사이의 모든 Mapping 상태를 Lock 기반으로 동기화하면 Runtime overhead가 커질 수 있다.
- DMGUARD는 이를 해결하기 위해 Lockless design을 사용하고, Atomic operation과 Memory barrier를 통해 Concurrent Map/Free race를 막는다.
- The kernel provides low-level mapping interfaces that bypass standard page management mechanisms
- Linux kernel은 VM_PFNMAP과 같이 Page descriptor나 Reference counting을 우회하는 Low-level PFN-based mapping interface를 제공한다.
- 이러한 Interface는 MMIO처럼 일반 Buddy allocator가 관리하지 않는 Memory를 Mapping하기 위해 필요하지만, Device driver가 Buddy allocator에서 온 Page에도 이를 사용하면 Reference count가 제대로 갱신되지 않을 수 있다.
- 결과적으로 Page가 아직 Mapping되어 있음에도 Free되거나, 이미 Free된 PFN을 다시 Mapping하는 문제가 생길 수 있다.
- Correctness under concurrency is non-trivial
- Map과 Free가 서로 다른 CPU core 또는 Subsystem에서 동시에 발생할 수 있다.
- Weak memory model을 가진 ARM/RISC-V에서는 Instruction reordering 때문에 MapCount update와 PageTag check의 순서가 뒤바뀔 수 있다.
- DMGUARD는 LKMM(Linux Kernel Memory Model)을 기준으로 Memory barrier와 Atomic operation을 배치하여, Concurrent Map-Free 상황에서도 Dangling mapping이 생기지 않도록 설계한다.
Background
- Physical-page use-after-free
- Traditional heap use-after-free는 Virtual address space 안의 Pointer가 이미 Free된 Object를 가리키는 문제이다.
- Physical-page use-after-free는 Page table entry가 이미 Free되었거나 다른 목적으로 Reallocation된 Physical page를 계속 가리키는 문제이다.
- 따라서 문제의 위치가 Object allocator가 아니라 Address translation layer이다.
- 공격자는 Page spraying을 통해 Freed physical page가 Attacker-controlled content로 재할당되도록 유도할 수 있다.
- 그 결과 User process가 Dangling mapping을 통해 Kernel page table, Credential structure 등 민감한 Physical memory를 접근할 수 있다.
- Dangling mapping
- Dangling mapping은 Page table entry가 이미 Free된 Physical page를 계속 가리키는 상태이다.
- 이 상태에서 Processor가 해당 Virtual address에 접근하면, 실제로는 Free되었거나 다른 용도로 재사용된 Physical page에 접근하게 된다.
- 논문은 Dangling mapping을 Physical-page UAF의 직접적인 원인으로 본다.
- Free-before-unmap
- Page가 Page table에 아직 Mapping되어 있는데 먼저 Free되는 경우이다.
- 정상적인 순서는 Unmap(P) 이후 Free(P)이다.
- 하지만 Free(P)가 Unmap(P)보다 먼저 발생하면 기존 Page table entry가 Freed page를 계속 가리키게 된다.
- DMGUARD는 Free 시점에 MapCount가 0인지 확인하여 이를 탐지한다.
- Map-after-free
- 이미 Free된 Page reference를 사용해서 Mapping을 만드는 경우이다.
- 예를 들어 Old struct page* 또는 Old PFN이 남아 있고, 이 Reference를 이용해 다시 PTE를 만들면 Freed page에 대한 Mapping이 생성될 수 있다.
- DMGUARD는 PageTag와 RefTag를 비교하여 Reference가 현재 Allocation cycle에 속하는지 확인한다.
- CVE-2025-0072 사례
- 논문은 Mali GPU driver의 CVE-2025-0072를 대표적인 Real-world example로 제시한다.
- Mali driver는 mmap() 과정에서 GPU command buffer를 위한 Virtual address를 예약하고, GPU page allocator에서 Page를 할당한 뒤 queue->phys에 Physical address를 저장한다.
- 실제 CPU mapping은 Lazy하게 Page fault 시점에 생성된다.
- 취약한 경로에서는 두 번째 mmap()이 queue->phys를 새 Page로 덮어쓴 뒤, 첫 번째 mmap region을 munmap할 때 실제 Mapping은 제거되지 않지만 queue->phys가 가리키는 두 번째 Page가 Free된다.
- 그 결과 VA2 -> PA2 Mapping이 CPU page table에 남아 있는데 PA2가 Free되어 Free-before-unmap 취약점이 발생한다.
Main Idea
DMGUARD의 핵심 아이디어는 Physical page의 Lifecycle을 State machine으로 표현하고, 각 State transition이 올바른 순서로 일어나는지 Runtime에 검사하는 것이다.
Page는 크게 다음 상태를 가진다.
- Freed-Unmapped
- Page allocator의 Free pool에 있는 상태이다.
- 어떤 Page table에도 Mapping되어 있지 않다.
- Virtual address를 통해 접근할 수 없다.
- Allocated-Unmapped
- Page allocator에서 할당되었지만 아직 어떤 User-space page table에도 Mapping되지 않은 상태이다.
- Kernel은 struct page* 또는 PFN을 통해 이 Page를 참조할 수 있지만, User process는 아직 접근할 수 없다.
- Allocated-Mapped
- Page가 할당되어 있고, 하나 이상의 Page table entry가 이 Physical page를 가리키는 상태이다.
- CPU page table, GPU page table, IOMMU page table 등 여러 Translation domain에서 동시에 Mapping될 수 있다.
정상적인 Lifecycle은 다음과 같다.
- Freed-Unmapped -> Allocated-Unmapped
- Alloc(P)에 의해 Page가 할당된다.
- Allocated-Unmapped -> Allocated-Mapped
- Map(P)에 의해 Page table entry가 생성된다.
- Allocated-Mapped -> Allocated-Unmapped
- Unmap(P)에 의해 모든 Mapping이 제거된다.
- Allocated-Unmapped -> Freed-Unmapped
- Free(P)에 의해 Page가 allocator로 반환된다.
DMGUARD는 이 State machine에서 잘못된 Transition을 탐지한다.
- Free-before-unmap
- Allocated-Mapped 상태의 Page가 Unmap 없이 Free되는 경우이다.
- 즉, Allocated-Mapped -> Freed-Unmapped로 바로 가는 잘못된 Transition이다.
- DMGUARD는 Free(P) 시점에 MapCount(P) != 0이면 이를 Free-before-unmap으로 판단한다.
- Map-after-free
- Freed-Unmapped 상태의 Page reference를 이용해서 Mapping을 만드는 경우이다.
- 즉, Freed-Unmapped -> Allocated-Mapped처럼 Allocation 없이 Mapping이 만들어지는 잘못된 Transition이다.
- DMGUARD는 Map(P) 시점에 PageTag(P)와 RefTag(P)가 다르면 이를 Map-after-free로 판단한다.
이를 위해 DMGUARD는 두 종류의 Metadata를 사용한다.
- MapCount
- Physical page마다 유지되는 Counter이다.
- User-space Mapping이 생성될 때 증가하고, Mapping이 제거될 때 감소한다.
- CPU page table뿐 아니라 GPU page table, IOMMU page table의 Mapping도 함께 반영한다.
- Page를 Free할 때 MapCount가 0이 아니면 아직 Dangling mapping이 존재할 수 있으므로 Free-before-unmap으로 탐지한다.
- PageTag / RefTag
- PageTag는 Physical page의 현재 Allocation cycle을 나타내는 Per-page tag이다.
- RefTag는 struct page* 또는 PFN 같은 Page reference에 붙는 Tag이다.
- Page가 Allocate될 때 PageTag를 새 Random value로 갱신하고, 그 Page를 가리키는 Reference에는 같은 RefTag를 부여한다.
- Page가 Free되면 PageTag를 다시 갱신하여 Old reference를 무효화한다.
- Mapping을 만들 때 PageTag와 RefTag가 일치하지 않으면, Old reference를 통한 Map-after-free로 판단한다.
즉, DMGUARD는 Mapping status는 MapCount로 추적하고, Allocation status는 PageTag/RefTag로 추적한다. 이 두 정보를 결합하여 “Freed page가 Mapping되거나, Mapped page가 Free되는 상태”를 Runtime에 막는다.
Design
DMGUARD의 설계는 크게 State machine, Twofold state tracking, Lockless integration, Kernel/GPU driver instrumentation으로 구성된다.
Page Lifecycle State Machine
DMGUARD는 각 Physical page의 상태를 Allocation status와 Mapping status의 조합으로 본다.
- Allocation status
- Freed
- Allocated
- Mapping status
- Unmapped
- Mapped
이 조합을 통해 Page는 Freed-Unmapped, Allocated-Unmapped, Allocated-Mapped 상태를 가진다. Freed-Mapped 상태는 존재해서는 안 되는 Invalid state이다. Physical-page UAF는 결국 Freed-Mapped 상태가 만들어지는 문제로 볼 수 있다.
DMGUARD의 목표는 Runtime에 Page operation을 감시하여 Freed-Mapped 상태가 생기기 전에 중단하는 것이다.
Tracking Mapping Status with MapCount
MapCount는 Page가 몇 개의 User-space Mapping을 가지고 있는지를 나타낸다.
- Map(P)
- Page가 User-space page table에 Mapping되면 MapCount(P)를 증가시킨다.
- Unmap(P)
- Page의 Mapping이 제거되면 MapCount(P)를 감소시킨다.
- Free(P)
- Page를 Free하기 전에 MapCount(P)를 확인한다.
- MapCount(P)가 0이면 안전하게 Free할 수 있다.
- MapCount(P)가 0보다 크면 아직 Mapping이 남아 있으므로 Free-before-unmap으로 탐지한다.
이 방식은 Reference counting과 유사하지만, 일반적인 Object reference count가 아니라 Page table mapping의 개수를 추적한다는 점이 중요하다. 또한 CPU page table뿐 아니라 GPU/IOMMU page table의 Mapping까지 포함한다.
Tracking Allocation Status with PageTag / RefTag
MapCount만으로는 Map-after-free를 막을 수 없다. 이미 Free된 Page reference가 남아 있고, 이를 이용해 Mapping을 만들면 MapCount는 새로 증가할 수 있기 때문이다. 따라서 DMGUARD는 Allocation cycle을 구분하기 위해 Tagging을 사용한다.
- PageTag
- Physical page의 Per-page metadata에 저장된다.
- 현재 Allocation cycle을 나타낸다.
- Page가 Allocate되거나 Free될 때 새 Random tag로 갱신된다.
- RefTag
- struct page* 또는 PFN 같은 Page reference에 저장된다.
- 해당 Reference가 만들어졌을 때의 PageTag를 보존한다.
- ARM64에서는 TBI(Top Byte Ignore)를 활용하여 struct page*의 Top byte에 RefTag를 저장한다.
Mapping을 만들 때 DMGUARD는 PageTag(P)와 RefTag(P)를 비교한다.
- PageTag(P) == RefTag(P)
- Reference가 현재 Allocation cycle의 Page를 가리키므로 Mapping을 허용한다.
- PageTag(P) != RefTag(P)
- Reference가 Old allocation cycle의 Stale reference이므로 Map-after-free로 탐지한다.
논문에서는 8-bit Tag를 사용한다. 하나의 값은 Default tag로 예약하고, 나머지 값을 Random하게 사용한다. 이 때문에 일반적인 Reallocation 이후 Map-after-free에는 1/255 확률의 Tag collision 가능성이 있다. 그러나 Free 직후 바로 Mapping하는 Immediate map-after-free의 경우 이전 Tag와 다른 값을 강제하여 100% 탐지한다고 설명한다.
Lockless Integration
Page management path는 매우 성능에 민감하므로 DMGUARD는 Global lock을 사용하지 않는다. 대신 Atomic operation과 Memory barrier를 사용하여 Concurrent operation의 Correctness를 보장한다.
DMGUARD의 핵심 Operation은 다음과 같다.
- dmcAlloc()
- 기존 Alloc()을 호출해 Page를 할당한다.
- PageTag를 새 값으로 갱신한다.
- 반환되는 struct page* 또는 PFN에 같은 RefTag를 설정한다.
- dmcMap()
- MapCount를 증가시킨다.
- Memory barrier를 수행한다.
- PageTag와 RefTag를 비교한다.
- Tag가 일치하면 실제 Map(P)를 수행한다.
- Tag가 다르면 Map-after-free로 판단한다.
- dmcUnmap()
- 실제 Unmap(P)를 수행한다.
- MapCount를 감소시킨다.
- MapCount가 음수가 되면 잘못된 Unmap으로 판단한다.
- dmcFree()
- PageTag를 먼저 갱신하여 기존 Reference를 무효화한다.
- Memory barrier를 수행한다.
- MapCount가 0인지 확인한다.
- MapCount가 0이면 실제 Free(P)를 수행한다.
- MapCount가 0보다 크면 Free-before-unmap으로 판단한다.
이 순서는 Concurrent Map-Free race를 막기 위해 중요하다. 예를 들어 dmcMap에서 MapCount 증가가 PageTag check보다 뒤로 Reorder되면, 동시에 수행되는 dmcFree가 MapCount를 0으로 보고 Page를 Free할 수 있다. DMGUARD는 Memory barrier를 통해 이러한 Reordering을 막는다.
논문은 이 Lockless design이 x86, ARM, RISC-V 등 Linux가 지원하는 Architecture의 Memory model에서도 안전하게 동작하는지 LKMM(Linux Kernel Memory Model) Litmus test로 검증했다고 주장한다.
Integration with Kernel and GPU Drivers
DMGUARD는 Linux kernel과 GPU driver의 Page operation interface에 통합된다.
- Linux kernel
- Map: set_pte_at
- Unmap: ptep_get_and_clear, ptep_get_and_clear_full
- Alloc: post_alloc_hook
- Free: free_pages_prepare
- Mali GPU driver
- Map: entry_set_ate, entry_set_pte
- Unmap: entries_invalidate
- Alloc: kbase_mem_pool_alloc, kbase_mem_pool_alloc_pages 등
- Free: kbase_mem_pool_free, kbase_mem_pool_free_pages 등
- Adreno GPU driver
- Map: __arm_lpae_set_pte, arm_lpae_init_pte
- Unmap: __arm_lpae_set_pte, arm_lpae_init_pte, __arm_lpae_free_pgtable, __arm_lpae_unmap
- Alloc: kgsl_pool_alloc_page
- Free: kgsl_pool_free_page
구현 규모는 Core DMGUARD가 약 400 LOC, Tagged PFN macro가 약 560 LOC, Mali GPU driver 변경이 약 90 LOC, Adreno GPU driver 변경이 약 80 LOC이다. 이는 DMGUARD가 기존 Kernel 구조를 크게 바꾸기보다는 주요 Page lifecycle operation에 작은 Instrumentation을 추가하는 방식임을 보여준다.
Comparison with CONFIG_PAGE_TABLE_CHECK
CONFIG_PAGE_TABLE_CHECK는 CPU page table의 Mapping status를 일부 추적할 수 있지만, DMGUARD와 비교하면 다음 한계가 있다.
- CPU page allocator와 CPU page table 사이의 Free-before-unmap은 탐지할 수 있다.
- 그러나 CPU page와 Device mapping, Device page와 CPU mapping, Device page와 Device mapping은 충분히 다루지 못한다.
- Allocation status를 추적하지 않으므로 Map-after-free를 탐지하지 못한다.
- Concurrent Map-Free race에 대한 Synchronization이 부족하여 TOCTOU-style vulnerability가 가능하다.
반면 DMGUARD는 Allocation status와 Mapping status를 모두 추적하고, CPU/GPU/IOMMU context를 함께 고려하며, Lockless synchronization으로 Concurrent race까지 다루려고 한다.
Evaluation
논문은 DMGUARD를 Security, Performance, Robustness 측면에서 평가하였다.
Evaluation Setup
DMGUARD는 세 가지 환경에서 평가되었다.
- QEMU AArch64 환경
- Linux kernel v6.6.0
- Mali GPU driver
- Dummy GPU device(MALI_NO_MALI)
- Pixel 8
- Android 15
- Linux kernel v6.1.99
- ARMv8.5 CPU
- Mali GPU
- Pixel 3 XL
- Android 12
- Linux kernel v4.9.270
- ARMv8.2 CPU
- Qualcomm Adreno GPU
비교 대상은 다음과 같다.
- Baseline
- Dangling mapping mitigation이 없는 기본 Kernel configuration
- ptcheck
- Linux CONFIG_PAGE_TABLE_CHECK
- DMGUARD
- 본 논문에서 제안한 Runtime mitigation
Security Evaluation
Security evaluation에서는 총 24개의 Physical-page use-after-free vulnerability를 대상으로 DMGUARD와 ptcheck를 비교하였다.
- 19개는 Real-world vulnerability이다.
- Linux kernel
- Mali GPU driver
- Adreno GPU driver
- PowerVR GPU driver
- 5개는 Synthetic vulnerability이다.
- Map-after-free case
- Race condition 기반 Free-before-unmap case
논문은 이 중 15개를 실제 환경에서 Empirical evaluation하였다. 나머지 9개는 Hardware 부족, GPU driver virtual environment 미지원, Kernel/driver version mismatch 등의 이유로 직접 재현하지 못하고 Theoretical analysis를 수행하였다.
Empirical evaluation 결과는 다음과 같다.
- DMGUARD
- 15개 중 15개 모두 탐지하였다.
- ptcheck
- 15개 중 5개만 탐지하였다.
ptcheck가 탐지한 경우는 주로 CPU page가 CPU page table에 Mapping된 Free-before-unmap case이다. 반면 GPU page allocator, GPU page table, IOMMU page table이 관련된 경우나 Map-after-free case는 탐지하지 못했다.
Theoretical analysis 대상 9개에서도 논문은 DMGUARD가 설계상 모두 탐지 가능하다고 분석하였다. 이 9개는 모두 GPU page가 GPU 또는 IOMMU context에 Mapping되는 형태라 ptcheck는 탐지하지 못한다고 설명한다.
False Positives and False Negatives
논문은 Performance evaluation과 Robustness test 중 DMGUARD가 False alarm을 발생시키지 않았다고 보고한다. 또한 Known vulnerability test에서 모든 Empirical case를 탐지했기 때문에 실험상 False negative도 관찰되지 않았다고 한다.
그러나 설계상 False positive와 False negative 가능성은 존재한다.
- MapCount 관련 False positive
- 실제로는 Unmap되었지만 MapCount가 감소하지 않으면, Free 시점에 Dangling mapping으로 잘못 판단할 수 있다.
- MapCount 관련 False negative
- 실제로 Mapping되었지만 MapCount가 증가하지 않으면, Free-before-unmap을 놓칠 수 있다.
- PageTag 관련 False negative
- Mapping 시점에 Tag check가 빠지면 Map-after-free를 놓칠 수 있다.
- Page가 Free/Reallocation될 때 Tag가 갱신되지 않으면 Stale reference를 탐지하지 못할 수 있다.
- 8-bit Tag collision이 발생하면 Old reference의 RefTag와 New PageTag가 우연히 일치할 수 있다.
- Instrumentation coverage 문제
- Driver가 Standard API를 거치지 않고 Page table을 직접 조작하면 DMGUARD가 상태 변화를 추적하지 못할 수 있다.
Finding Unknown Vulnerabilities
논문은 Pixel 8에서 DMGUARD를 활성화한 상태로 Syzkaller를 실행하였다. 이 과정에서 Upstream Mali GPU driver의 Dangling mapping issue를 발견하였다.
해당 Issue는 Process가 GPU-allocated region에 대해 명시적으로 munmap()을 호출하지 않고 종료될 때, Physical page가 Free된 뒤에도 GPU page table entry가 남는 문제였다. 연구진은 이를 ARM에 보고했고, ARM은 Dangling mapping은 존재하지만 GPU task가 이미 종료된 뒤 생성되기 때문에 Exploitable하지 않다고 판단하였다.
이 결과는 DMGUARD가 Known vulnerability를 막는 방어 기법일 뿐 아니라, 실제 Kernel/Driver의 Page lifecycle bug를 찾는 Detection tool로도 사용할 수 있음을 보여준다.
Performance Evaluation
Performance evaluation은 Pixel 8에서 수행되었다.
- LMBench
- DMGUARD의 Geomean overhead는 2.96%이다.
- ptcheck의 Geomean overhead는 1.99%이다.
- Fork 계열 Benchmark에서 상대적으로 높은 Overhead가 나타났다.
- Process fork+exit: 10.05%
- Process fork+execve: 12.58%
- Process fork+/bin/sh -c: 4.81%
- 이는 Fork 과정에서 많은 Page table entry를 설정하기 때문이라고 설명한다.
- Phoronix Test Suite
- DMGUARD의 Geomean overhead는 1.26%이다.
- Workload는 OpenSSL, PyBench, Apache, Nginx, Redis, Linux unpack/build 등을 포함한다.
- 실사용 Application workload에서는 Overhead가 낮은 편이다.
- Geekbench 6
- CPU Single-core
- Baseline: 1629.45
- DMGUARD: 1622.27(-0.44%)
- CPU Multi-core
- Baseline: 4605.09
- DMGUARD: 4545.73(-1.29%)
- GPU OpenCL
- Baseline: 7691.36
- DMGUARD: 7674.18(-0.22%)
GPU workload에서도 Overhead가 낮다는 점은 DMGUARD가 GPU page table까지 추적하면서도 Runtime cost가 크지 않음을 보여준다. CPU Multi-core overhead는 Memory barrier로 인한 영향이 상대적으로 큰 것으로 해석된다.
- Kernel boot time
- Baseline: 0.510s
- DMGUARD: 0.528s(+3.53%)
- Application cold-start latency
- AOSP system app 10개에서 Geomean overhead는 3.10%이다.
- 최대 Overhead도 수 ms~수십 ms 수준으로 보고된다.
- 논문은 Boot time과 Cold-start overhead는 One-time cost이므로 지속적인 Runtime performance에는 큰 영향을 주지 않는다고 설명한다.
- Memory overhead
- DMGUARD는 ptcheck 대비 Page당 8 bytes의 추가 Metadata를 사용한다.
- Pixel 8 기준 Baseline 대비 Memory overhead는 약 1.05%이다.
- 논문은 전체 7,739,468 KB memory에서 약 50 MB 수준의 추가 사용량으로, 현대 시스템에서는 작은 비용이라고 주장한다.
Robustness Evaluation
DMGUARD는 Linux kernel의 Page management path를 수정하므로 Stability가 중요하다. 논문은 Pixel 8에서 Android Vendor Test Suite(VTS) kernel test plan을 10회 반복 실행하였다.
- Kselftest와 Linux Test Project(LTP)를 포함한 vts-kernel test를 수행하였다.
- 10회 반복 실행 중 Crash나 Hang이 발생하지 않았다.
- 모든 Test가 통과하였다.
- Performance evaluation 중에도 Unexpected error가 발생하지 않았다.
이를 통해 논문은 DMGUARD가 실제 Android kernel에서 Stability를 해치지 않는다고 주장한다.
Conclusion
우선 메모리 Vulnerability domain을 새로 찾았다고 나오지만, 사실 pte check에서 체크하고 있던 잘 알려진 문제 였다는 점, 그리고 전반적으로 Design이 pte check의 확장 (이기종 시스템으로의)로 보인다는 점이 주된 한계로 들수 있다. 그러나 이기종 시스템에서 발생할 수 있는 UAF문제를 시기 적절하고 & 최초로 상정하였다는 점에서 Motivation이 납득 가능하고, Mechanisms측면에서는 이 적절한 Motivation을 효율적으로 풀 수 있는 최적의 방법이라는 점이 이 논문의 장점이라고 생각한다.