개요

Use after free 버그는 Free된 버그에 Access가 일어나서, 예측하지 못한 행동이 프로그램에 일어나는 버그를 말한다. 간단한 개념에 쉬운 작동방식을 가지고 있지만, UAF버그는 많은 사용 프로그램에서 지속적으로 발생하며, 발생할 경우 치명적인 영향을 프로그램에 미칠수도 있는 버그이다.

실제로 UAF버그는 매우 복잡한 환경에서 일어난다.

  • 많은 경우 Allocation, 메모리 대입, 그리고 Dereference는 다른 함수 혹은 다른 프로그램 모듈, 공유 메모리에서 일어난다.
  • 이러한 버그는 또한 Thread accross하게 일어나는 경우가 많다.
  • Event-driven방식 혹은 Object-oriented programming은 위와 같은 환경을 매우 빈번하게 사용한다.

이러한 이유로 인해서, Chromium browser에서 UAF버그는 2011-2013년에서 680건이나 발생한 것처럼, 매우 Mature한 프로그램에서도 빈번하게 일어나는 버그이다.

UAF Bug Prevention & Detection

UAF버그를 막기 위한 시스템은 크게 Preventor와 Detector로 구분된다. Preventor는 UAF버그를 잡지는 못하지만, malicious한 버그가 일어나는 것을 차단한다. 그에 비해서 Detector는 UAF버그가 발생하자마자, Detector를 한다. Detector가 Preventor를 포함하고 더 유용한 Debugging tool이지만, 구현하기 까다로워 성능상으로는 훨씬 느리다.

기존 UAF 논문들 정리

  • Performance와 Memory overhead는 서로 trade-off관계이 있는 경우가 대다수임
  • Scalability는 멀티 스레딩 환경 (보통 PARSEC)에서 어느정도 Scalability를 보였는지를 표시, ? (멀티 스레딩 구현 안함, 측정 안함), Low - Moderate - High로 표기
  • Transparency는 Application수정 필요한지 표기. Yes (Full transparent), No (특정 기능이 없거나, 전체적으로 다시 구현해야 하는 경우)
UAF 논문 정리 (* 수치는 직접 측정, 혹은 다른 논문에 측정된 수치를 참고함)
Category Research Memory Performance Scalability Bug-detect Precision Transparency
One-time-allocator *FFmalloc 230% 2.3% High Preventor Yes
OSCAR 60% 40% ? Detector No-COW
*DangZero 25% 30% ? Detector No
Garbage collection *MarkUS 28% 14.8% Low Preventor Yes
Minesweeper 22.3% 10% ? Preventor No-fork
CRCount 18% 22% High Preventor Yes
Randomization

& BIBOP Allocator

DieHard ? 12% ? Preventor Yes
DieHarder ? 20% ? Preventor Yes
*FreeGuard 115.4% 7.2% Low Preventor Yes
Cling ? 11% ? Preventor ?
Pointer Nullification *DangNULL 127.1% 54%

Low

Detector Yes
FreeSentry ? 42% ? Detector Yes
*DangSan 148.1% 40% Low Detector Yes
*pSweeper 125.2% 15% High Preventor Yes
Dynamic checking CETS ? 48% ? Detector Yes
MemSafe ? 88% ? Detector Yes
One-time-allocator
One time allocator (OTA)는 VA를 reuse하지 않는다. VA를 Reuse하지 않고, Virtual page들을 각 object들에 대해서 배분한다. TLB cache miss가 증가하고, 한번 사용된 VA를 다시 사용하지 못한다는 점과, intensive한 page table modification이 필요하지만, 안정적이고 다른 방법들에 대비하여 상대적으로 빠른 속도를 제공한다는 장점이 있다.
Garbage collection
C/C++에 GC의 매커니즘을 변경시켜서, 효율적으로 UAF버그에 적용될 수 있는 GC기반의 UAF preventor를 만드는 연구들이 있다. 그러나, UAF버그를 효과적으로 막기 위해서는 Boehm-Demers-Weiser GC와 같은 Conservative GC를 사용해야 하는데, 이는 Memory leak을 가져올 수 있는 문제가 있다. 또한 Concurrency issue, 그리고 memory overhead와 같은 문제들이 존재한다.
Randomization & BIBOP Allocator
Secure allocator 혹은 Secure layout of object이라고도 불리는 이 방식은, 오브젝트들은 최대한 randomization된 VA에 배치하는 방식으로 UAF버그를 예방한다. 이 방식에서는 기존의 Free list기반의 방식을 사용하면 UAF버그를 이용한 heap metadata공격을 막지 못함으로, free list가 아닌 BIBOP방식의 bitmap metadata를 사용하여서 Application이 사용하는 메모리 영역과 Allocator 메타데이터 영역을 분리한다. BIBOP searching에 performance overhead가 커지는 문제와, Randomization이기 때문에 100%완벽하지 않다는 문제가 존재한다.
Pointer Nullification
Explicit pointer invalidation이라고도 알려진 이 방법은, 포인터 사이의 reference 관계를 추적하다 한 포인터가 free()되면, 다른 모든 포인터들의 값은 Nullification (invalidation)시킨다. Performance overhead가 크고 이를 해결하더라도 Pointer relationship을 유지하기 위한 Memory overhead가 커지는 문제가 있다.
Dynamic checking (tracking)
이 방식은, 포인터들의 reference count를 동적으로 추적하여서, reference count가 drop된 뒤에만 release를 시킨다. 모든 instrumentation에 체크 코드를 injection시켜야 하기 때문에 큰 performance overhead를 가진다. 굳이 Reference count가 아니더라도, taint tracking과 같은 방식으로 runtime에 동적으로 포인터의 상관관계를 추적하는 기법들을 여기에 분류하였다.

이 외에도 Hardware based 방식의 CHERI, Watchdog와 같은 방식과, Static analysis를 이용한 방법이 있는데, 전자는 특수한 하드웨어가 필요하고, 후자는 false positive의 가능성이 매우 높아 Practical하게 사용하기 힘들다는 단점이 존재한다.