handling unbounded loops with esbmc 1 20
play

Handling Unbounded Loops with ESBMC 1.20 Jeremy Morse, Lucas - PowerPoint PPT Presentation

Handling Unbounded Loops with ESBMC 1.20 Jeremy Morse, Lucas Cordeiro Denis Nicole, Bernd Fischer ESBMC: SMT-based BMC of single- and multi-threaded software exploits SMT solvers and their background theories: optimized encodings for


  1. Handling Unbounded Loops with ESBMC 1.20 Jeremy Morse, Lucas Cordeiro Denis Nicole, Bernd Fischer

  2. ESBMC: SMT-based BMC of single- and multi-threaded software • exploits SMT solvers and their background theories: – optimized encodings for pointers, bit operations, unions and arithmetic over- and underflow – efficient search methods (non-chronological backtracking, conflict clauses learning) conflict clauses learning) • supports verifying multi-threaded software that uses pthreads threading library – interleaves only at “visible” instructions – lazy exploration of the reachability tree – optional context-bound • derived from CBMC

  3. ESBMC Verification Support • built-in properties: – arithmetic under- and overflow – pointer safety – array bounds – division by zero – memory leaks – memory leaks – atomicity and order violations – deadlocks – data races • user-specified assertions (__ESBMC_assume, __ESBMC_assert) • built-in scheduling functions (__ESBMC_atomic_begin, __ESBMC_atomic_end, __ESBMC_yield)

  4. Differences to ESBMC 1.17 • ESBMC 1.20 is largely a bugfixing release: – memory handling – internal data structure (replaced CBMC’s string-based accessor functions) – Z3 encoding (replaced the name equivalence used in the pointer representation) pointer representation) • improved our pthread-handling and added missing sequence points (pthread join-function) • produces a smaller number of false results – score improvement of more than 25% – overall verification time reduced by about 25%

  5. Induction-Based Verification k -induction checks... • base case ( base k ): find a counter-example with up to k loop unwindings (plain BMC) • forward condition ( fwd k ): check that P holds in all states reachable within k unwindings • inductive step ( step k ): check that whenever P holds for k unwindings, it also holds after next unwinding – havoc state – run k iterations – assume invariant – run final iteration ⇒ iterative deepening if inconclusive

  6. The k -induction algorithm k =initial bound while true do if base k then return trace s[0..k] else if fwd k else if fwd k return true else if step k then return true end if k=k+1 end

  7. The k -induction algorithm inserts unwinding k =initial bound assumption after while true do each loop if base k then return trace s[0..k] else if fwd k else if fwd k return true else if step k then return true end if k=k+1 end

  8. The k -induction algorithm inserts unwinding k =initial bound assumption after while true do each loop if base k then inserts unwinding return trace s[0..k] assertion after each else if fwd k else if fwd k loop loop return true else if step k then return true end if k=k+1 end

  9. The k -induction algorithm inserts unwinding k =initial bound assumption after while true do each loop if base k then inserts unwinding return trace s[0..k] assertion after each else if fwd k else if fwd k loop loop return true else if step k then havoc variables that return true occur in the loop’s termination condition end if k=k+1 end

  10. The k -induction algorithm inserts unwinding k =initial bound assumption after while true do each loop if base k then inserts unwinding return trace s[0..k] assertion after each else if fwd k else if fwd k loop loop return true else if step k then havoc variables that return true occur in the loop’s termination condition end if k=k+1 unable to falsify or end prove the property

  11. Running example n = ∑ for n ≥ 1 = S a na Prove that n = 1 i unsigned int nondet_uint(); int main() { unsigned int i, n=nondet_uint(), sn=0; assume (n>=1); assume (n>=1); for (i=1; i<=n; i++) sn = sn + a; assert (sn==n*a); }

  12. Running example: base case Insert an unwinding assumption consisting of the termination condition after the loop – find a counter-example with k loop unwindings unsigned int nondet_uint(); int main() { int main() { unsigned int i, n=nondet_uint(), sn=0; assume (n>=1); for (i=1; i<=n; i++) sn = sn + a; assume (i>n); assert (sn==n*a); }

  13. Running example: forward condition Insert an unwinding assertion consisting of the termination condition after the loop – check that P holds in all states reachable with k unwindings unsigned int nondet_uint(); int main() { int main() { unsigned int i, n=nondet_uint(), sn=0; assume (n>=1); for (i=1; i<=n; i++) sn = sn + a; assert (i>n); assert (sn==n*a); }

  14. Running example: inductive step Havoc (only) the variables that occur in the loop’s termination and branch conditions unsigned int nondet_uint(); typedef struct state { unsigned int i, n, sn; } statet; } statet; int main() { unsigned int i, n=nondet_uint(), sn=0, k; assume (n>=1); statet cs, s[n]; cs.i=nondet_uint(); cs.sn=nondet_uint(); cs.n=n;

  15. Running example: inductive step Havoc (only) the variables that occur in the loop’s termination and branch conditions unsigned int nondet_uint(); define the type of the typedef struct state { program state unsigned int i, n, sn; } statet; } statet; int main() { unsigned int i, n=nondet_uint(), sn=0, k; assume (n>=1); statet cs, s[n]; cs.i=nondet_uint(); cs.sn=nondet_uint(); cs.n=n;

  16. Running example: inductive step Havoc (only) the variables that occur in the loop’s termination and branch conditions unsigned int nondet_uint(); define the type of the typedef struct state { program state unsigned int i, n, sn; } statet; } statet; int main() { state vector unsigned int i, n=nondet_uint(), sn=0, k; assume (n>=1); statet cs, s[n]; cs.i=nondet_uint(); cs.sn=nondet_uint(); cs.n=n;

  17. Running example: inductive step Havoc (only) the variables that occur in the loop’s termination and branch conditions unsigned int nondet_uint(); define the type of the typedef struct state { program state unsigned int i, n, sn; } statet; } statet; int main() { state vector unsigned int i, n=nondet_uint(), sn=0, k; assume (n>=1); statet cs, s[n]; cs.i=nondet_uint(); explore all possible cs.sn=nondet_uint(); values implicitly cs.n=n;

  18. Running example: inductive step ESBMC is called to verify the assertions where the first arbitrary state is emulated by nondeterminism. for (i=1; i<=n; i++) { s[i-1]=cs; sn = sn + a; cs.i=i; cs.i=i; cs.sn=sn; cs.n=n; assume (s[i-1]!=cs); } assume (i>n); assert (sn == n*a); }

  19. Running example: inductive step ESBMC is called to verify the assertions where the first arbitrary state is emulated by nondeterminism. capture the state cs for (i=1; i<=n; i++) { s[i-1]=cs; before the iteration sn = sn + a; cs.i=i; cs.i=i; cs.sn=sn; cs.n=n; assume (s[i-1]!=cs); } assume (i>n); assert (sn == n*a); }

  20. Running example: inductive step ESBMC is called to verify the assertions where the first arbitrary state is emulated by nondeterminism. capture the state cs for (i=1; i<=n; i++) { s[i-1]=cs; before the iteration sn = sn + a; cs.i=i; cs.i=i; capture the state cs cs.sn=sn; after the iteration cs.n=n; assume (s[i-1]!=cs); } assume (i>n); assert (sn == n*a); }

  21. Running example: inductive step ESBMC is called to verify the assertions where the first arbitrary state is emulated by nondeterminism. capture the state cs for (i=1; i<=n; i++) { s[i-1]=cs; before the iteration sn = sn + a; cs.i=i; cs.i=i; capture the state cs cs.sn=sn; after the iteration cs.n=n; assume (s[i-1]!=cs); constraints are } included by means assume (i>n); of assumptions assert (sn == n*a); }

  22. Running example: inductive step ESBMC is called to verify the assertions where the first arbitrary state is emulated by nondeterminism. capture the state cs for (i=1; i<=n; i++) { s[i-1]=cs; before the iteration sn = sn + a; cs.i=i; cs.i=i; capture the state cs cs.sn=sn; after the iteration cs.n=n; assume (s[i-1]!=cs); constraints are } included by means assume (i>n); of assumptions assert (sn == n*a); insert unwinding } assumption

  23. Strengths: • robust context-bounded model checker for multi- threaded C code • combines plain BMC with k-induction – k -induction by itself is by far not as strong as plain BMC ⇒ although it produced substantially fewer false results

  24. Strengths: • robust context-bounded model checker for multi- threaded C code • combines plain BMC with k-induction – k -induction by itself is by far not as strong as plain BMC ⇒ although it produced substantially fewer false results Weaknesses: Weaknesses: • scalability (like other BMCs...) – loop unrolling – interleavings • pointer handling and points-to analysis – exposed by excessive typecasts in the CIL-converted code – better memory model in progress

Download Presentation
Download Policy: The content available on the website is offered to you 'AS IS' for your personal information and use only. It cannot be commercialized, licensed, or distributed on other websites without prior consent from the author. To download a presentation, simply click this link. If you encounter any difficulties during the download process, it's possible that the publisher has removed the file from their server.

Recommend


More recommend