Rudra: Finding Memory Safety Bugs in Rust at the Ecosystem Scale
Citation: Yechan Bae, Youngsuk Kim, Ammar Askar, Jungwon Lim, Taesoo Kim (10/26/2021) Rudra: Finding Memory Safety Bugs in Rust at the Ecosystem Scale. SOSP '21: Proceedings of the ACM SIGOPS 28th Symposium on Operating Systems Principles (RSS)
DOI (original publisher): 10.1145/3477132.3483570
Semantic Scholar (metadata): 10.1145/3477132.3483570
Sci-Hub (fulltext): 10.1145/3477132.3483570
Internet Archive Scholar (search for fulltext): Rudra: Finding Memory Safety Bugs in Rust at the Ecosystem Scale
Download: https://dl.acm.org/doi/10.1145/3477132.3483570
Tagged: Computer Science
(RSS) programming languages (RSS)
Summary
Rust has a safe and unsafe mode; the former guarantees memory safety but the latter gives the programmer more control over the system, often needed for high-performance. For example, the standard library uses unsafe code internally. The authors build Rudra, a static analyzer for unsafe Rust. They find a large amount of bugs in real-world unsafe Rust code.
Problem
- There is a tradeoff between safety and control. Giving programmer low-level control makes it harder for compiler to check safety.
- Rust language balances this with safe and unsafe rust.
- In unsafe rust, programmer is responsible for memory safety, but has full control.
- Safety of a program depends on safety of all unsafe code.
- Unsafe code either exposed directly in API or wrapped in a safe API. Bugs in the wrapper are serious problems, because user can cause memory safety bug without typing
unsafe
.
Solution
- Rudra: Static analyzer for unsafe Rust.
- Checks for these bugs:
- Panic-unsafety: incorrect resource deallocation in compiler-inserted invisible code paths.
- Higher-order invariant bug: unchecked assumptions on user-provided higher-order values. E.g., assuming comparator is reflexive, anti-symmetric, and transitive.
- Send/sync variance bug: incorrect condition for manual thread safety assertions.
- Challenges:
- Incomplete definitions (e.g. higher-order invariants are rarely specified).
- Some information is not available in later compilation stages (e.g. types get dropped after checking).
- Use high-level IR to find unsafe blocks and mid-level IR to find callgraph and other things.
- Unsafe-dataflow checker checks panic-unsafety and higher-order invariant bugs; send/sync variance bug requires its own checker.
- Checks for these bugs:
Evaluation
- Run on all Rust crates.
- 2 bugs in Rust standard library.
- 112 Rust security advisories.
- 76 CVEs.
- Compare with dynamic fuzzers, Fuzzers and Miri, and other static analyzers, UAFChecker.
- None found bugs that Rudra found.
- Miri found bugs that Rudra didn't find.
= Limitations
- Rudra is not exhaustive.
- Rudra has a high false-positive rate (50% for high precision, 80% for high scalability).
- Rudra finds Bugs at the definition site: pro and con.
- Is the buggy code-path in API definition actually invoked by callers?