This tool tries to analyze the MIR generated by the Rust compiler and emit diagnostic messages. It is based on the theory of Abstract Interpretation.
Information about bugs detected by this tool are listed in Trophy Case.
The associated paper titled MirChecker: Detecting Bugs in Rust Programs via Static Analysis will appear at the 28th ACM Conference on Computer and Communications Security (CCS '21).
-
Rust nightly, as specified in rust-toolchain.
-
rustc-dev
andllvm-tools-preview
:$ rustup component add rustc-dev llvm-tools-preview
-
GMP
,MPFR
,PPL
andZ3
:# For Ubuntu: $ sudo apt-get install libgmp-dev libmpfr-dev libppl-dev libz3-dev
-
Clone the repository (use
--recursive
to initialize the nested submodule)$ git clone --recursive https://github.com/lizhuohua/rust-mir-checker.git $ cd rust-mir-checker
-
Build & Install
# Make sure to have llvm/clang version 15 installed $ export LIBCLANG_PATH=`llvm-config-15 --libdir`/libclang.so # Use the LLVM lld linker $ export RUSTFLAGS="-Clink-args=-fuse-ld=lld" # You can build and install the cargo subcommand: $ cargo install --path . # Or, you can only build the checker itself: $ cargo build
Note: clang 15 is required because of this issue with handling anonymous structs in clang 16. If you cannot find LLVM 15 in your Linux distribution's package manager, you can also download the precompiled binary. For specific usage, please refer to the GitHub actions build script.
The following is a simple example which contains an out-of-bounds access. For more examples, please see tests and trophy-case.
fn main() {
let mut a = [1, 2, 3, 4, 5];
let mut i = 0;
while i < 5 {
a[i] = i;
i = i + 1;
}
a[i] = 100;
}
It compiles but will panic at runtime. Our checker can detect it at compile time, the following command will emit a warning:
$ target/debug/mir-checker examples/loop-buffer-overflow.rs --entry main --domain interval --widening_delay 5 --narrowing_iteration 5
warning: [MirChecker] Provably error: index out of bound
--> examples/loop-buffer-overflow.rs:8:5
|
8 | a[i] = 100;
| ^^^^
Before using this tool, make sure your Rust project compiles without any errors or warnings.
# If you have installed the cargo subcommand:
$ cargo mir-checker -- --entry <entry-function-name> --domain <abstract-domain> --widening_delay <N> --narrowing_iteration <N> --suppress_warnings <S>
# Or, you can directly run the checker for a single file
$ target/debug/mir-checker <path-to-file> --entry <entry-function-name> --domain <abstract-domain> --widening_delay <N> --narrowing_iteration <N> --suppress_warnings <S>
<entry-function-name>
is the entry function. The default value ismain
.<abstract-domain>
is the numerical abstract domain. Currently, 7 abstract domains are supported:interval
,octagon
,polyhedra
,linear_equalities
,ppl_polyhedra
,ppl_linear_congruences
, andpkgrid_polyhedra_linear_congruences
.widening_delay
controls the number of iterations before triggering widening.<N>
is an unsigned integer.narrowing_iteration
controls the maximum number of narrowing operations that may improve the result.<N>
is an unsigned integer.suppress_warnings
filters out some specific kinds of warnings.<S>
is a string where each character represents a kind of warning:a
: arithmetic overflow,b
: bit-wise overflow,s
: inline assembly,c
: comparison operations,d
: division by zero / remainder by zero,m
: memory-safety issues,p
: run into panic code,i
: out-of-bounds access.
Set RUST_LOG
environment variable to enable logging:
# Enable all logging
$ export RUST_LOG=rust_mir_checker
# Can also set logging level
$ export RUST_LOG=rust_mir_checker=debug
For more settings, please see the documents of env_logger.
There are a lot of limitations of MirChecker that we would like to address in the future:
- Eliminating runtime panics for unsupported cases
- Reducing false positives
- Better support for interprocedural analysis
- Better support for analyzing the standard library
- Adding support for user annotations
For macOS, you may encounter dyld: Library not loaded
error, try setting:
$ export LD_LIBRARY_PATH=$(rustc --print sysroot)/lib:$LD_LIBRARY_PATH
Many ideas and code bases are from the following projects, many thanks!