Practical Methods for Automatic Intra-Process Compartmentalization with MPK
Many attacks on modern software begin when the application processes untrusted data. Often attackers exploit a lack of memory safety in the underlying program, which is frequently written in unsafe languages, like C or C++. While memory-safe alternatives, like Rust, are emerging as a viable replacement for these languages, many applications implemented in a memory-safe language will still need to rely on external code that lacks memory safety until safe alternatives exist. Unfortunately, process-level isolation can incur substantial overheads, leading to high risk components often being embedded within the process, thereby exposing the rest of the application to memory corruption by an adversary. Today, new hardware features, like Memory Protection Keys, are being used to create efficient intra-process data isolation schemes. However, adapting existing software to correctly enforce the desired isolation policy can be challenging due to the complex inter-procedural data flows present within modern applications.
To address these issues, we propose a general architecture for compartmentalizing memory- safe applications from components written in memory-unsafe languages using efficient hardware enforcement. Our architecture limits memory access to these components in a manner that aligns with the principle of least privilege, only granting them access to their own private data and data directly shared with them from the memory-safe portion of the application.
Next, we identify cross-compartment data flow as one of the key challenges to automating intra-process compartmentalization. We demonstrate how type systems can be used to guide refactoring efforts and identify cross-compartment data flows that conflict with the desired isolation policy. Further, we show how a simple, yet practical, dynamic analysis can be used to automate the process of isolating program data without significant effort by programmers. Our extensive evaluation on the Servo web browser demonstrates our system’s practicality, scalability, and efficiency, as it automatically compartmentalizes one of the largest Rust programs available, while only introducing overheads between 1-11.5% on average.