immunant / IA2-Phase2

5 stars 0 forks source link

IA2 Sandboxing Runtime

IA2 (or Intent-capturing Annotations for Isolation and Assurance) is a runtime and set of tools for compartmentalizing C/C++ applications to provide coarse spatial memory-safety.

Applications typically use many third-party C/C++ libraries that may introduce memory-safety vulnerabilities if developers don't have the resources to exhaustively audit them. Putting everything in a single process means that a vulnerability in one library can compromise another, and that's a problem for programs that handle security-sensitive information. The IA2 sandbox splits applications into isolated compartments and uses CPU hardware features (Memory Protection Keys on x86-64) to forbid cross-compartment memory accesses. Compartments are delineated along pre-existing boundaries (at the shared library level), avoiding the need to rearchitect a codebase, and source-code annotations are used to mark variables that are intentionally shared between compartments. The runtime also ensures that each set of shared libraries in a compartment uses a distinct region of memory for its stack, heap, static, and thread-local variables.

Sandboxing workflow

IA2 uses source-code transformations as part of the build process to sandbox programs. Our rewriter tool processes a codebase's source files before each build to produce a set of intermediate sources with annotations for compartment transitions at cross-DSO (dynamic shared object) calls, which we refer to as call gates. These intermediate sources are then passed on to a build system using off-the-shelf compilers with some additional flags and the IA2 runtime linked in to create the compartmentalized program. See the design doc for details.

This workflow treats intermediate sources as build artifacts so that the only annotations that need to be checked-in are those that can't be inferred. These are primarily annotations for shared variables and cross-DSO indirect calls when round-tripping function pointers through void *. For the latter, the rewriter also does type-system transformations to turn missing annotations into compiler errors and avoid accidental miscompartmentalization. In compartmentalized programs, cross-compartment memory accesses kill the process, but they also support a permissive mode, which just logs the accesses to aid developers adding shared variable annotations.

Features

Usage

See this doc for instructions on building the tools and tests in this repo. For more detailed instructions on the compartmentalization process, see the usage doc.