DangZero: Efficient Use-After-Free Detection via Direct Page Table Access


Floris Gorter, Keon Koning, Herbert Bos, Cristiano Giuffrida
CCS '22: 2022 ACM SIGSAC Conference on Computer and Communications Security

개요

DangZero는 user가 Page table에 직접 접근할 수 있도록 하여서, 효율적으로 Use after free을 사전에 차단할 수 있도록 하였다.

Motivation

User after free(UAF)버그는 많이 발생하며 버그라서 이를 찾아내고 차단하는 것은 보안상 중요한 일이었다.

Importance

  • Type safety (Rust와 같은 방식): 프로그램하기 복잡하고, Type safety만을 보장함, Unmodified binary와 같은 경우에는 방어하지 못함
  • Reference counting: 일반적인 C/C++ 프로그램에 적용할 수 없음
  • One-time allocation: Virtual memory space를 넘어가는 작업을 할 수 없음 (언젠가는 OOM이 남)
  • Garbage collector: 성능상의 피할 수 없는 단점이 있음

Main Idea

  • 이 논문은 Use-after-free 버그를 막기 위해서 page table access를 가능하게 하였다.
  • 이를 통해서 Page table에 있는 Metadata를 활용한 효율적인 VA에 대한 GC가 가능하게 하였다.

Design

  • Proxy Allocator: Memory allocator와 User malloc API사이에 Proxy Allocator을 두어서 커널이 준 VA에 대한 Aliased VA를 만들어서 Object allocation을 하도록 하였다. 이를 통해서 같은 Physical address에 대해서 여러개의 서로 다른 VA Mapping이 가능하게 하였다. 이러한 Mapping은 Page table access를 직접할 수 있도록 하여서 효율적으로 이루어지게 하였다. 즉 여러개의 Object들이 하나의 Page를 사용하지만 VA는 다르게 하여서 Memory fragmentation이 생기지 않도록 하였다. (UAF에 대한 논문이기 때문에 Out-of-bound access와 같은 문제는 다루지 않음)
  • GC가 Dangling된 Aliased pointer를 Detect하도록 하여서 Aliased VA공간이 계속해서 생기도록 하였다. 이 GC는 Page table access가 가능하며 대상이 VA이기 때문에 SOTA GC와 비교하여도 빠르게 이루어지게 하였다.
  • 여러개의 다른 VA를 같은 PA에 매핑하기 때문에, 커널의 VMA구조를 사용할 수 없다, 따라서 User-level에서 VA를 관리하여야 하였다. 또한 Allocation된 Page에 대한 정보가 있어야 하기 때문에 On-demand page를 사용할 수 없었다. (On-demand의 경우에는 Page가 나중에 Allocation되기 떄문임)
  • GC과정에서 GC는 Page에 대한 Metadat information이 필요하다. 예를 들어서, page가 available한지, in-use인지, invalidated되었는지와 같은 정보들이 필요하다. 이러한 정보를 기존에는 따로 보관하여야 하였지만, Page table에 직접 접근 가능하기 때문에 논문에서는 새로운 Memory overhead가 없다고 하였다.
  • 만약 페이지 테이블의 PMD의 512개의 PTE가 모두 Free된 상태라면, Metadata를 위해서 PTE들을 들고 있으면 메모리 낭비가 일어난다. 따라서, 이러한 문제를 하결하기 위해서 위와 같은 상황이 발견되면 따로 Slab allocator을 통해서 Compressed page table을 관리하도록 하였다.
  • Dune을 사용하면 Up to 60%까지 느려지기 때문에 Kernel-mode-linux (Unikernel같은 것 같음)을 VM위에 돌려서 실험하였다. 또한 Kernel이 사용하지 않는 VMA영역을 통해서 Mapping하였다. 마지막으로 Fork operation을 Support하기 위해서 일일이 Fork를 모든 Page에 일으켜서 Alias to host physical mapping을 만들었다.

Conclusion

  • DangZero는 Page table에 대한 Direct접근이 가능할때에 어떤 작업을 할 수 있는지 에 대한 서술을 하였다.
  • 한계를 찾아보자면, 반드시 VM위에서 해야 할것, MALLOC함수 만 Support하는 것, Page table locking에 대한 Cost가 빠진것, Kernel address leak에 대한 내용이 없는 것, Fork시에 COW가 안되는 점, On-demand allocation이 안되는 점, KML이라는 오래된 기술에 의존해야 하는 점들이 있다.

설치 방법

새로운 가상머신에서 작업할 것. (DangZero는 KML을 설치하기에 가상머신위에서 돌리는 것이 기본이다.)

git clone https://github.com/vusec/dangzero.git
cd dangzero; cd kml-image; ./build_kml.sh
sudo dpkg -i *.deb
# kmod 폴더로 이동
cd ..; cd kmod
make 
# 여기서 gcc compatibility issue떄문에 code mode kernel 모라면서 빌드가 안될경우 
# https://stackoverflow.com/questions/52703658/compile-error-when-compiling-a-driver-using-makefile/76849000#76849000 
# 참고해서 Docker이용해서 빌드 할것
sudo insmod dangmod.ko
# KML이 사용할 trusted 폴더 생성
sudo mkdir /trusted
cd ..; sudo ./test.sh