개요
MarkUS는 GC기반의 Memory allocator로써, Free된 메모리를 Quarantine영역에 보관하고 있다가, Dangling pointer가 사라지만 다시 사용하도록 하여서 UAF버그를 Prevent할 수 있는 기법을 제시하였다.
Motivation
기존에 pointer nullification이나 static analysis, dynamic tracking과 같은 방식은 메모리 그리고 성능 면에서 좋지 않았다. MarkUS는 GC가 아니다. GC는 가비지, 즉 사용되지 않지만 free되지 않은 메모리들을 잡아낸다 (Memory leak을 막기 위한 목적). MarkUS는 GC와 비슷한 방식으로 Pointer tracking을 하지만 목적이 UAF버그를 막는 것이다. 따라서 더 Simplify된 코드로 UAF버그들을 검출할 수 있다.
Main Idea
UAF버그를 탐지 하기 위해서 MarkUS는 GC처럼 Mark and sweep을 이용하여서 Reuse할 수 있는 포인터들을 찾아 내었다. 기존 GC와 다른 점은 MarkUS는 프로그램의 free()함수를 기점으로 포인터가 Free됨을 힌트로 삼을 수 있다는 점이다.
Design
사용자가 Object A를 free()한 경우.
- 만약 Object A가 large object인 경우 바로 virtual address를 unmap시키고, reuse할 수 있도록 delete한다.
- 만약 Object A가 Page size보다 작은 small object일 경우, Object A는 Quarantine List에 들어간다.
- 주기적으로 Quarantine list에 있지만, 현재 stack, heap, bss, data, registers에 포인터 reference가 없는 reuse가능한 포인터들을 search한다. 이때 상호참조를 해결하기 위해서, graph traversing을 통해서 pointer들을 walking하여서 free할 수 있는 포인터들을 찾는다. 이 phase는 parallel하게 진행할 수 있다. 만약 Object A에 해당하는 참조가 없을 경우, Object A를 delete하지만 아닐 경우 quarantine list에서 계속 추적한다.
- Mark-and-sweep은 free()를 통해서 얻은 현재 free된 메모리 양을 통해서 heuristic하게 어느 시점에 시작할 것인지를 조절할 수 있다. 정확하지는 않지만, 이 방식을 통해서 Memory overhead의 정도를 어느정도 조절할 수 있다. 또한 dirty bit tracking을 통해서 stop-the-world 시간을 최소화 하였다.
Evaluation
- 전반적으로 Acceptable한 Overhead를 보여주었음. (SPEC CPU 2006기준, performance 14% memory 27%의 오버헤드)
- 특정 벤치에서 (NGINX)에서 매우 큰 Memory leak이 관측되었음. 이는 False-positive때문일 것이라 사료됨.
Conclusion
Limitations
- False-positive가 존재할 수 있다.
- Obfuscated된 Pointer들을 추적할 수 없다.
- Bohem방식의 GC를 사용함으로 Concurrency가 떨어진다.
- High-contention상황에서 성능이 매우 떨어진다.
Positive
- GC방식과 비슷하면서 다른 방식을 사용하여 UAF버그를 어떻게 Quarantine방식을 통해서 막을 수 있는지를 보임
- 이 방식은 후속연구(Minesweeper)들에 영향을 미침