Code-Centric Domain Isolation : a hardware/software co-design for efficient program isolation
Authors:   , Vilanova García Lluís 
Published: July 2023

Current software systems contain a multitude of software components: from simple libraries to complex plugins and services. System security and resiliency depends on being able to isolate individual components onto separate domains.
Conventional systems impose large performance and programmability overheads when isolating components. Importantly, when performance and isolation are at stake, performance often takes precedence at the expense of security and reliability.
These performance and programmability overheads are rooted at the co-evolution of conventional architectures and OSs, which expose isolation in terms of a loose "virtual CPU" model. Operating Systems (OSs) expose isolation domains to users in the form of processes. The OS kernel is isolated from user code by running at a separate privileged level. At the same time, user processes are isolated from each other through the utilization of different page tables. The OS kernel then multiplexes processes across the available physical resources, providing processes the illusion of having a machine for their exclusive use. Given this virtual CPU model, processes interact through interfaces designed for distributed systems, making their programming and performance poorer.
The architectural foundations used for building processes impose performance overheads in the excess of 10× and 1000× compared to a function call (for privilege level and page table switches, respectively). Even more, not all overheads can be attributed to the hardware itself, but to the inherent overheads imposed by current OS designs; the OS kernel must mediate cross-process communications through expensive Inter-Process Communication (IPC) operations, which deviate from the traditional synchronous function call semantics. Threads are bound to their creating process, and invoking functionality across processes requires costly OS kernel mediation and application developer involvement to synchronize and exchange information through IPC channels.
This thesis proposes a hardware and software co-design that eliminate the overheads of process isolation, while providing a path for gradual adoption for more aggressive optimizations. That is, it allows processes to efficiently call into functions residing on other isolation domains (e.g., processes) without breaking the synchronous function call semantics. On the hardware side, this thesis proposes the CODOMs protection architecture. It provides memory and privilege protection across software components in a way that is at the same time very efficient and very flexible. This hardware substrate is then used to propose DomOS, a set of changes to the OS at the runtime and kernel layers to allow threads to efficiently and securely cross process boundaries using regular function calls. That is, a thread in one process is allowed to call into a function residing in another process without involving the OS in the critical communication path. This is achieved by mapping processes into a shared address space and eliminating IPC overheads through a combination of new hardware primitives and compile-time and run-time optimizations.
IPC in DomOS is up to 24× times faster than Linux pipes, and up to 14× times faster than IPC in L4 Fiasco.OC. When applied to a multi-tier web server, DomOS performs up to 2.18× better than an unmodified Linux system, and 1.32× on average. On all configurations, DomOS provides more than 85% of the ideal system efficiency.
Els sistemes software d'avui en dia contenen una multitud de components software: des de simples llibreries fins a plugins o serveis complexos. La seguretat i fiabilitat d'aquests sistemes depèn de ser capaç d'aïllar cadascun d'aquests components en un domini a part. L'aïllament en els sistemes convencionals imposa grans costos tant en el rendiment com en la programabilitat del sistema. És més, tots els sistemes solen donar prioritat al rendiment sobre qualsevol altre consideració, degradant la seguretat i fiabilitat del sistema. Aquests costos en rendiment i programabilitat són deguts a la co-evolució de les arquitectures i Sistemes Operatius (SOs) convencionals, que exposen l'aïllament en termes d'un model de "CPUs virtuals". Els SOs encarnen aquest model a través dels processos que proprcionen. El SO s'aïlla del codi d'usuari a través d'un nivell de privilegi separat. Al mateix temps, els processos d'usuari estan aïllats els uns dels altres al utilitzar taules de pàgines separades. El nucli del SO multiplexa aquests processos entre els diferents recursos físics del sistema, proporcionant-los la il·lusió d'estar executant-se en una màquina per al seu ús exclusiu. Donat aquest model, els processos interactuen a través d'interfícies que han estat dissenyades per a sistemes distribuïts, empitjorant-ne la programabilitat i rendiment. Els elements de l'arquitectura que s'utilitzen per a construïr processos imposen costos en el rendiment que superen el 10x i 1000x en comparació amb una simple crida a funció (en el cas de nivells de privilegi i canvis de taula de pàgina, respectivament). És més, part d'aquests costos no vénen donats per l'arquitectura, sinó pels costos inherents al disseny dels SOs actuals. El nucli del SO actua com a mitjancer en la comunicació entre processos a través de primitives conegudes com a IPC. El IPC no és només costós en termes de rendiment, sinó que a més a més es desvia de les semàntiques tradicionals de crida síncrona de funcions. Tot "thread" està lligat al procés que el crea, i la invocació de funcionalitat entre processos requereix de la costosa mediació del SO i de la participació del programador a l'hora de sincronitzar "threads" i intercanviar informacio a través dels canals d'IPC. Aquesta tesi proposa un co-disseny del programari i del maquinari que elimina els costos de l'aïllament basat en processos, alhora que proporciona un camí per a l'adopció gradual d'optimitzacions més agressives. És a dir, permet que qualsevol procés faci una simple crida a una funció que està en un altre domini d'aïllament (com ara un altre procés) sense trencar la la semàntica de les crides síncrones a funció. Aquesta tesi proposa l'arquitectura de protecció CODOMs, que proporciona protecció de memòria i privilegis entre components de programari d'una forma que és, alhora, eficient i flexible. Aquest substrat del maquinari és aleshores utilitzat per proposar DomOS, un conjunt de canvis al SO al nivell del "runtime" i del nucli que permeten a qualsevol "thread" fer crides a funció de forma eficient i segura a codi que resideix en d'altres processos. És a dir, que el "thread" d'un procés pot cridar una funció d'un altre procés sense haver de passar pel SO en el seu camí crític. Això s'aconsegueix a través de mapejar tots els processos en un espai d'adreces compartit i d'eliminar tots els costos d'IPC a través d'una combinació de noves primitives en el maquinari i d'optimitzacions en temps de compilació i en temps d'execució. El IPC a DomOS és fins a 24x més ràpid que les pipes a Linux, i fins a 14x més ràpid que el IPC al SO L4 Fiasco.OC. Si s'aplica el sistema a un servidor web multi-capa, DomOS és fins a 2.18x més ràpid que un sistema Linux no modificat, i 1.32x més ràpid de mitjana. En totes les configuracions, DomOS proporciona més del 85% de la eficiència d'un sistema ideal.