Memory safety is a common topic when discussing programming languages. However, it's not well-defined what is being talked about.
- Compiler-based static analysis.
- Compiler-based code creation that is expected to be memory-safe.
- Runtime mechanisms like garbage collection and array bounds checking.
- Security hardening. Aka, just trying to make the system safe against attackers.
Lisp, traditionally memory safe language, has features that may allow for memory corruption. C/C++, traditionally considered a memory unsafe language, can also be done safely. Static analysis tools, strict code review and good runtime detectors do well. This demonstrates that memory safety isn't the sole responsibility of the compiler or the runtime - it's a coordinated effort. The author of this post comes from a project called Hardened Linux that's goal is to create a version of Linux that is resistant to compromise.
The lifecycle of vulnerability has a few stages:
-
Identifying a bug and assessing whether it can be exploited.
- Writing a PoC.
- Adapting the PoC into a stable exploit.
- Digital arms dealers integrating it into a weaponizing framework.
Most of the effort in preventing vulnerabilities is around a bug not existing in the first place. However, there are other ways to keep users safe besides removing bugs - we could just make them unexploitable to get RCE.
Fil-C is a customization on Clang/LLVM compiler that catches many memory safety vulnerabilities by doing a combination of garbage collection and capability checking on pointer accesses made by Epic Games. Buffer overflows, type confusions, use after frees and many classes of vulnerabilities can be prevented using this.
Another strategy is around mitigation techniques at the hardware or software level. NX, CET, etc. are good examples of this. Many vulnerabilities would have been harder to exploit with some of these protections, if not outright impossible. Every protection is another roadblock that makes it less likely that exploitation will occur.
Practically speaking, I like this take on simply rewriting software: "Rewriting software and libraries using memory-safe languages is an expensive endeavor. If you have thoroughly considered this approach and decide to proceed, please consider rewriting them in Lisp/Scheme." Great post on the practically on exploiting systems!