sslab-gatech/Rudra

Standalone examples for Rudra

aytey opened this issue · 1 comments

aytey commented

tl;dr: is there a collection of standalone examples demonstrating the power of Rudra?

Hi,

I'm attempting to "play around" with Rudra and run some "toy" examples, but I'm not having much success.

If I run the following:

for i in tests/*/*.rs; do rudra --crate-type lib $i; done

Then I do get Rudra-based warnings on the following (I didn't show the SendSyncVariance issues):

  • Error (UnsafeDataflow:/WriteFlow/VecSetLen): Potential unsafe dataflow issue in 'MyVec::<T>::push_all'
  • Info (UnsafeDataflow:/Transmute): Potential unsafe dataflow issue in 'test_order_unsafe'
  • Warning (UnsafeDataflow:/ReadFlow): Potential unsafe dataflow issue in 'test_order_unsafe_loop'
  • Warning (UnsafeDataflow:/ReadFlow): Potential unsafe dataflow issue in 'test_order_unsafe'
  • Warning (UnsafeDataflow:/ReadFlow/CopyFlow/WriteFlow): Potential unsafe dataflow issue in 'insertion_sort_unsafe'

So far so good, so I think that means that my Rudra build is working ... so I then I tried to create my own examples.

Example 1

Taken from: rust-lang/rust#80894 / https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=c0ea390522bda958c9d60ad47a42e296

#![forbid(unsafe_code)]

use std::io::Read;

struct MyRead {
    first: bool,
}

impl MyRead {
    pub fn new() -> Self {
        MyRead { first: false }
    }
}

impl Read for MyRead {
    fn read(&mut self, _buf: &mut [u8]) -> std::io::Result<usize> {
        if !self.first {
            self.first = true;
            // First iteration: return more than the buffer size
            Ok(64)
        } else {
            // Second iteration: indicate that we are done
            Ok(0)
        }
    }
}

struct VecWrapper {
    inner: Vec<u8>,
}

impl VecWrapper {
    pub fn new() -> Self {
        VecWrapper { inner: Vec::new() }
    }
}

impl Drop for VecWrapper {
    fn drop(&mut self) {
        // Observe uninitialized bytes
        println!("{:?}", &self.inner);
        // Overwrite heap contents
        for b in &mut self.inner {
            *b = 0x90;
        }
    }
}

fn main() {
    let mut vec = VecWrapper::new();
    let mut read = MyRead::new();
    read.read_to_end(&mut vec.inner).unwrap();
}

rudra --crate-type bin main.rs:

2023-01-03 10:32:13.123601 |INFO | [rudra-progress] Rudra started
2023-01-03 10:32:13.124523 |INFO | [rudra-progress] SendSyncVariance analysis started
2023-01-03 10:32:13.124571 |INFO | [rudra-progress] SendSyncVariance analysis finished
2023-01-03 10:32:13.124593 |INFO | [rudra-progress] UnsafeDataflow analysis started
2023-01-03 10:32:13.129166 |INFO | [rudra-progress] UnsafeDataflow analysis finished
2023-01-03 10:32:13.129196 |INFO | [rudra-progress] Rudra finished

That is, no warnings.

Example 2

Inspired from: andydude/rust-sha#2 / https://github.com/sslab-gatech/Rudra-PoC/blob/master/poc/0148-sha.rs

fn to_bytes_len(len: usize) -> Vec<u8> {
    let mut bytes: Vec<u8> = Vec::with_capacity(len);
    unsafe {
        bytes.set_len(len);
    };
    bytes
}

fn main() {
    let x = to_bytes_len(10);
    println!("{}", x[0]);
}

rudra --crate-type bin main.rs:

2023-01-03 10:35:18.845653 |INFO | [rudra-progress] Rudra started
2023-01-03 10:35:18.846712 |INFO | [rudra-progress] SendSyncVariance analysis started
2023-01-03 10:35:18.846773 |INFO | [rudra-progress] SendSyncVariance analysis finished
2023-01-03 10:35:18.846786 |INFO | [rudra-progress] UnsafeDataflow analysis started
2023-01-03 10:35:18.847592 |INFO | [rudra-progress] UnsafeDataflow analysis finished
2023-01-03 10:35:18.847647 |INFO | [rudra-progress] Rudra finished

That is, no warnings.

Based on the description from andydude/rust-sha#2 I was hoping this would exhibit:

This is unsound, because it allows safe Rust code to exhibit an undefined behavior (read from uninitialized memory).

Question

Should I be able to use Rudra like this? Are these false negatives in Rudra, or are the examples "bad" (i.e., they don't contain issues)?

Alternatively, do you have a collection of standalone examples that demonstrate the kind of problems that Rudra can find? I'd hoped that maybe the tests would show this, but as there are only threefive UnsafeDataflow issues in the test-suite, I was thinking that there might be more examples of the issues that Rudra can find!

Version info

rudra --version
rustc 1.56.0-nightly (6d64f7f69 2021-08-19)
rustc --version
rustc 1.56.0-nightly (6d64f7f69 2021-08-19)
rustup toolchain list
beta-aarch64-apple-darwin
nightly-2021-08-20-aarch64-apple-darwin (default)
nightly-2022-11-20-aarch64-apple-darwin
nightly-aarch64-apple-darwin

Thanks for your help and for building Rudra -- cheers,

Andrew

Qwaz commented

Rudra only analyzes the "current crate". Thus, You should run Rudra directly on the libraries (the Rust standard library and rust-sha in the examples) instead of running it on dependencies.

For rust-sha, downloading the library source code and running cargo rudra command would suffice. To analyze standard library with Rudra, please check the corresponding section in the artifact evaluation guide.

For the full list of bugs we reported with Rudra, please check Rudra-PoC repository.

Hope this helps!