markhakansson / klee-tutorial

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

KLEE tutorial

  • Installing and testing klee.

  • Manual use of the KLEE tools for C and Rust programs.

  • Simplified usage adopting klee-sys and cargo klee.

Dependencies

Dependencies for building klee is discussed in building klee.

Under the hood, klee uses a sat solver for First Order Logic (FOL). Klee can interface to z3 which is modern and efficient solver using Satisfiability Modulo Theories (SMT). In essence SMT is FOL + built in theories for reasoning on fixed-size bit-vectors, extensional arrays, datatypes, and uninterpreted functions, making it suitable for program analysis.

So first install z3 on your system (then klee will use that instead of the default solver).

Later, you also need to have gdb installed, under arch by:

Arch linux:

Under arch with yay installed simply:

> yay -S z3
> yay -S gdb

Ubuntu (like) systems

sudo apt install z3 libz3-4 libz3-cil libz3-dev libz3-java libz3-jni libz3-ocaml-de

Install KLEE from source

The instructions recommend LLVM 9, but the current master (2.2-pre) supports LLVM 11 (which is what you would have under arch as of 2020-12-07).

Under arch you can simply:

> git clone https://github.com/klee/klee.git
> cd klee
> mkdir build
> cd build
> cmake ..
> make -j 8 (-j sets number of parallel builds, e.g., on a 8 threaded machine)
> sudo make install

Verify that you have the tool installed.

> klee -version
KLEE 2.2-pre (https://klee.github.io)
  Build mode: RelWithDebInfo (Asserts: ON)
  Build revision: 199bd43deffc614b2915f4de26475ca43d22e2ae

LLVM (http://llvm.org/):
  LLVM version 11.0.0
  Optimized build.
  Default target: x86_64-pc-linux-gnu
  Host CPU: znver2

If your build fails at some point, consult the docs building klee.

Install KLEE from aur (arch linux)

The aur package klee, installs KLEE in /usr/bin (binaries), /usr/include (C-include files), and usr/lib (libraries). These are the default system folders respectively, so it makes it easier to compile, link, and run the KLEE tools.

> yay -S klee
> klee -version
KLEE 2.2 (https://klee.github.io)
  Build mode: Release (Asserts: ON)
  Build revision: 5719d2803e93252e5d4613f43afc7db0d72332f1

LLVM (http://llvm.org/):
  LLVM version 11.0.0
  Optimized build.
  Default target: x86_64-pc-linux-gnu
  Host CPU: skylake

Notice, if you have previously installed from source, but want to use the aur instead you should remove the source installed files found in /usr/local/bin, /usr/local/include and /usr/local/lib (please make sure that you only remove the KLEE related files).


Testing a small C function

See the examples/get_sign file.

Here you learn:

  • how to generate LLVM-IR
  • how to run KLEE
  • how to inspect generated test
  • how to replay test cases

Testing a small Rust function

See the examples/get_sign.rs file.

Here you learn:

  • how to generate LLVM-IR from a Rust program
  • how to run KLEE on Rust code
  • how to replay test cases for Rust programs

klee-sys and Cargo-klee

See the cargo-klee-examples folder.

Here you learn:

  • an easy way to compile and run KLEE on Rust code
  • an easy way to replay test cases for Rust programs
  • an easy way to find "hard to find" errors in embedded code

Related files and their locations and attributes

  • vcell: KLEE enable vcell

    • version: 0.1.2
    • git: https://github.com/perlindgren/vcell/blob/trustit
    • branch: trustit
    • features:
      • klee-analysis
        • get results in a new (fresh) symbolic object.
        • set is suppressed (no side effect).
  • klee-sys: low-level bindings for KLEE.

    • version: 0.2.0
    • git: https://gitlab.henriktjader.com/pln/klee-sys
    • features:
      • klee-analysis
        • KLEE API binds to external functions
      • klee-replay
        • KLEE API klee_make_symbolic binds to inline assembly breakpoint. This allows a debugger to catch the halted CPU and insert test case to location of symbolic object. Other KLEE API binds to Rust panic!.
  • cargo-klee: cargo sub-command.

    • version: 0.3.0
    • git: https://gitlab.henriktjader.com/pln/cargo-klee
  • panic_klee: Binds panic handler to external abort

    • version: 0.1.0
    • git: https://gitlab.henriktjader.com/pln/panic-klee

Why KLEE on Rust

Out the box, Rust provides superior memory safety and guarantees to well defined behavior. However there are cases where the Rust compiler (rustc) cannot statically (at compile time) ensure these guarantees. For such cases (e.g., division by zero, slice/array indexing etc.) Rust injects code for run-time verification that emit a panic! (with appropriate error message). While still being safe (the code nevhttps://github.com/perlindgren/vcell.giter runs into memory unsafety or undefined behavior) this limits the reliability (availability) of the system (as its very hard to recover from a panic!.) In practice, the developer would typically reboot/reset the system (and store some error code/trace for post-mortem analysis).

With KLEE we can do better! We bind Rust panic! to KLEE abort (a path termination), and let. For all reachable panic!s, KLEE will provide a concrete test, which we can replay and address in our source code. When done, we have a proof of panic freedom and thus defined behavior, with huge impact to reliability (and security) of the system at hand.

About


Languages

Language:Rust 98.1%Language:HTML 1.9%