Facilitating the Spread of Knowledge and Innovation in Professional Software Development

Write for InfoQ


Choose your language

InfoQ Homepage News Static Analyzer Rudra Found over 200 Memory Safety Issues in Rust Crates

Static Analyzer Rudra Found over 200 Memory Safety Issues in Rust Crates

This item in japanese

Developed at the Georgia Institute of Technology, Rudra is a static analyzer able to report potential memory safety bugs in Rust programs. Rudra has been used to scan the entire Rust package registry and identified 264 new memory safety bugs.

Rust is a language designed to be memory safe, thanks to a number of features restricting the possibility of creating null pointers, dangling pointers, or data races. All of those features are based on Rust's ownership-based memory management model and type system, which enable the compiler to flag any unsafe usage.

While the Rust compiler goes to great lengths to ensure Rust programs are free from undefined behaviour, Rust allows programmers to write code that is not constrained by those guarantees including it in an unsafe region. This is a language feature necessary to write system software that requires low-level hardware access, such as directly accessing pointers. In other words, unsafe regions provide a mechanism to temporarily bypass the compiler's guarantees.

This is where unsound behaviour may live in Rust programs, explain the creators of Rudra:

Rust’s safety guarantee relies on the soundness of all unsafe code in the program as well as the standard and external libraries, making it hard to reason about their correctness. In other words, a single bug in any unsafe code breaks the whole program’s safety guarantee.

It is estimated that 25-30% of Rust packages use unsafe, which makes them at risk of unsoundness. While having all potentially unsound code isolated within unsafe regions makes it possible to review it in great depth, reasoning about unsoundness is not trivial, say Rudra's authors. They describe three patterns that lead to memory bugs in Rust, including panic safety, higher-order safety invariants, and propagating Send/Sync in generic types. Rudra builds specific techniques to deal with those patterns. The analysis of the three patterns and the approach to detect them exceeds the level of complexity that can be reached here, but interested readers can access the paper linked above.

While the three bug patterns mentioned above may sound arcane, running Rudra against the Rust package registry led to identify bugs in a number of packages, including the Rust standard library and the Rust compiler as well as the 30 most popular crates based on their downloads.

Rudra found memory-safety bugs from heavily tested packages—containing unit tests with extensive code coverage and fuzzers. The found bugs are non-trivial—they had existed for over three years on average.

Rudra was used to analyze the over 43k packages available in, which took 6.5 hours. A total of 264 new memory-safety bugs were identified in 145 packages. This resulted in 112 RustSec and 76 CVEs, say the researchers.

It could appear that these results undermine the belief that Rust safety model represents an improvement over other languages, e.g. C++, but this would not be correct, say the researchers behind Rudra, who still consider Rust safety a supreme improvement.

In C/C++, getting a confirmation from the maintainers whether certain behavior is a bug or an intended behavior is necessary in bug reporting, because there are no clear distinctions between an API misuse and a bug in the API itself. In contrast, Rust's safety rule provides an objective standard to determine whose fault a bug is.

Yet, their conclusion is that Rust safety model is not powerful enough to guarantee on its own that a system is secure, especially in view of the possibility of a malicious package or OS driver intentionally written to include some kind of unsound behaviour. In this regard, Rudra appears to be a valuable contribution to the Rust ecosystem safety.

As an added bonus, the analysis led by Rudra creators also allowed to identify the most frequently misused Rust APIs, which made it possible to create new specific rules for the official Rust linter, Clippy.

Rudra can be installed easily using its official Docker image. It is implemented as a Rust compiler plugin that injects its analysis algorithm into the target package while leaving its dependencies unmodified. It is integrated within cargo, so that you can check an existing package by simply running cargo rudra.

Rate this Article