Description
Unikernels are gaining traction as an operating system paradigm which creates single-purpose bootable images from an application
and a lightweight library operating system. This work investigates the state of heap security in unikernels written in memory
unsafe languages. The heap security of unikernel systems is especially relevant, because of their design choice to omit a privilege
separation between kernel and user mode. As heap exploits allow the attacker to overwrite arbitrary memory, a heap bug in the application
can be used to corrupt kernel data in a unikernel environment. Additionally, control-flow hijacking yields maximal privileges. Heap
exploitation typically targets object metadata, such as size information and list pointers, which can be modified to plant overlapping
or arbitrarily placed chunks in the allocator. Hence, we examine the resilience against heap metadata corruption based attacks and present
proof-of-concept exploits against a selection of heap allocators in use in prevalent unikernel implementations. Our attacks assume a metadata
corruption vulnerability or misuse of (de-)allocation primitives in the application or library operating system. Our findings indicate that
prevalent unikernels such as HermiTux, OSv and Unikraft take insufficient countermeasures against such attacks. In these unikernels, metadata
corruption can be exploited to allocate (nearly) arbitrary chunks, or, in the case of Unikraft, directly overwrite an arbitrary address with
an attacker controlled value. To combat this problem, we propose an allocator hardening based on metadata isolation. Our design prevents metadata
corruption by extracting vulnerable in object metadata and placing it inside of write protected memory. Unlike related approaches based on hardware
virtualization extensions, our work investigates Memory Protection Keys (MPK) for the memory protections. MPK facilitate a more lightweight protection
switch inside of functions authorized to modify metadata. This approach could integrate well into recent MPK-based intra-unikernel isolation mechanisms.
Furthermore, our design provides a highly flexible mapping between heap objects and metadata, allowing the mechanism to be implemented on a variety of
heap allocators. We implemented the extension in two of Unikraft's heap allocators, TLSF and BBUDDY. Our security evaluation shows that our proof-of-concept
exploits can no longer succeed, as the corruption of metadata outside of trusted functions is mitigated. To achieve this security benefit, our modifications
to BBUDDY come with a modest performance cost of about 26ns and 36ns for malloc and free, respectively. During a batch of SQLite insert queries, this amounts
to a slowdown of 4–13% for 10,000–200,000 queries. The corresponding costs for TLSF are 28ns, 43ns and a slowdown of 14–24%. For this allocator, we
analytically compute a per object overhead of about 16B. Experiments have shown that this number varies in practice due to size class up-alignment. In a test
with a batch of 400,000 insert queries, our extension encurred a negligible overhead of 0.95% overall. We believe that our design provides much needed heap
security benefits at a justifiable cost to the realm of unikernels.
|