sagar.jan

Verifying Regular Behavior of C
modules
Sagar Chaki, Edmund Clarke,
Alex Groce, CMU
Somesh Jha, Wisconsin
Regular Behavior
• Expressed as Finite Labeled Transition
Systems (FLTS)
- Locking protocols
• We use the FSP syntax to describe FLTSs
- Concurrency: State Models and Java Programs –
Jeff Magee, Jeff Kramer - Wiley
Regular Behavior: LockUnlock
• U = (lock -> L | return -> S),
L = (unlock -> U).
lock
U
L
unlock
return
S
C Module: PCI device driver
void example() {
do {
KeAcquireSpinLock(); //event lock
nPackets = nPacketsOld;
if(cond) {
KeReleaseSpinLock(); //event unlock
nPackets++;
}
} while(nPackets != nPacketsOld);
KeReleaseSpinLock();
//event unlock
}
Our Goal
• To show that LockUnlock simulates the PCI
driver
- Need to keep track of the predicate (nPackets ==
nPacketsOld)
- Flow-insensitive analysis will fail
• Provide diagnostic feedback in case the
simulation does not exist
POSIX pthread Spec
• pthread_mutex_lock()
- Acquires lock and returns 0
- Increments user count on lock and returns 0
- Returns non-zero error code
lock
U
U
ret_zero
U
inc_count
U
ret_err
Glibc pthread source code
int pthread_mutex_lock() {
case PTHREAD_MUTEX_RECURSIVE_NP:
self = thread_self();
if (mutex->__m_owner == self) {
mutex->__m_count++;
//inc_count
return 0;
//ret_zero
}
pthread_lock(&mutex->__m_lock, self);
//lock
mutex->__m_owner = self;
mutex->__m_count = 0;
return 0; }
//ret_zero
C module
• Collection of C procedure definitions
- The pthread library
• Designated main procedure
- The pthread_mutex_lock function
- We are interested in behavior observed during an
invocation of main
C module
• For each procedure called, one of two things
must be available
- Definition of procedure
- Information about behavior observed during
invocation of procedure
Verification
• Check that every possible behavior of main is
also a behavior of the FLTS
- Trace-containment
• In practice it is sufficient to check for a
stronger condition viz. simulation
- FLTS ≥ main
FLTS: Definition
• Fix an alphabet: Σ
- Assume Σ contains special symbol ε
• Three-tuple: <Q,I,δ>
- Q: finite set of states
- I: initial state
- δ: transition relation over Q X Σ X Q
Example
V’
ε
lock
L’
U’
unlock
return
M’
S’
ε
Simulation
•
•
FLTSs: <Q1,I1,δ1>,<Q2,I2,δ2>
Relation ≥ Q1 X Q2 is simulation if
(1) Init: For all t Є I2 exists s Є I1 s.t. s ≥ t
(2) Step: s ≥ t and (t,a,t’) Є δ2 => exists s’ s.t.
(s,a,s’) Є δ1 and s’ ≥ t’
(3) Stutter: s ≥ t and (t,ε,t’) Є δ2 => s ≥ t’ OR exists
s’ s.t. (s,ε,s’) Є δ1 and s’ ≥ t’
Overall method
• Step 1: Compute relation R that satisfies
conditions 2 and 3
• Step 2: Check that R satisfies condition 1 as
well
Step 1
• Start with R = Q1 X Q2
• Iteratively refine R using condition 2 and 3 till
a fixed point is reached
- If (s,t) Є R and if (t,a,t’) Є δ2 then remove (s,t) if
there does not exist s’ s.t. (s,a,s’) Є δ1 and (s’,t’) Є
R
Example
lock
U
return
unlock
{U,L,S}
{U,L,S}
V’
ε
S
lock
{U,L,S}
L’
U’
unlock
return
M’
S’
{U,L,S}
{U,L,S}
ε
L
Example
lock
U
return
unlock
{U,L,S}
{U}
V’
ε
S
lock
{U,L,S}
L’
U’
unlock
return
M’
S’
{U,L,S}
{U,L,S}
ε
L
Example
lock
U
return
unlock
{U}
{U}
V’
ε
S
lock
{U,L,S}
L’
U’
unlock
return
M’
S’
{U,L,S}
{U,L,S}
ε
L
Example
lock
U
return
unlock
{U}
{U}
V’
ε
S
lock
{U,L,S}
L’
U’
unlock
return
M’
S’
{U,L,S}
{L}
ε
L
Example
lock
U
return
{U}
{U}
V’
ε
S
lock
{L}
L’
U’
unlock
return
M’
S’
{U,L,S}
{L}
unlock
ε
L
FLTS from C module
• Based on a set of predicates
• Each state of the FLTS consists of a control
location of the C module and a valuation to
the predicates
- Non-context-sensitive
• Weakest preconditions and theorem proving
are used to compute the transitions on-the-fly
Predicates and Property
• Need to specify predicates to be used
- predicate (nPackets == nPacketsOld);
• Need to specify the simulation relation to be
checked
- property U simulates example;
Additional Info
• Specify that call to KeAcquireSpinLock()
represents a locking action
- action call KeAcquireSpinLock = lock;
• Similarly for KeReleaseSpinLock()
- action call KeReleaseSpinLock = unlock;
Related Work
• Based on predicate abstraction
- Graf & Saidi, Dill et. al.
• Do not work with C
- SLAM, Bandera
• Specify desired behavior as patterns, or
unwanted behavior as monitors
- Engler et. al., SLAM, Bandera
Challenges
• Extract event information from C code
• Provide diagnostic feedback in case
simulation is not found
• Pointers and dynamic memory allocation
• Introduce context-sensitivity
• Introduce concurrency
Major Differences
• Unlike Engler et. al.
- Flow-sensitive, based on predicates
- Check arbitrary regular behavior
• Unlike SLAM
- On-the-fly: no boolean programs
- Not context-sensitive
• Unlike Bandera
- Work with C
- Check arbitrary regular behavior