Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/lizhuohua/rust-mir-checker


https://github.com/lizhuohua/rust-mir-checker

Last synced: 8 days ago
JSON representation

Awesome Lists containing this project

README

        

# MirChecker: A Simple Static Analysis Tool for Rust

[![Build Status](https://github.com/lizhuohua/rust-mir-checker/workflows/build/badge.svg)](https://github.com/lizhuohua/rust-mir-checker/actions?query=workflow%3Abuild)
[![codecov](https://codecov.io/gh/lizhuohua/rust-mir-checker/branch/master/graph/badge.svg?token=Y4MlI5AUql)](https://codecov.io/gh/lizhuohua/rust-mir-checker)

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](https://en.wikipedia.org/wiki/Abstract_interpretation).

Information about bugs detected by this tool are listed in [Trophy Case](trophy-case/README.md).

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).

## Requirements

* Rust nightly, as specified in [rust-toolchain](rust-toolchain.toml).
* `rustc-dev` and `llvm-tools-preview`:

```sh
$ rustup component add rustc-dev llvm-tools-preview
```

* `GMP`, `MPFR`, `PPL` and `Z3`:

```sh
# For Ubuntu:
$ sudo apt-get install libgmp-dev libmpfr-dev libppl-dev libz3-dev
```

## Build

1. Clone the repository (use `--recursive` to initialize the nested submodule)

```sh
$ git clone --recursive https://github.com/lizhuohua/rust-mir-checker.git

$ cd rust-mir-checker
```

2. Build & Install

```sh
# 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](https://github.com/rust-lang/rust-bindgen/issues/2312).
If you cannot find LLVM 15 in your Linux distribution's package manager, you can also download the [precompiled binary](https://github.com/llvm/llvm-project/releases/download/llvmorg-15.0.6/clang+llvm-15.0.6-x86_64-linux-gnu-ubuntu-18.04.tar.xz). For specific usage, please refer to the GitHub actions [build script](.github/workflows/build.yml).

## Example

The following is a simple example which contains an out-of-bounds access. For more examples, please see [tests](tests) and [trophy-case](trophy-case).

```rust
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:

```sh
$ 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;
| ^^^^
```

## Usage

Before using this tool, make sure your Rust project compiles without any errors or warnings.

```sh
# If you have installed the cargo subcommand:
$ cargo mir-checker -- --entry --domain --widening_delay --narrowing_iteration --suppress_warnings

# Or, you can directly run the checker for a single file
$ target/debug/mir-checker --entry --domain --widening_delay --narrowing_iteration --suppress_warnings
```

* `` is the entry function. The default value is `main`.
* `` is the numerical abstract domain. Currently, 7 abstract domains are supported: `interval`, `octagon`, `polyhedra`, `linear_equalities`, `ppl_polyhedra`, `ppl_linear_congruences`, and `pkgrid_polyhedra_linear_congruences`.
* `widening_delay` controls the number of iterations before triggering [widening](https://en.wikipedia.org/wiki/Widening_(computer_science)). `` is an unsigned integer.
* `narrowing_iteration` controls the maximum number of narrowing operations that may improve the result. `` is an unsigned integer.
* `suppress_warnings` filters out some specific kinds of warnings. `` 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.

## Debug

Set `RUST_LOG` environment variable to enable logging:

```sh
# 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](https://crates.io/crates/env_logger).

## Future Work

There are a lot of limitations of MirChecker that we would like to address in the future:

1. Eliminating runtime panics for unsupported cases
2. Reducing false positives
3. Better support for interprocedural analysis
4. Better support for analyzing the standard library
5. Adding support for user annotations

## Troubleshooting

For macOS, you may encounter `dyld: Library not loaded` error, try setting:

```sh
$ export LD_LIBRARY_PATH=$(rustc --print sysroot)/lib:$LD_LIBRARY_PATH
```

## Credits

Many ideas and code bases are from the following projects, many thanks!

* [MIRAI](https://github.com/facebookexperimental/MIRAI)
* [Crab](https://github.com/seahorn/crab)
* [IKOS](https://github.com/NASA-SW-VnV/ikos)
* [Miri](https://github.com/rust-lang/miri)
* [DR.CHECKER](https://github.com/ucsb-seclab/dr_checker)

## License

See [LICENSE](LICENSE) and [licenses](licenses)