That's the core problem.
The mechanisms mentioned are primarily attack detection and mitigation techniques rather than prevention mechanisms. Bugs can't be exploited as easily, but they still exist in the codebase. We're essentially continuing to ship faulty software while hoping that tooling will protect us from the worst consequences.
Couldn't one argue that containers and virtual machines also protect us from exploiting some of these memory safety bugs? They provide isolation boundaries that limit the impact of exploits, yet we still consider them insufficient alone.
It's definitely a step in the right direction, though.
The paper mentions Rust, so I wanted to highlight a few reasons why we still need it for people who might mistakenly think this approach makes Rust unnecessary:
- Rust's ownership system prevents memory safety issues at compile time rather than trying to mitigate their effects at runtime
- Rust completely eliminates null pointer dereferencing
- Rust prevents data races in concurrent code, which the paper's approach doesn't address at all
- Automatic bounds checking for all array and collection accesses prevent buffer overflows by design
- Lifetimes ensure pointers are never dangling, unlike the paper's approach which merely tries to make dangling pointers harder to exploit
So, we still need Rust, and we should continue migrating more code to it (and similar languages that might emerge in the future). The big idea is to shift bug detection to the left: from production to development.