PACSan Memory Safety Sanitizer
- PACSan is a memory safety sanitizer that uses ARM Pointer Authentication to embed cryptographic metadata directly into pointers, ensuring comprehensive spatial and temporal safety.
- It enforces runtime checks via constant-time metadata lookups during pointer dereference and deallocation, achieving negligible false negatives and zero false positives.
- Evaluated on benchmarks like Magma and SPEC CPU2017, PACSan demonstrates improved performance (+84% runtime overhead) and low memory overhead (1.92×) compared to traditional sanitizers.
PACSan is a memory safety sanitizer that utilizes ARM Pointer Authentication (PA) hardware to enforce comprehensive spatial and temporal memory safety with low runtime and memory overheads. Designed to detect and prevent memory corruption vulnerabilities in C/C++ programs—including out-of-bounds accesses and use-after-free errors—PACSan integrates metadata directly into pointers using cryptographic signatures, thereby eliminating the bottlenecks associated with explicit per-pointer metadata propagation. PACSan was systematically evaluated on the Magma, Juliet, Nginx, and SPEC CPU2017 test suites, demonstrating zero false positives, negligible false negatives, and significantly improved performance and memory efficiency compared to state-of-the-art sanitizers (Li et al., 2022).
1. Objectives and Threat Model
The principal objective of PACSan is to enforce full memory safety during program execution, specifically:
- Spatial safety: Ensuring every pointer dereference remains within the bounds of its associated object.
- Temporal safety: Ensuring pointers do not reference deallocated (dead) memory objects.
PACSan is engineered to:
- Avoid false positives, ensuring that no benign code behavior is erroneously rejected.
- Drive false negatives—missed safety violations—to negligible levels.
- Maintain performance overhead sufficiently low for integration into development, regression, and fuzzing workflows.
The threat model covers arbitrary memory corruption in heap, stack, and global regions due to out-of-bounds accesses, use-after-free, double-free, or invalid free. PACSan instruments all pointer uses: allocation, propagation, and dereference. Non-instrumented code can only be corrupted via undetected memory-safety bugs.
2. Pointer Metadata Representation and Sealing
PACSan stores all metadata per object in a global table, with metadata comprising:
- Base address (64 bits)
- Object size (32 bits)
- “Birthmark”: a 32-bit pseudo-random tag unique to the allocation
This 128-bit metadata tuple is not propagated in shadow memory or auxiliary structures. Instead, with each pointer, PACSan "seals" the metadata table index directly into the pointer representation by leveraging ARMv8.3-A Pointer Authentication instructions:
- PACDA / PACDZA / PACGA (Pointer Authentication Code instructions): Compute a cryptographic MAC over the pointer address and the birthmark (serving as a modifier), storing the resulting PAC bits in the high-order unused address bits. Typical VA configurations provide ~24 PAC bits (on a 39-bit VA system).
The PAC bits form a direct index into the metadata table:
- At allocation: PACSan picks a birthmark, computes its seal (PAC), checks for collisions in the table, and retries as necessary to guarantee two live objects never share a slot.
- Upon pointer dereference: The birthmark is extracted, the PAC code verified and stripped (using AUTDA), and the index used for a fast, constant-time metadata lookup.
This approach removes the overheads associated with explicit metadata tracking in software instrumentation schemes.
3. Memory Safety Enforcement Algorithms
PACSan performs run-time safety checks at pointer dereference and object deallocation:
- Pointer Dereference:
- Extract the packed birthmark from the pointer payload.
- Authenticate and strip the PAC via AUTDA; trap on failure, signaling a violation.
- Use the PAC bits as an index into
meta_table, retrieving base, size, and birthmark. - Verify offset is within ; else, report violation.
- Object Deallocation (free):
- Authenticate pointer as above to ensure integrity.
- Zero out the corresponding metadata table entry to mark object as dead.
- Invoke the underlying free on the object base address.
PACSan’s layout and hashing guarantee that no two live objects map to the same metadata slot (false positives are structurally excluded). False negatives are negligible and arise only for intra-object (sub-object field) overflows, e.g., overflows within struct fields; empirical evaluation shows these comprise less than 1.2% of spatial bugs in Juliet.
4. Implementation Details
PACSan is implemented via an LLVM 14 compiler pass that recognizes all allocations (heap, stack, global), pointer dereferences, and frees. Instrumentation details:
- At allocation: Generates a birthmark, computes the PAC seal, populates the global metadata table, and seals the pointer.
- At dereference or free: Inlines AUTDA for authentication, counters extract, and table lookup for bounds check.
- Runtime provides a large metadata table mapped as shadow memory; startup code initializes metadata for static globals and marks the GOT read-only.
Interop with external/uninstrumented code is handled by stripping PAC before module boundary crossings and re-tagging on return, ensuring compatibility.
5. Security Evaluation
PACSan’s security was quantified across diverse benchmark suites:
- Magma (real-world Proof-of-Concepts): Found all flaws detected by ASan, and discovered 45 additional out-of-bounds PoCs in PHP not detected by ASan due to redzone limitation.
- Juliet (systematic CWE tests): Evaluated over stack/heap overflow, underflow, use-after-free, double/invalid free, null dereference; reported 0% false positives, ≤1.18% false negatives (on CWE121 sub-object field overflows), and ≈0% elsewhere.
For comparison, competing tools exhibited significantly higher false negatives: up to 16.97% (ASan, stack overflow), >40% (LowFat, heap overflow), and >70% (Memcheck, globals).
The main undetected category is intra-object overflow; per-field bounds metadata (as in SoftBound) would be needed. Table saturation (>2²⁴ concurrent objects) could occur in pathological cases but is mitigated by table chaining or multi-stage indirection.
6. Performance and Memory Overhead
PACSan performance was assessed on Apple M1 (hardware ARM PA) and x86:
Runtime Overhead (geomean):
| Tool / Mode | Runtime Overhead (ARM) | Memory Overhead (ARM) |
|---|---|---|
| PACSan (full) | +83.9% | +191.9% |
| PACSan (write-only) | +38.0% | +187.7% |
| ASan (ARM) | +90.4% | +1,755% |
| HWASan (ARM) | +132.8% | +7.3% |
| Memcheck (x86) | +2,036% | +610.6% |
| LowFat (x86) | +26.8% | +147.7% |
PACSan achieves lower or comparable runtime overhead to ASan and HWASan, but with much lower memory overhead—1.92× versus 17.55× for ASan. This low overhead derives from:
- Zero per-pointer metadata propagation cost (PAC bits are inherent in pointer).
- Constant-time metadata lookup.
- Hardware acceleration for PAC computation (~2.3 ns per PAC/AUTDA operation), requiring only two operations per dereference.
A plausible implication is that PACSan’s hardware offloaded design is especially advantageous for environments with stringent performance and scaling constraints.
7. Comparative Analysis with Existing Sanitizers
A summary comparison highlights key properties and limitations:
| Sanitizer | Spatial Safety | Temporal Safety | False Positives | False Negatives | Runtime Overhead | Memory Overhead |
|---|---|---|---|---|---|---|
| PACSan | Yes | Yes | 0% | Negligible (<1.2%) | Moderate (~84%) | Low (1.92×) |
| ASan | Yes | Partial | Nonzero | High (>10% in cases) | High (~90%) | Very high (17.55×) |
| HWASan | Yes (tagged) | Partial (no stack/globals) | Nonzero | High in some cases | Higher (~133%) | Low (7.3%) |
| LowFat | Partial | No | Nonzero | High (esp. heap) | Lower (26.8%) | Moderate (147.7%) |
| Memcheck | Partial | Partial | High | Very high | Extreme (2,036%) | High (610.6%) |
| SoftBound+CETS | Yes | Yes | Significant | Moderate | Very Low | Negative/Erratic |
PTAuth, another PA-assisted tool, protects only heap temporal safety and requires manual scanning for metadata, lacking spatial checks.
PACSan’s use of ARM Pointer Authentication with “sealed” metadata indices provides simultaneous spatial and temporal safety, no need for per-pointer metadata propagation, constant-time metadata table lookups, and no hardware changes beyond existing ARM PA (Li et al., 2022). These improvements yield negligible false negatives and zero false positives in empirical evaluations.
A plausible implication is that PACSan’s methodology—leveraging cryptographic pointer sealing and hardware PA support—constitutes a new practical baseline for memory safety in ARM architectures, addressing legacy sanitizer bottlenecks without sacrificing scalability or compatibility.