Skip to content
Snippets Groups Projects
Select Git revision
  • 8bb1d3e283ec5c2569a8f910452b1fb60f8e4035
  • master default protected
2 results

array.rs

Blame
  • Forked from Per Lindgren / klee_tutorial
    Source project has a limited visibility.
    array.rs 2.93 KiB
    // get_sign.rs
    // Showcase how we automatically can interface Rust to KLEE
    //
    
    #![no_std]
    #![no_main]
    
    use klee_sys::klee_make_symbolic;
    use panic_klee as _;
    
    fn sum_first_elements(arr: &[u8], index: usize) -> u16 {
        let mut acc: u16 = 0;
        let index = core::cmp::min(arr.len(), index);
        for i in 0..index {
            acc += arr[i as usize] as u16;
        }
        acc
    }
    
    #[no_mangle]
    fn main() {
        let mut arr = [0u8; 8];
        let mut i: usize = 0;
        klee_make_symbolic!(&mut arr, "arr");
        klee_make_symbolic!(&mut i, "i");
        let b = sum_first_elements(&arr, i);
    }
    
    // A) Array indexing is tricky to analyse at compile time.
    // Thus Rust (rustc) will inject code for run-time verification
    // `panic`ing on index out of range.
    //
    // (Compare to C/C++, where a "buffer overflow" might pass unnoticed
    // causing all sorts of problems.)
    //
    // Compare the test generated in release `--release` (optimized) to
    // test generated in debug/dev mode (un-optimized).
    //
    // Try to explain in your own words the difference and why?
    // (Hint, even if we don't use the result `b`, Rust do not optimize out the call, why?)
    //
    // [There are 10 path with debug/dev mode and 2 path on release mode.
    // In the debug mode/dev 8 of the paths is 8 for each loop, 1 path is for panic when index is out of range.
    // The release mode is optimizing out all the loops, which means there are only two paths; one inside the loop
    // and one outside. The b is not optimized out because the calculation of b can have side effects and
    // code with side effects are not optimized out.]
    //
    // B) Fix the code so that you don't get an error.
    // (It should still compute the sum of the n first elements
    // and return the sum of the whole array if index larger than size/length).
    // The fix should be in the function (not on the caller side).
    //
    // [Git commit "B"]
    //
    // C) In the example, the array is holding only zeroes.
    // Figure out a way to make the content symbolic.
    // (Hint, declare as mutable, iterate and set each element symbolic.)
    // (Hint2, it seems that you can set the whole array symbolic directly
    // without messing with an iterator, super!!!.)
    //
    // [Git commit "C"]
    //
    // D) Analyze the example using KLEE. Now a new (maybe unexpected) error should occur!
    // Notice, the error occurs only in `debug/dev` builds.
    //
    // Explain what caused the error.
    //
    // [It seems to be a overflow problem in the varaible acc.]
    //
    // E) Make a sensible fix to the code.
    // Motivate your choice.
    //
    // [I changed the acc variable to a u16. It will allow bigger values without overflowing.]
    //
    // [Git commit "D"]
    //
    // F) Learning outcome.
    // 70% of Microsoft security updates over the last decade is directly related to
    // memory safety.
    //
    // Explain in your own words what Microsoft would gain by using Rust.
    //
    // [your answer here]
    //
    // Explain in your own words what Microsoft would gain by using `cargo klee`
    // on their Rust code.
    //
    // And YES, Microsoft is rewriting core system functionality in Rust as we speak!