Finding errors in software is a difficult problem: millions of dollars are spent in testing and debugging, yet latent bugs continue to be discovered even in thoroughly tested programs. Apart from the undesirable effects of producing incorrect results, crashing systems, and corrupting data, bugs also raise security concerns: memory-safety errors like buffer overruns and stale pointer dereferences can be exploited by malicious agents to acquire confidential data or seriously compromise the target system, sometimes in undetectable ways.
A key feature of the C programming language is that it allows low-level control over memory usage and runtime behavior; this flexibility is crucial for many programming settings, such as at the system level, and is one reason why C programs continue to be widely used today. However, this flexibility is achieved at the price of safety: the language syntax is too weak to prevent type errors and memory-safety errors from occurring at runtime.
This work explores three related approaches to detect errors in C programs via runtime monitoring. The Memory-Safety Enforcer is a tool that detects memory-safety errors at runtime, and can be used for both security and debugging. The Sensitive Location Checker is a security tool that prevents invalid memory accesses from overwriting sensitive locations that are vulnerable to attack. The Runtime Type Checker is a debugging tool for detecting bugs that manifest themselves as type errors at runtime. All three approaches tag memory locations with auxiliary information at runtime, and make use of static analysis to improve performance and coverage by eliminating unnecessary runtime instrumentation.