290 likes | 455 Views
Automatically Validating Temporal Safety Properties of Interfaces. Thomas Ball and Sriram K. Rajamani Software Productivity Tools, Microsoft Research. Presented for CMSC631 by Iulian Neamtiu. Goal: Validate temporal safety properties using model checking. SLAM Project, Microsoft Research.
E N D
Automatically Validating Temporal Safety Properties of Interfaces Thomas Ball and Sriram K. Rajamani Software Productivity Tools, Microsoft Research Presented for CMSC631 by Iulian Neamtiu
Goal: Validate temporal safety properties using model checking SLAM Project, Microsoft Research http://research.microsoft.com/slam/
Motivation • Large-scale software – many components, many programmers • Integration testing • Impossible • Ineffective at best • Fuzzy requirements -> inconsistent implementation • Consistent requirements -> inconsistent implementation (Jim Larus)
SLAM Approach • Modules interact properly… • If program observes temporal safety properties of interfaces it uses • temporal safety= properties whose violation is witnessed by a finite execution trace, i.e. path to ERROR state • State temporal safety properties formally • Automatic verification • Interface compliance checked statically (catch bugs early)
SLAM Process Generate abstract boolean program from C code Model checker boolean program C2BP prog. P prog. P’ slic BEBOP SLIC rule predicates path NEWTON Predicate discoverer Language for specifying safety properties
SLAM - formally • P’ a C program, Ei={e1,e2,…,en} a set of predicates, apply C2BP to create a boolean program BP(P’,Ei) • Apply BEBOP to check whether exists a path piin BP(P’,Ei) that reaches ERROR state • if pinot found, terminate with SUCCESS • if pifound go to 3 • Use NEWTONto check pifeasible • Ifpifeasible, terminate with FAILURE • Ifpinot feasible find set Fi of predicates that explains infeasibility • Ei+1= Ei UFi+1 , i=i+1, go to 1
Example – device driver do { KeAcquireSpinLock(); nPacketsOld = nPackets; if(request){ request = request->Next; KeReleaseSpinLock(); nPackets++; } } while (nPackets != nPacketsOld); KeReleaseSpinLock(); Prove safety – “something bad does not happen” (lock acquired/released twice)
Step 0 – Property Specification typedef {Locked, Unlocked} STATETYPE; typedef {Acq, Rel} MTYPE; STATETYPE state = Unlocked; FSM(m : MTYPE){ if ((state==Unlocked) && (m==Acq)) A: state = Locked; else if ((state==Locked) && (m==Rel)) B: state = Unlocked; else ERROR: ; } SLIC Specification = FSM • Global state • State transitions (events)
Step 1 - Instrumentation do { KeAcquireSpinLock(); C: FSM(Acq); nPacketsOld = nPackets; if(request){ request = request->Next; KeReleaseSpinLock(); D: FSM(Rel); nPackets++; } E: } while (nPackets != nPacketsOld); KeReleaseSpinLock(); F: FSM(Rel); typedef {Locked, Unlocked} STATETYPE; typedef {Acq, Rel} MTYPE; STATETYPE state = Unlocked; FSM(m : MTYPE){ if ((state==Unlocked) && (m==Acq)) A: state = Locked; else if ((state==Locked) && (m==Rel)) B: state = Unlocked; else ERROR: ; } SLIC Specification Instrumented Program P’ Program P
Outline • Step 0 - Specification • Step 1 - Instrumentation • Step 2 - Abstraction • Step 3 - Model Checking • Step 4 - Theorem Proving • Step 5 – Predicate discovery manual automated
Abstraction • Abstract Interpretation • In • C program P • set of predicates E={e1,e2,…,en} • Out • abstract boolean program BP(P,E) withnboolean variables V={b1,b2,…,bn} • Boolean program (C-like) • all vars have type bool • control nondeterminism (*) • only call by value
Step 2 – Abstraction (C2BP) typedef {Locked, Unlocked} STATETYPE; typedef {Acq, Rel} MTYPE; STATETYPE state = Unlocked; FSM(m : MTYPE){ if ((state==Unlocked) && (m==Acq)) A: state = Locked; else if ((state==Locked) && (m==Rel)) B: state = Unlocked; else ERROR: ; } decl {state==Locked, state==Unlocked}; void FSM({m==Acq,m==Rel}){ if ({state==Unlocked} & {m==Acq}) A: {state==Locked, state==Unlocked }:=1,0; else if ({state==Locked} & {m==Rel}) B: {state==Locked, state==Unlocked }:=0,1; else ERROR: ; }
Step 2 – Abstraction (C2BP) do { skip; C:FSM(1,0); skip; if(*){ skip; skip; D:FSM(0,1); skip; } E: } while (*); skip; F: FSM(0,1); do { KeAcquireSpinLock(); C:FSM(Acq); nPacketsOld = nPackets; if(request){ request = request->Next; KeReleaseSpinLock(); D: FSM(Rel); nPackets++; } E: } while (nPackets != nPacketsOld); KeReleaseSpinLock(); F: FSM(Rel); Instrumented Program P’ Boolean Program BP(P’,E0)
Step 3 - Model Checking (BEBOP) do { skip; C:FSM(1,0); skip; if(*){ skip; skip; D:FSM(0,1); skip; } E: } while (*); skip; F: FSM(0,1); decl {state==Locked, state==Unlocked}; void FSM({m==Acq,m==Rel}){ if ({state==Unlocked} & {m==Acq}) A: {state==Locked, state==Unlocked }:=1,0; else if ({state==Locked} & {m==Rel}) B: {state==Locked, state==Unlocked }:=0,1; else ERROR: ; } 1 3 4 2 Boolean Program BP(P’,E0) Is there a path that leads to ERROR ? YES [C,A,E,C,ERROR ]
Step 4 – Theorem Proving (NEWTON) do { KeAcquireSpinLock(); C:FSM(Acq); nPacketsOld = nPackets; if(request){ request = request->Next; KeReleaseSpinLock(); D: FSM(Rel); nPackets++; } E: } while (nPackets != nPacketsOld); KeReleaseSpinLock(); F: FSM(Rel); typedef {Locked, Unlocked} STATETYPE; typedef {Acq, Rel} MTYPE; STATETYPE state = Unlocked; FSM(m : MTYPE){ if ((state==Unlocked) && (m==Acq)) A: state = Locked; else if ((state==Locked) && (m==Rel)) B: state = Unlocked; else ERROR: ; } // nPacketsOld==nPackets, nPacketsOld != nPackets Is path [C,A,E,C] feasible ? NO
Step 5 – Predicate Discovery (NEWTON) do { skip; C:FSM(1,0); skip; if(*){ skip; skip; D:FSM(0,1); skip; } E: } while (*); skip; F: FSM(0,1); b: {nPackets == nPacketsOld}; do { skip; b:=1; C:FSM(1,0); skip; if(*){ skip; skip; D:FSM(0,1); skip; b:=0; } E: } while (!b); skip; F: FSM(0,1); Boolean Program BP(P’,E0) Boolean Program BP(P’,E1)
Step 3 - Model Checking (BEBOP) do { skip; b:=1; C:FSM(1,0); skip; if(*){ skip; skip; D:FSM(0,1); skip; b:=0; } E: } while (!b); skip; F: FSM(0,1); decl {state==Locked, state==Unlocked}; decl b: {nPackets==nPacketsOld}; void FSM({m==Acq,m==Rel}){ if ({state==Unlocked} & {m==Acq}) A: {state==Locked, state==Unlocked }:=1,0; else if ({state==Locked} & {m==Rel}) B: {state==Locked, state==Unlocked }:=0,1; else ERROR: ; } Is there a path that leads to ERROR ? NO
C2BP • From a C program P and a set of predicates E={e1,e2,…,en} create an abstract boolean program BP(P,E) which has n boolean variables V={b1,b2,…,bn} • Determine for each statement s in P and predicate eiin E how the execution of s can affect the truth value of ei • if it doesn’t, s->skip
C2BPcont’d • Static analysis • alias • logical model: p, p+i same object • interprocedural • side-effects (conservative)
BEBOP • Essentially a model checker • Interprocedural dataflow analysis -> reachable states • Uses BDDs to represent state/transfer functions • ERROR state reachability reduces to vertex reachability on the CFG of the boolean program BP which is decidable
NEWTON Predicate discoverer / Theorem prover • walk error path p found by BEBOP • compute conditions (predicate values) along p • if algorithm terminates • inconsistence detected ( =!), add to list of predicates, repeat whole process • else report p as witness
Results NT device drivers • Max 60000 LOC • <10 user-supplied predicates, tens-hundreds inferred • < 20-30 iterations • 672 runs daily, 607 terminate within 20 minutes
Conclusions • SLAM = process for checking temporal safety properties • Formally state safety properties that interface clients must observe • Fully automated validation (iterative refinement) • Sound; if process terminates either SUCCESS or FAILURE (w/counterexample) reported • Accurate (few false positives) - Poor scalability
Thank You Questions ?
Complexity • O(|P|x2|E|) worst case • In practice O(|E|3)
SLAM = A collection of tools SLIC • Language for specifying safety properties C2BP • Generate abstract boolean program from C code BEBOP • Model checking boolean programs NEWTON • Theorem prover • Refine boolean program