Preventing Use-after-free with Dangling Pointers Nullification


Byoungyoung Lee, Chengyu Song, Yeongjin Jang, Tielei Wang, Taesoo Kim, Long Lu, Wenke Lee
Proceedings 2015 Network and Distributed System Security Symposium

개요

DangNull은 포인터와 오브젝트의 관계를 추적해서, 나중에 Object가 free될 경우 연관된 모든 오브젝트들을 Nullification시켜서 Use-after-free 버그가 시스템에 치명적인 영향을 미치지 않도록 하였다.

Motivation

Use after free 버그는 C나 C++에서 자주 발생하는 버그지만, 그 파급력에 불구하고, Detect하는 것은 매우 어려운 일이다. 이 문제를 해결하기 위해서 One time allocatorGarbage collection과 같은 방식들이 많이 사용되지만, OTA는 Virtual address exhaustion문제가 발생하며 Garbage collection방식은 Pointer obfuscation이나 False positive detection문제를 해결하기 힘들다.

Importance

기존의 방식은 Runtime check나 Dynmaic analysis를 통해서 UAF문제를 해결하였다. 그러나 이러한 방식은 Metadata 크기가 엄청 커지는 문제가 있으며, Performance문제가 생기는 한계가 있었다. Memory error detector와 같은 경우에는, Corner case에서 자유롭지 못하였다.

Main Idea

DangNull은 포인터의 연결관계를 Static time 그리고 Runtime에 자동으로 추적하여서, 포인터가 Free될 경우 연관된 모든 포인터를 Nullification시킨다.

Design

Static Instrumentation
Bynary code를 분석해서, Allocation/Deallocation time에 object와 pointer의 관계를 추적하는 Metadata (Shadow objects)를 채워넣는 명령어(trace)를 삽입하도록 LLVM IR Compiler를 수정하였다. DangNull은 Stack object는 추적하지 않았는데, 이는 대부분의 Stack object들은 매우 짧은 lifetime을 가지기 때문에, 치명적인 영향을 미치지 못한다고 생각했기 때문이다 (추가적으로 성능적으로 큰 영향을 줄 것이다).
Runtime Library
Static타임에 넣어둔 trace함수를 통해서 DangNull은 Runtime에 포인터 Reference를 추적하였다. Runtime trace()함수는 Pointer -> Objects을 저장하는 RB Tree를 이용해서 포인터<->오브젝트 관계를 추적한다. 추적된 관계는 나중에 포인터를 Free할때, Object들에 대해서 Nullification을 통해서 Null값을 저장하게 되고, 나중에 Nullify된 포인터에 접근하는 경우 SIGSEV를 내게 된다.

Conclusion

  • 다른 시스템에서 Stack을 추적하지 않는다면, DangNull과 비교해서 어떤 성능적 이점을 보여줄 것인가? 즉 DangNull이 빠른 이유가 Stack 추적과 같은 Optimization때문인 것인가 아니면 DagnNull의 Design적인 측면인 것인가?
  • Static Instrumentation이 C/C++ Type signature에 의존하기 때문에, Pointer casting 혹은 Pointer arithmetic이 있을 경우 추적하지 못한다는 단점이 있다. 또한 언어에 종속적이라는 문제점이 있다.