Skip to content
Snippets Groups Projects
Select Git revision
  • master
1 result

r

Blame
  • array.rs 3.08 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) -> u8 {
        let mut acc = 0;
        for i in 0..index {
            if index < arr.len() {
                acc += arr[i as usize];
            } else {
                break;
            }
        }
        acc
    }
    
    #[no_mangle]
    fn main() {
        let mut arr = [0u8; 8];
        for i in 0..arr.len() {
            let mut element: u8 = 0;
            klee_make_symbolic!(&mut element, "element");
            arr[i] = element;
        }
        let mut i: usize = 0;
        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?)
    //
    // [your answer here]]
    // The diffrence is that debug test all 10 possible paths and release only checks 2. This is becaus
    // 9 of the paths are basicly the same. These are the path were index is 0..8, the last path is
    // diffrent because then the index is out side of the array(index = 255), thus there will be an error.
    //
    //
    // Debug:
    // KLEE: done: total instructions = 4686
    // KLEE: done: completed paths = 10
    // KLEE: done: generated tests = 10
    //
    // Release:
    // KLEE: done: total instructions = 32
    // KLEE: done: completed paths = 2
    // KLEE: done: generated tests = 2
    //
    //
    // 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.
    //
    // [your answer here]
    //
    // E) Make a sensible fix to the code.
    // Motivate your choice.
    //
    // [your answer here]
    //
    // [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!