Understanding and Detecting Memory Bugs in Rust
Rust is a young programming language designed for systems software development. Its main design goal is to achieve runtime performance as good as C while offering better memory and thread safety using a linear type system and strict compile-time checking. Rust has become increasingly popular among developers of safety-critical software, such as OSs, browsers, and block-chain systems. However, both practitioners and researchers know little about the status of memory bugs in real-world Rust programs. For example, do Rust’s compile-time checks eliminate all memory bugs? If not, do memory bugs in Rust exhibit certain patterns? How to identify and eliminate them? This project seeks to answer these questions. In particular, it aims to achieve a better understanding of common mistakes made by Rust programmers and build novel techniques to catch memory bugs missed by Rust’s compile-time checks. The outcome will influence how Rust evolves, guide how developers program Rust safely, and improve the safety of the Rust ecosystem.
Rust’s safety mechanisms are sound, but sometimes they are too strict and prevent flexible control over low-level resources. To mitigate this problem, Rust allows developers to bypass its compiler checks using unsafe code. A function can be declared as unsafe. A piece of code inside a safe function can be unsafe, known as interior unsafe, where the unsafe code is encapsulated internally and treated as safe externally. Unfortunately, unsafe code and interior unsafe code can lead to memory bugs since they bypass Rust’s safety checks. This project aims to better understand Rust’s memory bugs and build novel static/dynamic tools to combat Rust’s memory bugs. This project contains three components: (1) a comprehensive taxonomy of Rust’s memory bugs, (2) novel static techniques to identify memory bugs in interior unsafe functions, and (3) novel fuzzing techniques enhanced by the safe/unsafe information in Rust.