Title: The Next Challenges in Software Verification
1The Next Challenges inSoftware Verification
- Rupak Majumdar
- U.C. Los Angeles
2Software Validation
- Large scale reliable software is hard to build
and test - Different groups write different components
- Integration testing is a nightmare
3Property Checking
- Programmer gives partial specifications
- Code checked for consistency w/ spec
- Different from program correctness
- Specifications are not complete
- Is there a complete spec for Word ? Emacs ?
4Interface Usage Rules
- Rules in documentation
- Order of operations data access
- Resource management
- Incomplete, unenforced, wordy
- Violated rules ) bad behavior
- System crash or deadlock
- Unexpected exceptions
- Failed runtime checks
5Property 1 Double Locking
An attempt to re-acquire an acquired lock or
release a released lock will cause a deadlock.
Calls to lock and unlock must alternate.
6Property 2 Drop Root Privilege
Chen-Dean-Wagner 02
User applications must not run with root
privilege When execv is called, must have
suid ? 0
7Property 3 IRP Handler
Fahndrich
8Does a given usage rule hold?
- Undecidable!
- Equivalent to the halting problem
- Restricted computable versions are
- prohibitively expensive (PSPACE)
- Why bother ?
- Just because a problem is undecidable,
- it doesnt go away!
9Plan
- Motivation
- Lazy Abstraction
- Some Ugly Secrets
- Some Recent Progress
10Example
Example ( ) 1 do lock() old
new q q-gtnext 2 if (q ! NULL) 3
q-gtdata new unlock() new
4 while(new ! old) 5 unlock ()
return
11What a program really is
State
Transition
3 unlock() new 4
Example ( ) 1 do lock() old
new q q-gtnext 2 if (q ! NULL) 3
q-gtdata new unlock() new
4 while(new ! old) 5 unlock ()
return
12The Safety Verification Problem
Error
Safe
Initial
Is there a path from an initial to an error state
? Problem Infinite state graph Solution Set of
states ' logical formula
13Representing States as Formulas
F states satisfying F s s ² F
F FO fmla over prog. vars
F1 Ã… F2
F1 Æ F2
F1 F2
F1 Ç F2
F
F
F1 µ F2
F1 implies F2
i.e. F1Æ F2 unsatisfiable
14Idea 1 Predicate Abstraction
- Predicates on program state
- lock
- old new
- States satisfying same predicates
- are equivalent
- Merged into one abstract state
- abstract states is finite
-
15Abstract States and Transitions
State
3 unlock() new 4
Theorem Prover
lock oldnew
lock oldnew
16Abstraction
State
3 unlock() new 4
Theorem Prover
lock oldnew
lock oldnew
Existential Lifting
17Abstraction
State
3 unlock() new 4
lock oldnew
lock oldnew
18Analyze Abstraction
Analyze finite graph Over Approximate Safe )
System Safe No false negatives Problem Spurious
counterexamples
19Idea 2 Counterex.-Guided Refinement
Solution Use spurious counterexamples to refine
abstraction !
20Idea 2 Counterex.-Guided Refinement
Solution Use spurious counterexamples to refine
abstraction
1. Add predicates to distinguish states
across cut 2. Build refined abstraction
Imprecision due to merge
21Iterative Abstraction-Refinement
Solution Use spurious counterexamples to refine
abstraction
1. Add predicates to distinguish states
across cut 2. Build refined abstraction -eliminat
es counterexample 3. Repeat search Till real
counterexample or system proved safe
Kurshan et al 93 Clarke et al
00 Ball-Rajamani 01
22Lazy Abstraction
Yes
BLAST
Safe
Abstract
C Program
Refine
No
Property
Trace
23Lazy Abstraction
Yes
BLAST
Safe
C Program
Instrumented C file With ERROR label
spec.opt
Property
No
Trace
24Problem Abstraction is Expensive
Reachable
Problem abstract states 2predicates Exponentia
l Thm. Prover queries
- Observe
- Fraction of state space reachable
- Preds 100s, States 2100 ,
- Reach 1000s
25Solution1 Only Abstract Reachable States
Safe
Solution Build abstraction during search
Problem abstract states 2predicates Exponentia
l Thm. Prover queries
26Solution2 Dont Refine Error-Free Regions
Error Free
Solution Dont refine error-free regions
Problem abstract states 2predicates Exponentia
l Thm. Prover queries
27Key Idea 1 Reachability Tree
Initial
Unroll Abstraction 1. Pick tree-node (abs.
state) 2. Add children (abs. successors) 3. On
re-visiting abs. state, cut-off
1
2
3
Find min infeasible suffix - Learn new predicates
locally - And forget predicates that arent
needed - Rebuild subtree with new preds.
5
4
3
28Key Idea 1 Reachability Tree
Initial
Unroll Abstraction 1. Pick tree-node (abs.
state) 2. Add children (abs. successors) 3. On
re-visiting abs. state, cut-off
1
2
3
6
Find min infeasible suffix - Learn new
predicates - Rebuild subtree with new preds.
4
7
5
3
3
Error Free
29Key Idea 1 Reachability Tree
Initial
Unroll 1. Pick tree-node (abs. state) 2. Add
children (abs. successors) 3. On re-visiting
abs. state, cut-off
1
2
3
6
Find min spurious suffix - Learn new predicates -
Rebuild subtree with new preds.
4
7
8
5
8
3
1
1
3
Error Free
S1 Only Abstract Reachable States S2 Dont
refine error-free regions
SAFE
30Predicates grows with program size
while(1) 1 if (p1) lock() if (p1)
unlock() 2 if (p2) lock() if
(p2) unlock() n if (pn) lock()
if (pn) unlock()
T F T
Tracking lock not enough
Problem p1,,pn needed for verification Exponen
tial reachable abstract states
31Predicates grows with program size
while(1) 1 if (p1) lock() if (p1)
unlock() 2 if (p2) lock() if
(p2) unlock() n if (pn) lock()
if (pn) unlock()
LOCK
LOCK, p1
LOCK, p1
LOCK, p1
LOCK, p1
LOCK
p1p2
p1 p2
p1 p2
p1 p2
2n Abstract States
Problem p1,,pn needed for verification Exponen
tial reachable abstract states
32Predicates useful locally
while(1) 1 if (p1) lock() if (p1)
unlock() 2 if (p2) lock() if
(p2) unlock() n if (pn) lock()
if (pn) unlock()
LOCK
p1
LOCK , p1
LOCK, p1
LOCK , p1
LOCK
LOCK , p1
LOCK
LOCK
p2
pn
2n Abstract States
Solution Use predicates only where needed Using
Counterexamples - Find predicates - Find where
predicates are needed
33Key Idea 2 Parsimonious Abstractions
- Abstract Locally
- Find what predicates are required to rule out a
trace - Find where predicates can be forgotten
LOCK
LOCK , p1
LOCK, p1
LOCK
Counterexample analysis based on interpolants
34Build-and-Search
Example ( ) 1 do lock() old
new q q-gtnext 2 if (q ! NULL) 3
q-gtdata new unlock() new
4while(new ! old) 5 unlock ()
1
LOCK
1
Reachability Tree
Predicates LOCK
35Build-and-Search
Example ( ) 1 do lock() old
new q q-gtnext 2 if (q ! NULL) 3
q-gtdata new unlock() new
4while(new ! old) 5 unlock ()
1
LOCK
lock() old new qq-gtnext
2
LOCK
1
2
Reachability Tree
Predicates LOCK
36Build-and-Search
Example ( ) 1 do lock() old
new q q-gtnext 2 if (q ! NULL) 3
q-gtdata new unlock() new
4while(new ! old) 5 unlock ()
1
LOCK
2
LOCK
q!NULL
3
LOCK
1
2
3
Reachability Tree
Predicates LOCK
37Build-and-Search
Example ( ) 1 do lock() old
new q q-gtnext 2 if (q ! NULL) 3
q-gtdata new unlock() new
4while(new ! old) 5 unlock ()
1
LOCK
2
LOCK
3
LOCK
q-gtdata new unlock() new
4
LOCK
4
1
2
3
Reachability Tree
Predicates LOCK
38Build-and-Search
Example ( ) 1 do lock() old
new q q-gtnext 2 if (q ! NULL) 3
q-gtdata new unlock() new
4while(new ! old) 5 unlock ()
1
LOCK
2
LOCK
3
LOCK
4
LOCK
newold
5
LOCK
5
4
1
2
3
Reachability Tree
Predicates LOCK
39Build-and-Search
Example ( ) 1 do lock() old
new q q-gtnext 2 if (q ! NULL) 3
q-gtdata new unlock() new
4while(new ! old) 5 unlock ()
1
LOCK
2
LOCK
3
LOCK
4
LOCK
5
LOCK
5
unlock()
4
LOCK
1
2
3
Reachability Tree
Predicates LOCK
40Analyze Counterexample
Example ( ) 1 do lock() old
new q q-gtnext 2 if (q ! NULL) 3
q-gtdata new unlock() new
4while(new ! old) 5 unlock ()
1
LOCK
lock() old new qq-gtnext
2
LOCK
q!NULL
3
LOCK
q-gtdata new unlock() new
4
LOCK
newold
5
LOCK
5
unlock()
4
LOCK
1
2
3
Reachability Tree
Predicates LOCK
41Analyze Counterexample
What predicates should we track to eliminate
this spurious counterexample?
lock() old new q
1
LOCK
2
LOCK
q0
3
unlock() new
LOCK
4
LOCK
newold
5
LOCK
unlock()
LOCK
42Analyze Counterexample
Step 1 Construct a logical formula that is
satisfiable iff the trace is executable
1
LOCK
lock() old new q
lock1 1 old1 new1 q1
2
LOCK
q0
q10
3
LOCK
unlock() new
lock2 0 new2 new1 1
4
LOCK
newold
new2old1
What predicate is needed here?
5
LOCK
unlock()
lock3 0
LOCK
43Analyze Counterexample
lock() old new q
lock1 1 old1 new1 q1
Trace
Trace formula
q0
Interpolant
q10
unlock() new
lock2 0 new2 new1 1
newold
new2old1
unlock()
lock3 0
Relevant Information
Predicate
1. after executing trace prefix 2. has
present values of variables 3. makes trace
suffix infeasible
implied by TF prefix on common variables
TF suffix is unsatisfiable
44Interpolants Predicates
lock() old new q
lock1 1 old1 new1 q1
q0
old new
q10
unlock() new
lock2 0 new2 new1 1
old ? new
newold
new2old1
unlock()
lock3 0
Construct interpolants at each point in the
trace, and use the interpolants as
predicates For the theory of linear arithmetic
and equality with uninterpreted functions,
interpolants can be computed efficiently
McMillan05
45Repeat Build-and-Search
Example ( ) 1 do lock() old
new q q-gtnext 2 if (q ! NULL) 3
q-gtdata new unlock() new
4while(new ! old) 5 unlock ()
1
LOCK
1
Reachability Tree
Predicates LOCK, newold
46Repeat Build-and-Search
Example ( ) 1 do lock() old
new q q-gtnext 2 if (q ! NULL) 3
q-gtdata new unlock() new
4while(new ! old) 5 unlock ()
1
LOCK
lock() old new qq-gtnext
2
LOCK , newold
1
2
Reachability Tree
Predicates LOCK, newold
47Repeat Build-and-Search
Example ( ) 1 do lock() old
new q q-gtnext 2 if (q ! NULL) 3
q-gtdata new unlock() new
4while(new ! old) 5 unlock ()
1
LOCK
2
LOCK , newold
3
LOCK , newold
q-gtdata new unlock() new
4
LOCK , new old
4
1
2
3
Reachability Tree
Predicates LOCK, newold
48Repeat Build-and-Search
Example ( ) 1 do lock() old
new q q-gtnext 2 if (q ! NULL) 3
q-gtdata new unlock() new
4while(new ! old) 5 unlock ()
1
LOCK
2
LOCK , newold
3
LOCK , newold
4
LOCK , new old
newold
4
1
2
3
Reachability Tree
Predicates LOCK, newold
49Repeat Build-and-Search
Example ( ) 1 do lock() old
new q q-gtnext 2 if (q ! NULL) 3
q-gtdata new unlock() new
4while(new ! old) 5 unlock ()
1
LOCK
2
LOCK , newold
3
LOCK , newold
4
LOCK , new old
new!old
1
LOCK, new old
4
4
1
2
3
Reachability Tree
Predicates LOCK, newold
50Repeat Build-and-Search
Example ( ) 1 do lock() old
new q q-gtnext 2 if (q ! NULL) 3
q-gtdata new unlock() new
4while(new ! old) 5 unlock ()
1
LOCK
2
LOCK , newold
SAFE
3
LOCK , newold
4
4
LOCK , newold
LOCK , new old
1
5
5
LOCK, new old
4
4
4
1
LOCK , newold
2
3
Reachability Tree
Predicates LOCK, newold
51Key Idea Reachability Tree
Initial
Unroll 1. Pick tree-node (abs. state) 2. Add
children (abs. successors) 3. On re-visiting
abs. state, cut-off
1
2
3
6
Find min spurious suffix - Learn new predicates -
Rebuild subtree with new preds.
4
7
8
5
8
3
1
1
3
Error Free
S1 Only Abstract Reachable States S2 Dont
refine error-free regions
SAFE
52Lazy Abstraction
Yes
Safe
Abstract
C Program
Refine
No
Property
Trace
Problem Abstraction is Expensive
Solution 1. Abstract reachable states,
2. Avoid refining error-free regions
Key Idea Reachability Tree
53Device Driver Experiments
Property3 IRP Handler Win NT DDK
Pre-processed
54Plan
- Motivation
- Lazy Abstraction
- Some Ugly Secrets
- Some Recent Progress
55Device Drivers are a Nice Success Story, But
- They are really the only non-trivial systems and
specifications model checked - Other applications
- Lock / unlock in the kernel
- File open / close in open source code
- Is software model checking the right tool?
56Example Locking Revisited
0 lock 0 1 if (p) 2 assert(lock
0) 3 lock 1 4 5 . . .
- Control Flow Information Stmt 0 dominates Stmt
2 All paths going to stmt 2 must go through stmt
0 - Data Flow information Between stmt 0 and stmt 2,
lock does not get modified the value of lock
after stmt 0 is same as the value of lock at stmt
2
57Two Compiler Algorithms
- Dominator Tree captures control flow information
- For two stmts n, n we say n dominates n, n ?
D(n) if for every path to n goes through n - n is a immediate dominator of n, n Idom(n)
iff for every dominator of n is also a dominator
of n - A dominator tree is a tree whose nodes are
statements where each parent immediate dominates
its children - Static Single Assignment captures dataflow
information - Each variable is syntactically assigned once
- ?-assignments deal with joins
- x ? (x1, x2 . . . xn)
58Example
0 lock 0 1 if (p) 2 assert(lock
0) 3 lock1 4 5 . . .
n0
n1,true
n5
n1,false
SSA Form
n2
0 locko 0 1 if (p) 2 assert(lock0
0) 3 lock11 4 5 lock2 ?(lock0,
lock1) 6. . .
n3
Dominator Tree
59Dominator Invariants
n0
lock0 0
n1,true
n5
n1,false
p
lock2 ?(lock0, lock1)
p
n2
assert(lock0 0)
n3
lock1
n0 ? n1,true (lock0 0) ? p
(lock0 0)
gt
60Dominator Invariants
- Theorem
- For a node n, DInv(n) n ? (?ndominates
nn)is an - n-invariant
- After executing a node n, n holds
- If ndominates n then along every path to n, then
there is a point where n holds - After the last occurrence of n, the only nodes
visited are those that are dominated by n - None of the variables in n are modified
61Dominator Invariants are Insufficient
n0
00 locko 0 01 if (p) 02 assert(lock0
0) 03 lock11 04 05 lock2
?(lock0, lock1) 06 . . . 07 if (p) 08
assert(lock2 1) 09 lock3 0 10
11 lock4 ?(lock2, lock3)
n5
n1,true
n1,false
n7,true
n7,false
n11
n2
n3
n8
n9
(lock0 0) ? lock2 ?(lock0, lock1) ? p
gt
(lock2 1)
62?-Strengthening
n0
00 locko 0 01 if (p) 02 assert(lock0
0) 03 lock11 04 05 lock2
?(lock0, lock1) 06 . . . 07 if (p) 08
assert(lock2 1) 09 lock3 0 10
11 lock4 ?(lock2, lock3)
n5
n1,true
n1,false
n7,true
n7,false
n11
n2
n3
n8
n9
(lock0 0) ? lock2 ?(lock0, lock1) ? p
gt
(lock2 1)
63?-Strengthening
entry
CFG
n
n
Idom(n)
n x3 ?(x1, x2)
n
((x3 x1) ? DInv(Idom(n),n) ? (x3 x2) ?
DInv(Idom(n),n)) ? SI (entry, Idom(n))
n
n
Dominator Tree
642-SI is Sufficient
n0
00 locko 0 01 if (p) 02 assert(lock0
0) 03 lock11 04 05 lock2
?(lock0, lock1) 06 . . . 07 if (p) 08
assert(lock2 1) 09 lock3 0 10
11 lock4 ?(lock2, lock3)
n5
n1,true
n1,false
n7,true
n7,false
n11
n2
n8
n3
n9
p ? (lock0 0) ? (lock2 ?(lock0, lock1)) gt
(lock2 1)
652-SI is Sufficient
n0
00 locko 0 01 if (p) 02 assert(lock0
0) 03 lock11 04 05 lock2
f(lock0, lock1) 06 . . . 07 if (p) 08
assert(lock2 1) 09 lock3 0 10
11 lock4 f(lock2, lock3)
n5
n1,true
n1,false
n7,true
n7,false
n11
n2
n8
n3
n9
p ? (lock0 0) ? (((lock2 lock0)?p) ? ((lock2
lock1)?p?(lock11)))) gt (lock2 1)
66k-Structural Invariants (k-SI)
Idom(n)
- k-SI unfolds the nesting structure of the program
- k is the branch-width senstivity of the analysis
k
k-1
n
k-1
k
k-1
k-2
k-1
k-2
k-2
k
n
n
Dominator Tree
67Experiments
- Precision Tradeoffs
- Path sensitivity 2-SI captures the relevent
structural idioms - Past k2, FP does not decrease. Complex control
flow is rare for these properties
Although 2-SI is simple, 2-SI is sufficient.
68In Comparison
69Lesson
- Software verification tools are probably too
heavy weight for a bunch of applications they
have been used for - They should really be applied to deeper
properties of systems - But where are the specs?
70Why were Device Drivers a Success?
- A real problem
- Device drivers have 7X bugs as kernel
- Have to get right!
- Willing to invest time in writing specs
- Narrow and well defined interface
- Finite state protocol
- Control dominated properties
- What are other systems with these
characteristics? - And why havent we done anything about them?
71Other Systems
- OS Kernel
- Low level memory routines
-
- Software Models of Hardware
- Processors, ASICs,
72Why Havent we Verified These?
- We tried, but Blast didnt immediately work
- Yet!
- Reasoning about Data Structures
- Reasoning about Bitvectors
- Reasoning about Asynchrony
73Data Structures
Example ( ) 1 s emptyset () 2 do
lock() old new q 3 if (q
0) 4 s add (s,q) unlock()
new 5 while(new ! old) 6 unlock
() 7 if(! empty (s)) 8 y choose (s) 9
assert( y 0)
- Added a set data structure and an assertion on
data derived from the set - Modeling the actual set implementation gives
imprecise results - Mainly because of aliasing
74Bitvectors
Example (u32 a ) 1if (a 0x1 0)
error(Permission) 2 pte (a
0xFFFFF000)gtgt12 3 b tabpte 4 base b
0xFFFFFFFC 5 off a 0xFFC 6 return mbase
off
- What is going on?
- Stumps humans, compilers, verifiers
- What can we do about it?
75Asynchrony
reqs() if(rNULL) async reqs()
return rc malloc() if (rc NULL)
return ABORT_OUT_OF_MEM async
client(rc,r-gtid) r r-gtnext reqs()
global request_list r
- How can we make the
- model checker aware of
- asynchronous calls?
main() ...//setup request list r async
reqs() ...//dispatch loop
client(client_t c, int id) ...//setup c-gtid
id ...//continue processing return
76Plan
- Motivation
- Lazy Abstraction
- Some Ugly Secrets
- Some Recent Progress
- Data Structures
- Bitvectors
- Asynchrony
77Data Structures
Example ( ) 1 s emptyset () 2 do
lock() old new q 3 if (q
0) 4 s add (s,q) unlock()
new 5 while(new ! old) 6 unlock
() 7 if(! empty (s)) 8 y choose (s) 9
assert( y 0)
- Added a set data structure and an assertion on
data derived from the set - Modeling the actual set implementation gives
imprecise results - Mainly because of aliasing
78An Old Idea Modular Reasoning
Library
Client
79An Old Idea Modular Reasoning
Library
Client
Interface Functions emptyset void -gt set add
set X elt -gt set choose set -gt elt
Logical Relations x emptyset() x y
add(x,e) y x e e choose(x) x Ç e 2 x
Replaced reasoning about set implementation
with reasoning about the theory of sets
80A New Counterexample
1
Example ( ) 1 s emptyset () 2 do
lock() old new q 3 if (q
0) 4 s add (s,q) unlock()
new 5 while(new ! old) 6 unlock
() 7 if(! empty (s)) 8 y choose (s) 9
assert( y 0)
s emptyset()
2
lock() old new q
3
q!0
5
newold
6
unlock()
7
!empty(s)
8
y choose(s) y!0
Infeasible Track s
81Question Do Interpolants Exist?
- Craigs Theorem guarantees existence for first
order logic - But we are interpreting formulas over the theory
of sets
82The Good News
- Interpolants always exist for recursively
enumerable theories - The proof is a simple application of compactness
- So interpolants exist for theory of sets, theory
of lists, (quantifier-free) theory of arrays,
multisets,
83The Bad News
- The proof is a simple application of
compactness - May be algorithmically inefficient
- Daunting engineering task to construct
interpolating decision procedure for each
individual theory
84An Alternate Path Reduction
- Want to compile formulas in a new theory to
formulas in an old theory such that interpolation
in the old theory imply interpolation in the new
theory - T reduces to R can compile formulas in theory T
to formulas in theory R - And use decision procedures for R
- to answer decision questions for T
- Technically Given theories T and R, with Rµ T, a
reduction is a computable map ? from T formulas
to R formulas such that for any T-formula ? - ? and ?(?) are T-equivalent
- ? is T-satisfiable iff ?(?) is R-satisfiable
85Example Theory of Sets
- Theory of sets reduces to theory of equality with
uninterpreted functions - x y 8 e. e2 x , e2 y
- x 8 e.e? x
- xU 8 e.e2 x
- xe e2 x Æ 8 e.e2 x ) e e
- xy z 8 e.e2 x, e2 y Ç e2 z
- xyÅ z 8 e.e2 x, e2 y Æ e2 z
86Example Theory of Multisets
- Theory of multisets reduces to the combination
theory of equality with uninterpreted functions
and linear arithmetic - x y 8 e. count(x,e) count(y,e)
- x 8 e.count(x,e) 0
- x(e,n) count(x,e)max(0,n)
- Æ 8 e.e? e ) count(x,e)0
- xy z 8 e.count(x,e) count(y,e)count(z,e)
- xy z 8 e. count(x,e) max(count(y,e),
count(z,e)) - xyÃ… z 8 e. count(x,e) min(count(y,e),
count(z,e))
87Reduction and Interpolation
?- and ? in Theory T
Reduction from T to R
?- and ? in Theory R
Interpolate in R
Interpolant ? in Theory R as well as T
Eliminate quantifiers in T or R
Quantifier-free interpolant
88Main Theorem
- Interpolants for the theory of arrays, sets, and
multisets can be computed by reduction to the
combination theory of linear arithmetic and
equality with uninterpreted functions - We already have interpolating decision procedures
for this latter theory
89Analyzing the Counterexample
1
Trace Formula
s emptyset()
s1 lock1 1 old1 new q1 q1 ? 0 new
old1 lock2 0 s1? y 2 s1 y ? 0
2
lock() old new q
3
q!0
5
newold
6
unlock()
7
!empty(s)
8
y choose(s) y!0
90Analyzing the Counterexample
Trace
Trace Formula
- s emptyset()
-
- q
- q 0
- s add(s,q)
-
- q
- q ! 0
-
- !empty(s)
- y choose(s)
- assert(y0)
s1 q1 q1 0 s2 s1q1 q2 ? 0 s2?
y 2 s2 y ? 0
Example ( ) 1 s emptyset () 2 do
lock() old new q 3 if (q
0) 4 s add (s,q) unlock()
new 5 while(new ! old) 6 unlock
() 7 if(! empty (s)) 8 y choose (s) 9
assert( y 0)
91Analyzing the Counterexample
Trace
Reduced Formula
- s emptyset()
-
- q
- q 0
- s add(s,q)
-
- q
- q ! 0
-
- !empty(s)
- y choose(s)
- assert(y0)
8 e.e ? s1 q1 q1 0 (8 e.e2s2 , e2s1 Ç e
q1) q2 ? 0 (8 e.e? s2) y 2 s2 y ? 0
Example ( ) 1 s emptyset () 2 do
lock() old new q 3 if (q
0) 4 s add (s,q) unlock()
new 5 while(new ! old) 6 unlock
() 7 if(! empty (s)) 8 y choose (s) 9
assert( y 0)
92Analyzing the Counterexample
Reduced Formula
Trace
Interpolants
- s emptyset()
-
- q
- q 0
- s add(s,q)
-
- q
- q ! 0
-
- !empty(s)
- y choose(s)
- assert(y0)
8 e.e ? s1 q1 q1 0 (8 e.e2s2 , e2s1 Ç e
q1) q2 ? 0 (8 e.e? s2) y 2 s2 y ? 0
s s Æ q 0 s ? Æ (8 e.e2s ) e
0) y 0
93Forward Search with All Predicates
Example ( ) 1 s emptyset () 2 do
lock() old new q 3 if (q
0) 4 s add (s,q) unlock()
new 5 while(new ! old) 6 unlock
() 7 if(! empty (s)) 8 y choose (s) 9
assert( y 0)
1
LOCK
2
LOCK, s
3
LOCK, s, newold
LOCK , s, newold
5
4
LOCK, q 0, newold
5
6
LOCK , s, newold
LOCK, s0,new ? old
2
LOCK, s0,new ? old
LOCK, s
7
Predicates LOCK, newold, q0, s
s Æ 8 e.e2 s) e 0
(s0)
94Forward Search with All Predicates
Example ( ) 1 s emptyset () 2 do
lock() old new q 3 if (q
0) 4 s add (s,q) unlock()
new 5 while(new ! old) 6 unlock
() 7 if(! empty (s)) 8 y choose (s) 9
assert( y 0)
LOCK, s0,new ? old
3
LOCK, s0, newold
LOCK , s0, newold
5
4
LOCK, q 0, newold
5
6
LOCK , s0, newold
LOCK, s0,new ? old
2
LOCK, s0,new ? old
s0
7
8
s0
Predicates LOCK, newold, q0, s ,
y0, sÆ 8 e.e2 s) e 0
(s0)
9
y0
SAFE
95Plan
- Motivation
- Lazy Abstraction
- Some Ugly Secrets
- Some Recent Progress
- Data Structures
- Bitvectors
- Asynchrony
96Bitvectors
Example (u32 a ) 1if (a 0x1 0)
error(Permission) 2 pte (a
0xFFFFF000)gtgt12 3 b tabpte 4 base b
0xFFFFFFFC 5 off a 0xFFC 6 return mbase
off
97Bitvectors
Example (u32 a ) 1if (a 0x1 0)
error(Permission) 2 pte (a
0xFFFFF000)gtgt12 3 b tabpte 4 base b
0xFFFFFFFC 5 off a 0xFFC 6 return mbase
off
0
1
31
a,32
a
98Bitvectors
Example (u32 a ) 1if (a 0x1 0)
error(Permission) 2 pte (a
0xFFFFF000)gtgt12 3 b tabpte 4 base b
0xFFFFFFFC 5 off a 0xFFC 6 return mbase
off
11
0
31
a,32
,1
11
20
a
20
pte
12
99Bitvectors
Example (u32 a ) 1if (a 0x1 0)
error(Permission) 2 pte (a
0xFFFFF000)gtgt12 3 b tabpte 4 base b
0xFFFFFFFC 5 off a 0xFFC 6 return mbase
off
- Bitvector Types
- Sequence of
- ltname, lengthgt
offset,10
w,1
r1
a
index,20
pte
index,20
012
base
02
offset,30
off
offset,10
02
020
100Bitvectors
Example (u32 a ) 1if (a 0x1 0)
error(Permission) 2 pte (a
0xFFFFF000)gtgt12 3 b tabpte 4 base b
0xFFFFFFFC 5 off a 0xFFC 6 return mbase
off
Example (struct vaddr a ) 1if (a.rd 0)
error(Permission) 2 pte.index a.index 3
b tabpte.index 4 base b.addr 5 off
a.offset 6 return mbase off
offset,10
w,1
r1
a
index,20
pte
index,20
012
base
02
offset,30
off
offset,10
02
020
101Bitvector Type Inference
- Can set up bitvector inference as a type
inference problem - Have a type variable for each expression in the
program - Generate constraints for each bitwise operation
- Solve, using a style of ML type inference, by
splitting bitfields - Can compute the principal bitvector typing
102Experiences
- Implemented bitvector inference for C
- Applied to
- pmap, a kernel virtual memory system
- Implements the code for our running example
- Mondrian, a memory protection system
- scull, a Linux device driver
- Bitvector inference takes less than 1s
103Mondrian
- C implementation with 10 programmer-provided
assertions - Uses bit packed structures to represent memory
and permission bits - 2600 lines of code, generated 775 constraints
- Translated, after inference, to program without
bitvector operations - 18 different bit-packed structures
- Assertions verified using Blast
- 6 safe, 4 false positives
- False positives due to imprecise modeling of
arrays
104Next Step An Address Decoder
- Or, things the type system cannot do
- Bitvector operations with non-constants
- x ltlt y, x y,
- (Approximated with a value flow analysis)
- Dependent bitvectors
immediate
reg1
opcode
reg1
reg2
02
105Plan
- Motivation
- Lazy Abstraction
- Some Ugly Secrets
- Some Recent Progress
- Data Structures
- Bitvectors
- Asynchrony
- Conclusions
106Combining Strengths
Is Blast a theorem prover manipulating
formulas? A program analysis interpreting
an abstract program? A model checker exploring
states? Its all of the above! Blast is called
a model checker for historical reasons
Program Analysis - Imprecise
Abstraction Shrink state space
- Theorem Proving
- - loop invariants
- Behaviors encoded in logic
- Refine
- Theorem provers
- Computing Successors,Refine
Lazy Abstraction
Model Checking - Finite-state model, state
explosion State Space Exploration Path
Sensitive Analysis Counterexamples Finding
Relevant Facts
107More generally
- What does it take to get verified software?
- Blast is a small part in the whole process
- How can we make the programmers job easier,
through a combination of - Language support
- Process support
- Tool support
- Debugging and visualization support?
108- Questions?
- http//www.cs.ucla.edu/rupak/
109Acknowledgments
- Tom Henzinger
- Ranjit Jhala
- RuGang Xu
- Deepak Kapur
- Calogero Zarba