Rust Memory Safety & Undefined Behavior Detection

Overview

Rudra

Rudra is a static analyzer to detect common undefined behaviors in Rust programs. It is capable of analyzing single Rust packages as well as all the packages on crates.io.

Rudra and its associated paper received the Distinguished Artifact Award at the 28th ACM Symposium on Operating Systems Principles 2021 (SOSP '21). (PDF, short talk, long talk)

You can find the list of bugs found by Rudra at Rudra-PoC repository.

Usage

The easiest way to use Rudra is to use Docker.

  1. First, make sure your system has Docker and Python 3 installed.
  2. Add rudra:latest image on your system. There are two ways of doing this:
    • docker pull ghcr.io/sslab-gatech/rudra:master && docker tag ghcr.io/sslab-gatech/rudra:master rudra:latest
    • Alternatively, you can build your own image with docker build . -t rudra:latest
  3. Run ./setup_rudra_runner_home.py and set RUDRA_RUNNER_HOME to that directory. Example: ./setup_rudra_runner_home.py ~/rudra-home && export RUDRA_RUNNER_HOME=$HOME/rudra-home.
    • There are two scripts, ./setup_rudra_runner_home.py and ./setup_rudra_runner_home_fixed.py. In general, ./setup_rudra_runner_home.py should be used unless you want to reproduce the result of the paper with a fixed cargo index.
  4. Add docker-helper in Rudra repository to $PATH. Now you are ready to test Rudra!

For development, you might want to install Rudra on your host system. See DEV.md for advanced usage and development guide.

Run Rudra on a single project

docker-cargo-rudra 
   

   

The log and report are printed to stderr by default.

Run Rudra with different compiler version

Rudra is tied to a specific Rust compiler version, and it can only analyze projects that compiles with this version of the compiler. master branch uses nightly-2021-08-20 version of Rust right now. Check the version page for all supported versions.

Bug Types Detected by Rudra

Rudra currently detects the following bug types. For the full detail, please check our SOSP 2021 paper.

Panic Safety (Unsafe code that can create memory-safety issues when panicked)

Detects when unsafe code may lead to memory safety issues if a user provided closure or trait panics. For example, consider a function that dereferences a pointer with ptr::read, duplicating its ownership and then calls a user provided function f. This can lead to a double-free if the function f panics.

See this section of the Rustonomicon for more details.

while idx < len {
    let ch = unsafe { self.get_unchecked(idx..len).chars().next().unwrap() };
    let ch_len = ch.len_utf8();

    // Call to user provided predicate function f that can panic.
    if !f(ch) {
        del_bytes += ch_len;
    } else if del_bytes > 0 {
        unsafe {
            ptr::copy(
                self.vec.as_ptr().add(idx),
                self.vec.as_mut_ptr().add(idx - del_bytes),
                ch_len,
            );
        }
    }

    // Point idx to the next char
    idx += ch_len;
}

Example: rust#78498

Higher Order Invariant (Assumed properties about traits)

When code assumes certain properties about trait methods that aren't enforced, such as expecting the Borrow trait to return the same reference on multiple calls to borrow.

let mut g = Guard { len: buf.len(), buf }; 
// ...
  Ok(n) => g.len += n, 

Example: rust#80894

Send Sync Variance (Unrestricted Send or Sync on generic types)

This occurs when a type generic over T implements Send or Sync without having correct bounds on T.

unsafe impl
   Sized + 
   Send, U: ?
   Sized> 
   Send 
   for 
   MappedMutexGuard<
   '_, T, U> {} 

   unsafe 
   impl
   
    Sized + 
    Sync, U: ?
    Sized> 
    Sync 
    for 
    MappedMutexGuard<
    '_, T, U> {} 
   
  

Example: futures#2239

Bugs Found by Rudra

Rudra was ran on the entirety of crates.io state as of July 4th, 2020 as well as the Rust standard library from nightly-2020-08-26. It managed to find 264 new memory safety issues across the Rust ecosystem which resulted in 76 CVEs.

The details of these bugs can be found in the Rudra-PoC repo.

License

Licensed under either of

at your option.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

Issues
  • Rustup to

    Rustup to "rustc 1.56.0-nightly (6d64f7f69 2021-08-19)"

    Fixes #8

    Based on #9

    opened by bjorn3 9
  • Pre-built docker image?

    Pre-built docker image?

    I would love to test this out on my project, but it looks like that there's not pre-built docker image.

    You can host one on DockerHub or GitHub Container Registry. It would be really easier to try this out this way! 👍

    opened by sobolevn 4
  • adapt SendSyncChecker's filtering criteria for 'Channel-like' types

    adapt SendSyncChecker's filtering criteria for 'Channel-like' types

    Summary

    Adapt SendSyncChecker's detection criteria for PtrLike types & Concurrent Queue types.

    • PtrLike : Require T: Send + Sync for impl Sync
    • Concurrent Queue : Allow T: Send to be enough for impl Sync

    test cases relevant to this PR

    • Detected by analyzer
      • tests/send_sync/wild_channel.rs => Detected
      • tests/send_sync/wild_ptr_like.rs => Detected
    • Allowed by analyzer
      • tests/send_sync/okay_channel.rs => Allowed

    Update on Feb 3rd: I decided to remove the PtrLike type handling in this PR, and maybe try again in a separate pr

    opened by JOE1994 3
  • Allow setting Rust toolchain as an env var

    Allow setting Rust toolchain as an env var

    This is a really cool project! We're trying to use Rudra with the nightly-2021-08-20 toolchain but there's a small issue — if a user pulls the ghcr.io/sslab-gatech/rudra:2021-08-20 image as specified in the readme and tags it with rudra:latest, running the docker-cargo-rudra script will give an error that the installed Rust toolchain does not match the RUSTUP_TOOLCHAIN env var. I think this PR should resolve that issue so that a user can set RUDRA_RUSTUP_TOOLCHAIN to override the variable passed to Docker.

    opened by rajivshah3 3
  • Panic safety beta

    Panic safety beta

    Key features

    • CFG based analysis - calculated by graph traversal
    • Nested colorization support
    • Separate strong / weak bypasses
    opened by Qwaz 2
  • Update to newer rust version?

    Update to newer rust version?

    The rust version in the Dockerfile is from about one year ago, and a lot of new features have been implemented since then.

    https://github.com/sslab-gatech/Rudra/blob/a2ea65cad7c3fc30c5f8d29a62411e0236af2a2c/Dockerfile#L8

    I tried to change the rust version in the Dockerfile to the latest nightly:

    -     RUST_VERSION=nightly-2020-08-26 \
    +     RUST_VERSION=nightly-2021-08-20 \
    

    which resulted in a compilation failure:

       Compiling rudra v0.1.0 (/tmp/rudra)
    error[E0463]: can't find crate for `rustc_data_structures`
     --> src/lib.rs:7:1
      |
    7 | extern crate rustc_data_structures;
      | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't find crate
    
    error: aborting due to previous error
    
    For more information about this error, try `rustc --explain E0463`.
    error: could not compile `rudra`.
    
    To learn more, run the command again with --verbose.
    warning: build failed, waiting for other jobs to finish...
    error: failed to compile `rudra v0.1.0 (/tmp/rudra)`, intermediate artifacts can be found at `/tmp/rudra/target`
    
    Caused by:
      build failed
    
    opened by Luro02 2
  • Add ability to analyze the standard library

    Add ability to analyze the standard library

    This adds a new folder called stdlib-analysis that contains a convenience script to analyze the standard library.

    This approach creates a small change in rudra to allow for this, in particular it adds:

    • Adds a RUDRA_ALSO_ANALYZE environment variable. This variable causes rudra to also analyze a comma separated list of crates passed in. For example, if we're building crate foo with dependencies bar and baz. We can use RUDRA_ALSO_ANALYZE=bar,baz to analyze both the build dependencies.
    • -Zrudra-act-as-compiler, a rudra flag that makes the analyzer compile instead of just stopping compilation. This is needed because we're trying to analyze dependent crates that are built by xargo. Thus since we have a chain of build dependencies like core -> alloc -> std, we can't just stop building after we've analyzed the first crate.

    I also have an alternative approach that creates a bin/rudra-std.rs file but it either involves refactoring out a lot of the common code from bin/cargo-rudra.rs and bin/rudra.rs OR duplicating code. Please let me know if you would like to see those.

    opened by ammaraskar 1
  • Frozen cargo build

    Frozen cargo build

    • Use a fixed DB dump from a forked cargo index.
    • Try to use sccache to build dependencies if it is available.
    • Improvement in environment variable handling.
    opened by Qwaz 1
  • Tell rustup to install the necessary components

    Tell rustup to install the necessary components

    This makes it easier to build using plain cargo build

    opened by bjorn3 1
  • update compiler-version for `edition2021` support

    update compiler-version for `edition2021` support

    Currently, 2021 crates can't be analyzed because the feature is still unstable in the version used by rudra:

    $ docker-cargo-rudra .
    2021-11-14 06:39:02.906467 |INFO | [rudra-progress] Running cargo rudra
    2021-11-14 06:39:03.166856 |ERROR| [rudra-progress] Could not obtain Cargo metadata
    Error during execution of `cargo metadata`: error: failed to load manifest for workspace member `/tmp/rudra/...`
    
    Caused by:
      feature `edition2021` is required
    
      The package requires the Cargo feature called `edition2021`, but that feature is not stabilized in this version of Cargo (1.56.0-nightly (e96bdb0c3 2021-08-17)).
      Consider adding `cargo-features = ["edition2021"]` to the top of Cargo.toml (above the [package] table) to tell Cargo you are opting in to use this unstable feature.
      See https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#edition-2021 for more information about the status of this feature.
    
    opened by M1cha 0
  • Failed to run 'cargo rudura' for crates

    Failed to run 'cargo rudura' for crates

    When I execute cargo rudra for other crates, there is an error:

    dyld: Library not loaded: @rpath/librustc_driver-0fd0d43d50587954.dylib
    Referenced from: /Users/vaynnecol/.cargo/bin/cargo-rudra
    Reason: image not found
    [1] 91286 abort cargo rudra
    

    and this error does not apper when i running Rudra for itself.

    opened by VaynNecol 2
  • Failed to load source for dependency

    Failed to load source for dependency

    I am trying to use Rudra on a project structured in a workspace. In this workspace there are libraries that have dependencies to libraries from the same workspace. These are specified with relative paths. This causes Rudra to fail. The problem seems to be the dependencies that are specified by a path.

    This might be related to #11

    Minimal example: cargo new library --lib ; cargo new user In user/Cargo.toml add

    [dependencies]
     library = { path = "../library" }
    

    Running Rudra causes this error where erroneously library is assumed to be in /tmp?

    [email protected]:/opt/tmp/vogel/static-analysis/Rudra/docker-helper$ ./docker-cargo-rudra /opt/tmp/vogel/static-analysis/hello_world/user/
    
    2021-09-03 11:25:52.536262 |INFO | [rudra-progress] Running cargo rudra
    2021-09-03 11:25:52.871481 |ERROR| [rudra-progress] Could not obtain Cargo metadata
    Error during execution of `cargo metadata`: error: failed to get `library` as a dependency of package `user v0.1.0 (/tmp/rudra)`
    
    Caused by:
      failed to load source for dependency `library`
    
    Caused by:
      Unable to update /tmp/library
    
    Caused by:
      failed to read `/tmp/library/Cargo.toml`
    
    Caused by:
      No such file or directory (os error 2)
    

    When specifying the library dependency as a absolute path (library = { path = "/opt/tmp/vogel/static-analysis/hello_world/library" }) I get the same error without the /tmp issue. It still fails to read the library Cargo.toml, even though it should exist (see cat output).

    [email protected]:/opt/tmp/vogel/static-analysis/Rudra/docker-helper$ ./docker-cargo-rudra /opt/tmp/vogel/static-analysis/hello_world/user/
    
    2021-09-03 11:21:57.305532 |INFO | [rudra-progress] Running cargo rudra
    2021-09-03 11:21:57.973875 |ERROR| [rudra-progress] Could not obtain Cargo metadata
    Error during execution of `cargo metadata`: error: failed to get `library` as a dependency of package `user v0.1.0 (/tmp/rudra)`
    
    Caused by:
      failed to load source for dependency `library`
    
    Caused by:
      Unable to update /opt/tmp/vogel/static-analysis/hello_world/library
    
    Caused by:
      failed to read `/opt/tmp/vogel/static-analysis/hello_world/library/Cargo.toml`
    
    Caused by:
      No such file or directory (os error 2)
    
    [email protected]:/opt/tmp/vogel/static-analysis/Rudra/docker-helper$ cat /opt/tmp/vogel/static-analysis/hello_world/library/Cargo.toml
    [package]
    name = "library"
    version = "0.1.0"
    authors = ["Arne Vogel <>"]
    edition = "2018"
    
    # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
    
    [dependencies]
    
    opened by ArneVogel 1
  • Could not obtain Cargo metadata

    Could not obtain Cargo metadata

    I'm trying to run rudra on https://github.com/archlinux/alpm.rs but there is an error.

    [email protected] master ~git/Rudra % PATH=$PATH:docker-helper docker-cargo-rudra ~/git/alpm.rs/alpm/
    2021-08-21 12:15:24.016251 |INFO | [rudra-progress] Running cargo rudra
    2021-08-21 12:15:24.211067 |ERROR| [rudra-progress] Could not obtain Cargo metadata
    

    I think the issue might be because alpm.rs is in a workspace. But running a dir up doesn't work either.

    opened by Morganamilo 10
Owner
gts3.org ([email protected])
https://gts3.org
gts3.org (SSLab@Gatech)
Find the ideal fuzz targets in a Rust codebase

Siderophile Siderophile finds the "most unsafe" functions in your Rust codebase, so you can fuzz them or refactor them out entirely. It checks the cal

Trail of Bits 121 Nov 26, 2021
A cryptographically verifiable code review system for the cargo (Rust) package manager.

image credit cargo-crev A cryptographically verifiable code review system for the cargo (Rust) package manager. Introduction Crev is a language and ec

crev - Code REView system 1.5k Nov 20, 2021
A set of utilities to better enable polymorphic behavior in Rust

Polymorph A set of utilities to better enable polymorphic behavior in Rust. Introduction Rust is a wonderful language, with a strong emphasis on fast,

null 1 Nov 5, 2021
QueingSimulator is an application that can be used to build intuitions about behavior of synchronous request/reply systems

Queueing Simulator QueingSimulator is an application that can be used to build intuitions about behavior of synchronous request/reply systems (such as

Joe Magerramov 6 Nov 7, 2021
memory-profiler — A memory profiler for Linux

A memory profiler for Linux Features Can be used to analyze memory leaks, see where exactly the memory is being consumed, identify temporary allocatio

Koute 2.4k Nov 25, 2021
Custom memory allocator that helps discover reads from uninitialized memory

libdiffuzz: security-oriented alternative to Memory Sanitizer This is a drop-in replacement for OS memory allocator that can be used to detect uses of

Sergey 149 Sep 8, 2021
Starlight is a JS engine in Rust which focuses on performance rather than ensuring 100% safety of JS runtime.

starlight Starlight is a JS engine in Rust which focuses on performance rather than ensuring 100% safety of JS runtime. Features Bytecode interpreter

null 353 Nov 25, 2021
A rust web framework with safety and speed in mind.

darpi A web api framework with speed and safety in mind. One of the big goals is to catch all errors at compile time, if possible. The framework uses

null 32 Oct 18, 2021
A cross-platform GUI library for Rust focused on simplicity and type-safety

A cross-platform GUI library for Rust, inspired by Elm

Héctor Ramón 12k Nov 29, 2021
A flexible web framework that promotes stability, safety, security and speed.

A flexible web framework that promotes stability, safety, security and speed. Features Stability focused. All releases target stable Rust. This will n

Gotham 1.9k Nov 25, 2021
rip is a command-line deletion tool focused on safety, ergonomics, and performance

rip (Rm ImProved) rip is a command-line deletion tool focused on safety, ergonomics, and performance. It favors a simple interface, and does not imple

Kevin Liu 473 Nov 17, 2021
Explore from the safety of your shell

turtlescan Explore from the safety of your shell Installation: cargo install turtlescan tui Starts a little tui which connects to your JSON-RPC server

Brian Cloutier 4 Sep 27, 2021
Natural language detection library for Rust. Try demo online: https://www.greyblake.com/whatlang/

Whatlang Natural language detection for Rust with focus on simplicity and performance. Content Features Get started Documentation Supported languages

Sergey Potapov 649 Nov 27, 2021
👄 The most accurate natural language detection library in the Rust ecosystem, suitable for long and short text alike

Table of Contents What does this library do? Why does this library exist? Which languages are supported? How good is it? Why is it better than other l

Peter M. Stahl 377 Nov 15, 2021
Face detection library for the Rust programming language

Rustface SeetaFace detection library for the Rust programming language Example of demo program output SEETAFACE C++ – Github repository for the origin

Andrei Tomashpolskiy 290 Nov 18, 2021
Time series anomaly detection for Rust

AnomalyDetection.rs Time series AnomalyDetection for Rust Learn how it works Installation Add this line to your application’s Cargo.toml under [depend

Andrew Kane 3 Nov 14, 2021
Super Fast Sub-domain Takeover Detection!

NtHiM - Super Fast Sub-domain Takeover Detection Installation Method 1: Using Pre-compiled Binaries The pre-compiled binaries for different systems ar

Binit Ghimire 237 Nov 21, 2021
Semantic text segmentation. For sentence boundary detection, compound splitting and more.

NNSplit A tool to split text using a neural network. The main application is sentence boundary detection, but e. g. compound splitting for German is a

Benjamin Minixhofer 210 Nov 21, 2021
Super lightweight and dead-simple CI detection.

This crate tells you if you're in a CI environment or not. It does not tell you which you're in, but it makes a good effort to make sure to accurately

Kat Marchán 8 Nov 17, 2021
lingua-rs Python binding. An accurate natural language detection library, suitable for long and short text alike.

lingua-py lingua-rs Python binding. An accurate natural language detection library, suitable for long and short text alike. Installation pip install l

messense 6 Nov 29, 2021
Stretto is a Rust implementation for ristretto. A high performance memory-bound Rust cache.

Stretto is a Rust implementation for ristretto. A high performance memory-bound Rust cache.

Al Liu 188 Nov 20, 2021
Rust library to interract with memory written in rust

memory-rs Rust library to interract with memory written in rust It comes with: Pattern scanner (Return address for a pattern given). A pattern example

Alex 2 Nov 12, 2021
MiniDump a process in memory with rust

safetydump Rust in-memory MiniDump implementation. Features ntdll!NtGetNextProcess to obtain a handle for the desired ProcessId as opposed to kernel32

null 12 Aug 4, 2021
SegVec data structure for rust. Similar to Vec, but allocates memory in chunks of increasing size.

segvec This crate provides the SegVec data structure. It is similar to Vec, but allocates memory in chunks of increasing size, referred to as "segment

Jacob Ryan McCollum 25 Aug 25, 2021
Rust binding of fortran Limited memory LBFGS subroutine

lbfgs-sys Rust binding of fortran L-BFGS-B subroutine. The orginal fortran subroutine is distributed under BSD-3 license. To know more about the condi

Naushad Karim 9 Jul 25, 2020
A interactive and fun to use memory game written in Rust

memg - Memory Game memg is a interactive and fun to use memory game written in rust Installation Make sure you have rust installed. Use this official

null 4 Sep 9, 2021
🚀Memory safe, blazing fast, configurable, minimal hello world written in rust(🚀) in a few lines of code with few(1092🚀) dependencies🚀

?? hello-world.rs ?? ?? Memory safe, blazing fast, minimal and configurable hello world project written in the rust( ?? ) programming language ?? ?? W

mTvare 1.2k Nov 29, 2021
This crate allows writing a struct in Rust and have it derive a struct of arrays layed out in memory according to the arrow format.

Arrow2-derive - derive for Arrow2 This crate allows writing a struct in Rust and have it derive a struct of arrays layed out in memory according to th

Jorge Leitao 6 Oct 29, 2021