Skip to content

Shreds: Fine-grained Execution Units with Private Memory

HardwareIEEE Symposium on Security and Privacy23 minAdvancedOpen on YouTube ↗

Industry experts analyze emerging threats surrounding Shreds: Fine-grained Execution Units with Private Memory.

Summary

### Overview Modern application development frequently integrates multiple third-party libraries and components within a single process. However, the standard OS model only distinguishes between processes (separate address spaces) and threads (shared address space). This shared address space enables 'in-process memory abuse,' where compromised or malicious components access sensitive data (such as OpenSSL private keys or login passwords) or invoke private internal APIs belonging to other components within the same process.

To address this limitation without paying the high IPC overheads of process-level isolation or the usability constraints of Intel SGX and ARM TrustZone, the researchers present 'Shreds.' Shreds are fine-grained execution units that represent arbitrary scoped execution segments of a thread, augmented with private memory pools (termed 's-pools') isolated from the rest of the process.

### Key Topics - **In-Process Memory Abuse**: Malicious or compromised in-process components stealing secret data or executing private code. - **Limitations of Existing Defenses**: Process-based isolation incurs expensive IPC and complex multi-process re-architecting; software fault isolation (like Google Native Client) cannot easily handle dynamically generated or external code; hardware enclaves (Intel SGX, ARM TrustZone) suffer from semantic gaps or strict restrictions like forbidding system calls. - **Shreds & S-Pools**: Introducing segmented thread execution with dedicated private memory pools allocated from the shared address space. - **Hardware-Assisted Domain Isolation**: Utilizing ARM Memory Domains (and Intel Memory Protection Keys) to enforce memory isolation efficiently without multiple page tables or nested paging.

### Technical Details The Shreds architecture consists of two primary components: 1. **S-Driver**: An OS module responsible for runtime events, access control, and memory isolation. - **Memory Domain Binding**: ARM architecture provides 16 memory domains checked via domain access control registers. Because domains are scarce, S-Driver statically binds an accessible domain to each CPU core and reuses it across multiple s-pools. - **Critical Path Optimization**: Instead of altering page table entries and invalidating TLBs, S-Driver controls access by fast manipulation of domain access control registers (a single-instruction operation). Domain faults are resolved lazily via a domain fault handler to distinguish legitimate accesses from attacks. - **Secure Stacks and Interfaces**: Provides each shred with an isolated stack allocated inside its s-pool and intercepts system interfaces (like debugging or physical memory/IO access) that could bypass domain checks. 2. **S-Compiler**: A compiler module that verifies proper API usage, associates s-pools with valid shred enter call sites at compile time (storing metadata in a dedicated ELF section to prevent unauthorized s-pool access), hardens control flow, and checks data flows to prevent sensitive data leakage. 3. **API Design**: Developers use lightweight APIs including `s_enter` and `s_exit` (for scoping shred execution) alongside pool management functions (`s_alloc`/`s_free` wrappers, such as `sds_init` and `sds_free`). Multiple shreds can also securely share an s-pool when explicitly configured.

### Evaluation and Takeaways The system was evaluated on a Raspberry Pi 2 (ARM Cortex-A7, 1 GB RAM) across 5 different software packages, including the lighttpd web server and OpenSSL. Key evaluation takeaways include: - **Adoption Effort**: Minimal developer intervention was required—an average of 21 lines of code changed and roughly 32 minutes to instrument each application. - **Performance**: Shred execution introduced less than 5% execution slowdown and less than 1% memory overhead. Shred creation/entry APIs ran slightly faster than `clone()` (about twice the runtime of `getpid()`), while s-pool allocation ran comparably to `mmap()`.

Related talks