A Sixty-Year-Old Problem#
Memory safety bugs have been the single largest class of security vulnerabilities since the Morris Worm in 1988. Despite decades of research, tooling improvements, and coding standards, they remain the dominant cause of exploitable defects in systems software.
Why this matters for AGIACC: AI, robotics, and critical systems still rest on memory-unsafe foundations. Any company that helps move this risk out of software convention and into enforceable architecture is addressing a durable infrastructure problem.
The Numbers#
- ~70% of all security vulnerabilities reported by Microsoft, Google (Chrome), and the US Department of Defense stem from memory safety issues.
- The MITRE CWE Top 25 (2024) lists Out-of-Bounds Write (CWE-787) and Use-After-Free (CWE-416) in the top 5 most dangerous software weaknesses.
- The US White House (2024) issued a formal report urging the industry to adopt memory-safe approaches, citing the unsustainability of the current model.
Types of Memory Safety Violations#
Spatial Safety Violations#
Accessing memory outside the bounds of an allocated object.
| Type | Description | Example |
|---|---|---|
| Buffer overflow | Writing past the end of an array | char buf[64]; strcpy(buf, very_long_string) |
| Buffer over-read | Reading past the end of an array | Heartbleed (CVE-2014-0160) |
| Out-of-bounds indexing | Array index exceeds allocation size | arr[user_input] without bounds check |
Temporal Safety Violations#
Using memory after its lifetime has ended.
| Type | Description | Consequence |
|---|---|---|
| Use-after-free (UAF) | Accessing freed heap memory | Attacker controls freed region → arbitrary code execution |
| Double free | Freeing the same allocation twice | Heap metadata corruption |
| Dangling pointer | Pointer to stack-allocated object after function returns | Unpredictable data or control flow hijack |
Type Safety Violations#
Interpreting memory as the wrong type.
| Type | Description |
|---|---|
| Type confusion | Casting a pointer to an incompatible type |
| Uninitialized memory read | Using memory before it has been assigned a defined value |
Why C and C++ Are Memory-Unsafe#
C and C++ provide direct, unchecked access to raw memory through pointers. The language specification defines many operations on pointers as undefined behaviour — meaning the compiler is free to assume they never happen, and no hardware or runtime check is required.
Key design choices that create the problem:
- No bounds checking on array accesses or pointer arithmetic
- Manual memory management (malloc/free, new/delete) — the programmer is responsible for lifetimes
- Pointer aliasing — multiple pointers can reference the same memory, creating invisible dependencies
- Implicit type coercion — pointers can be cast freely between types
Why We Can’t “Just Rewrite in Rust”#
Memory-safe languages like Rust, Go, Java, and Swift eliminate many of these issues by design. Rust, in particular, enforces memory safety at compile time through its ownership and borrowing system.
However, rewriting existing systems in safe languages faces fundamental barriers:
- Scale: There are an estimated 2.8 trillion lines of C/C++ code in production worldwide. Rewriting even a fraction would take decades.
- Ecosystem lock-in: Operating system kernels (Linux, Windows, macOS), AI frameworks (PyTorch, TensorFlow), firmware, and embedded controllers are overwhelmingly C/C++.
- Performance characteristics: Some real-time and safety-critical systems depend on the precise memory layout and allocation behaviour that C/C++ provides.
- Interoperability: Even Rust programs typically link against C libraries, inheriting their memory safety properties at FFI boundaries.
The White House report (2024) explicitly acknowledged that rewriting is impractical for the vast majority of existing code, and endorsed hardware-enforced memory safety (specifically citing CHERI) as a complementary path forward.
The Exploit Chain#
A typical memory safety exploit follows a well-understood pattern:
- Trigger — The attacker provides input that causes a spatial or temporal violation (e.g., a buffer overflow).
- Primitive — The violation is leveraged to achieve a useful primitive: arbitrary read, arbitrary write, or code pointer corruption.
- Control flow hijack — The attacker overwrites a return address, function pointer, or vtable to redirect execution.
- Payload — The hijacked control flow executes attacker-chosen code or chains existing code gadgets (ROP/JOP).
Modern exploit mitigations (ASLR, stack canaries, DEP/NX) make this chain harder but not impossible. Sophisticated attackers routinely bypass all of them.