1 / 49

The SLAM Project: Debugging System Software via Static Analysis

The SLAM Project: Debugging System Software via Static Analysis. Thomas Ball Sriram K. Rajamani Microsoft Research http://research.microsoft.com/slam/. Thanks To. Sagar Chaki (CMU) Satyaki Das (Stanford) Rupak Majumdar (UC Berkeley) Todd Millstein (U. Washington) Robby (KSU)

libitha
Download Presentation

The SLAM Project: Debugging System Software via Static Analysis

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. The SLAM Project:Debugging System Software via Static Analysis Thomas Ball Sriram K. Rajamani Microsoft Research http://research.microsoft.com/slam/

  2. Thanks To • Sagar Chaki (CMU) • Satyaki Das (Stanford) • Rupak Majumdar (UC Berkeley) • Todd Millstein (U. Washington) • Robby (KSU) • Westley Weimer (UC Berkeley) • Andreas Podelski (MPI) • Stefan Schwoon (U. Edinburgh) • Software Productivity Tools Research group at MSR

  3. SLAM Agenda • Overview • Demo • Termination (of SLAM) • Termination (of talk)

  4. Specifying and Checking Properties of Programs • Goals • defect detection • partial validation • Properties • memory safety • temporal safety • security • … • Many (mature) techniques • automated deduction • program analysis • type checking • model checking • Many projects • Bandera, ESC-Java, FeaVer, JPF, LClint, OSQ, PolyScope, PREfix, rccjava, TVLA, Verisoft, Vault, xgcc, …

  5. API Usage Rules Programming Testing Code

  6. Windows Device Drivers • Kernel presents a very complex interface to driver • stack of drivers • NT kernel multi-threaded • IRP completion, IRQL, plug-n-play, power management, … • Correct API usage described by finite state protocols • Automatically check that clients respect these protocols

  7. start NP CallDriver SKIP1 SKIP2 return child status Skip CallDriver IPC synch MPR3 NP CallDriver prop completion PPC not pending returned MPR completion Complete request CallDriver MPR1 MPR2 DC return not Pend no prop completion synch CallDriver N/A N/A IRP accessible CallDriver start P SKIP2 Mark Pending SKIP1 Skip CallDriver IPC synch MPR3 NP CallDriver prop completion return Pending PPC not pending returned MPR completion Complete request CallDriver MPR1 MPR2 DC no prop completion CallDriver N/A

  8. The SLAM Thesis • We can soundly and precisely check a program without annotations against API rules by • creating a program abstraction • exploring the abstraction’s state space • refining the abstraction • We can scale such an approach to many 100kloc via • modular analysis • model checking

  9. SLAM • Input • API usage rules • client C source code “as is” • Analysis • create, explore and refine boolean program abstractions • Output • Error traces (minimize noise) • Verification (soundness)

  10. SLIC state { int locked = 0; } KeAcquireSpinLock.call { if (locked==1) abort; else locked = 1; } KeReleaseSpinLock.call { if (locked==0) abort; else locked = 0; } Usage Rule for Locking State Machine U L Unlocked Locked Error L U

  11. Example do { //get the write lock KeAcquireSpinLock(&devExt->writeListLock); nPacketsOld = nPackets; request = devExt->WLHeadVa; if (request){ KeReleaseSpinLock(&devExt->writeListLock); ... nPackets++; } } while (nPackets != nPacketsOld); KeReleaseSpinLock(&devExt->writeListLock); Loop Invariant: nPackets = nPacketsOld IFF lock is held

  12. The SLAM Process predicates boolean program c2bp prog. P prog. P’ slic predicates bebop SLIC rules newton path p

  13. Instrumented Code do { //get the write lock SLIC_KeAcquireSpinLock_call(); KeAcquireSpinLock(&devExt->writeListLock); nPacketsOld = nPackets; request = devExt->WLHeadVa; if (request){ SLIC_KeReleaseSpinLock_call(); KeReleaseSpinLock(&devExt->writeListLock); ... nPackets++; } } while (nPackets != nPacketsOld); SLIC_KeReleaseSpinLock_call(); KeReleaseSpinLock(&devExt->writeListLock);

  14. Predicate Abstraction of C (c2bp) • Input: a C program P and set of predicates E • predicate = pure C boolean expression • Output: a boolean program bp(P,E) that is • a sound abstraction of P • a precise (boolean) abstraction of P • Results • separate compilation (predicate abstraction) in presence of procedures and pointers

  15. do //get the write lock SLIC_KeAcquireSpinLock_call(); if (*) then SLIC_KeReleaseSpinLock_call(); fi while (*); SLIC_KeReleaseSpinLock_call(); Skeletal Boolean Program Predicates: (locked==0) (locked==1)

  16. Reachability in Boolean Programs (bebop) • Symbolic interprocedural data flow analysis • Based on CFL-reachability [Reps-Horwitz-Sagiv 95] • Explicit representation of CFG • Implicit representation of reachable states via BDDs • Worst-case complexity is O( P (GL)3 ) • P = program size • G = number of global states in state machine • L = max. number of local states over all procedures

  17. do //get the write lock SLIC_KeAcquireSpinLock_call(); if (*) then SLIC_KeReleaseSpinLock_call(); fi while (*); SLIC_KeReleaseSpinLock_call(); Shortest Error Path (Acquire 2x) Predicates: (locked==0) (locked==1)

  18. Counterexample-driven Refinement (newton) • Symbolically execute path in C program • Check for path infeasibility at each conditional • Simplify theorem prover • If path is infeasible, generate new predicates to rule out infeasible path • heuristics to generate “weak” explanation

  19. Error Path in C code do { //get the write lock KeAcquireSpinLock(&devExt->writeListLock); nPacketsOld = nPackets; request = devExt->WLHeadVa; if (request){ KeReleaseSpinLock(&devExt->writeListLock); ... nPackets++; } } while (nPackets != nPacketsOld); KeReleaseSpinLock(&devExt->writeListLock);

  20. Newton: Path Simulation Store: nPackets = nPacketsOld; request = devExt->WLHeadVa; assume(!request); assume(nPackets != nPacketsOld); Conditions:

  21. Newton Store: nPacketsOld:  nPackets = nPacketsOld; request = devExt->WLHeadVa; assume(!request); assume(nPackets != nPacketsOld); Conditions:

  22. Newton Store: nPacketsOld:  nPackets:  (1) nPackets = nPacketsOld; request = devExt->WLHeadVa; assume(!request); assume(nPackets != nPacketsOld); Conditions:

  23. Newton Store: nPacketsOld:  nPackets:  (1) devExt:  nPackets = nPacketsOld; request = devExt->WLHeadVa; assume(!request); assume(nPackets != nPacketsOld); Conditions:

  24. Newton Store: nPacketsOld:  nPackets:  (1) devExt:   ->WLHeadVa:  (3) nPackets = nPacketsOld; request = devExt->WLHeadVa; assume(!request); assume(nPackets != nPacketsOld); Conditions:

  25. Newton Store: nPacketsOld:  nPackets:  (1) devExt:   ->WLHeadVa:  (3) request:  (3,4) nPackets = nPacketsOld; request = devExt->WLHeadVa; assume(!request); assume(nPackets != nPacketsOld); Conditions:

  26. Newton Store: nPacketsOld:  nPackets:  (1) devExt:   ->WLHeadVa:  (3) request:  (3,4) nPackets = nPacketsOld; request = devExt->WLHeadVa; assume(!request); assume(nPackets != nPacketsOld); Conditions: !  (5)

  27. Newton Store: nPacketsOld:  nPackets:  (1) devExt:   ->WLHeadVa:  (3) request:  (3,4) nPackets = nPacketsOld; request = devExt->WLHeadVa; assume(!request); assume(nPackets != nPacketsOld); Conditions: !  (5)  !=  (1,2)

  28. Newton Store: nPacketsOld:  nPackets:  (1) devExt:   ->WLHeadVa:  (3) request:  (3,4) nPackets = nPacketsOld; request = devExt->WLHeadVa; assume(!request); assume(nPackets != nPacketsOld); Conditions:  !=  (1,2)

  29. Newton Store: nPacketsOld:  nPackets:  (1) nPackets = nPacketsOld; request = devExt->WLHeadVa; assume(!request); assume(nPackets != nPacketsOld); Conditions:  !=  (1,2)

  30. Newton Predicates: (nPacketsOld == ) (nPackets ==  ) ( != ) nPackets = nPacketsOld; request = devExt->WLHeadVa; assume(!request); assume(nPackets != nPacketsOld);

  31. Newton nPackets = nPacketsOld; request = devExt->WLHeadVa; assume(!request); assume(nPackets != nPacketsOld); Predicates: (nPacketsOld != nPackets)

  32. Newton nPackets = nPacketsOld; request = devExt->WLHeadVa; assume(!request); assume(nPackets != nPacketsOld); Predicates: (nPacketsOld == nPackets)

  33. do //get the write lock SLIC_KeAcquireSpinLock_call(); b := true; // npacketsOld = npackets; if (*) then SLIC_KeReleaseSpinLock_call(); b := b ? false : *; // npackets++; fi while ( !b ); // (nPackets != nPacketsOld); SLIC_KeReleaseSpinLock_call(); !b b b b b !b b Refined Boolean Program Boolean variable b represents the condition (nPacketsOld==nPackets)

  34. Results on Drivers (so far) • Handful of drivers analyzed so far • 2k-30k of C code each • Each driver has yielded bugs • SLAM process has always terminated • minutes to ½ hour • Process optimizations have huge effects

  35. Demo • Lock example • validation • Lock example with bug • error trace • SLAM’s first bug • floppy device driver

  36. Termination of SLAM • [Cousot-Cousot, PLILP’92] • widening + abstract interpretation with infinite lattices (WAIL) is more powerful than a (single) finite abstraction • [Ball-Podelski-Rajamani, TACAS’02] • finite abstractions plus iterative refinement (FAIR) is more powerful than WAIL

  37. Termination and Widening • Widening is used to achieve termination by enlarging the set of states (to reach a fixpoint) • 5  x  10 widened to 5  x • Of course, widening may lose precision • Every fixpoint algorithm that loses precision (in order to terminate) uses widening (implicitly)

  38. Fixpoint + Widening(WAIL) X := init; while X  S do X’ := X  F(X) ifX’  X then break i := oracle’s guess X := W(i, X’) od return X  S Fixpoint X := init; while X  S do X’ := X  F(X) ifX’  X then break X := X’ od return X  S

  39. F F F F F F F F W W W F W F W F F Search Space of Widenings

  40. Finite Abstraction + Iterative Refinement • If WAIL succeeds in N iterations then FAIR will succeed in N iterations • But, FAIR can succeed earlier, due to use of interior (abstract) fixpoint X := init; while truedo P := atoms(X); X# := lfp(F#P, init) ifX# S then break X := X  F(X) od return X# S

  41. F F F F F F F F F F W W W F F W F F W F F F Search Space WAIL+oracle FAIR

  42. Searching for Solutions • Once upon a time, only a human could play a great game of chess… • … but then smart brute force won the day (Deep Blue vs. Kasparov) • Once upon a time, only a human could design a great abstraction…

  43. Termination of Talk • SLAM automatically discovers inductive invariants via • predicate abstraction of C programs • model checking of boolean programs • counterexample-driven refinement • Implemented and starting to yield results on NT device drivers

  44. Model checking predicate abstraction counterexample-driven refinement BDDs and symbolic model checking Program analysis abstract interpretation points-to analysis dataflow via CFL-reachability Automated deduction weakest preconditions theorem proving Software AST toolkit Das’s Golf CU and CMU BDD Simplify, Vampyre OCAML SLAMming on the shoulders of …

  45. SLAM Future Work • More impact • Static Driver Verifier (internal, external) • More features • Heap abstractions • Concurrency • More languages • C# and CIL • More users • 2002 public release of SLAM toolkit

  46. Predictions • The holy grail of full program verification has been abandoned • New checking tools will emerge and be widely used • Tools will • exploit ideas from various analysis disciplines • alleviate the “chicken-and-egg” problem of specifications

  47. Challenges / SLAM Reading List • Specifications • Mining specifications • Abstractions • Predicate abstraction for software verification • Annotations • Types as models: model checking MP programs • Role analysis • Soundness • Ccured: type-safe retrofitting of legacy code • Scaling • Lazy abstraction

  48. The End

More Related