Modular Verification of Assembly Code with Stack-Based Control Abstractions Xinyu Feng Yale University Joint work with Zhong Shao, Alexander Vaynberg, Sen Xiang and Zhaozhong Ni.

Download Report

Transcript Modular Verification of Assembly Code with Stack-Based Control Abstractions Xinyu Feng Yale University Joint work with Zhong Shao, Alexander Vaynberg, Sen Xiang and Zhaozhong Ni.

Modular Verification of Assembly Code with
Stack-Based Control Abstractions
Xinyu Feng
Yale University
Joint work with Zhong Shao, Alexander Vaynberg,
Sen Xiang and Zhaozhong Ni
Motivation
How to verify the safety & correctness
properties of low-level system software?
System
Software
Java (JML)
Cyclone
…
CCured
C# (Spec #)
TAL
Vanilla C & C++ & Assembly?
Hardware
Verifying C & Assembly?
Many challenges …
This talk: how to specify/verify low-level stackbased control flows?


How to formulate the stack invariants?
How to design a compositional program logic?
Previous work does not apply!


Hoare-Logic done at high-level: no explicit stacks!
TAL & Proof-Carrying Code:


Mostly use continuations & CPS-based reasoning
Too general to distinguish different stack abstractions
Problems – call/return
void f(){
void h(){
h();
return;
Stacks are hidden!
return;
}
}
f:
pc
...
sw
$ra, -4($fp)
h:
jal h
pc
ct: lw
$ra, -4($fp)
;; $ra contains ct
pc
jr $ra
...
jr
$ra
Does f use the right return addr.?
Problems – setjmp/longjmp
jmp_buf env = …;
int rev(int x){
void cmp0(int x,jmp_buf env){
f0
pc
f2
if (setjmp(env) == 0){
pc
cmp0(x, env);
return 0;
cmp1(x, env);
}
void cmp1(int x,jmp_buf env){
env cannot outlive the stack frame of rev !
f1
}else{
if (x == 0)
pc
env
return 1;
longjmp(env, 1);
f0
else
}
…
}
f2
…
sp
f1
…
return;
}
Our Contributions
A simple program logic (SCAP) for modular verification of
(1) compiled C code & (2) manually-written assembly code
All systems are lemma libraries built on a
No ’s!
single CAP0 framework!
Outline of This Talk

Motivations and contributions

SCAP logic for verifying function call/return




Basic framework
Specifications
Stack-invariant
Instruction rules (to enforce the invariant)

Generalizations for complicated controls

Implementation & applications
The Machine
f1:
(data heap) H
I1
f2:
I2
f3:
I3
…
(code heap) C
::={f  I}*
0
1
2
…
pc
r1 r2 r3 … rn
(register file) R
(state) S::=(H,R)
(program) P::=(C,S,pc)
addu …
lw …
sw …
…
j f
(instr. seq.) I
Invariant-Based Verification
S0
c1
S1
c2
S2
c3
…
cn
Initial condition: Inv(S0)
Progress:
if Inv(S), then S’. S c S’.
Preservation:
if Inv(S) and S c S’, then Inv(S’).
Sn
Program Specifications
(spec)  ::= {f  a}*
a1
f1:
a2
f2:
a3
f3:
(data heap) H
I1
I2
I3
…
(code heap) C
::={f  I}*
0
1
2
…
pc
r1 r2 r3 … rn
(register file) R
(state) S::=(H,R)
(program) P::=(C,S,pc)
addu …
lw …
sw …
…
j f
(instr. seq.) I
The SCAP Program Logic

the form of specification “a”

the invariant (based on the spec. )

the proof obligations

Instruction rules for call, ret, tail call, …
Outline of This Talk

Motivations and contributions

SCAP logic for verifying function call/return




Basic framework
Specifications
Stack-invariant
Instruction rules (to enforce the invariant)

Generalizations for complicated controls

Implementation & applications
Specifications

Challenges

f uses the “right” return addr.?
f: {(p
{$ra
g0)}
n …}
0, =

Hoare triple {p} f {q}?


...
In different basic blocks!
sw
jal h
SCAP specifications: (p, g) g


p: State  Prop
g: State  State  Prop
0
ct: {(p1, g1)}
g1
g0 S S’ S’.$ra = S.$ra …
$ra, -4($fp)
lw
$ra, -4($fp)
...
jr
$ra
{$ra = n …}
Program Spec. and Code Pointers

Program Specification
::=
{f1(p1,g1), …,fn(pn,gn)}

“safe” to return (jr $ra):


$radom()  ($ra)=(p,g)
p holds at the time of return
p0
p1
jal f
g0
g1 p
3
p4
jr $ra
…
jr $ra
g4
p2
jal h
jr $ra
g3
g2
SCAP : Stack Invariant
Always safe to return?
S0
S1.$ra    (S1.$ra))=(p1, g1)  p1 S1
g1
p2
S1
S2
g0 S0 S1  g1 S1 S2 
g0 S0 S1  g1 S1 S2  g2 S2 S3 
g0
p1 jr $ra
g0 S0 S1 
S2.$ra    (S2.$ra)=(p2, g2)  p2 S2
p0
g2
p3
S3
g3
S3.$ra    (S3.$ra)=(p3, g3)  p3 S3
Logical control stack
SCAP : Stack Invariant
WFST(n, g0 S0, ) 
S1. g0 S0 S1 
 p1,g1.
(S1.$ra)=(p1, g1) 
p1 S1 
WFST(n-1, g1 S1, )
WFST(0, g0 S0, ) 
 S1. g0 S0 S1
S0
p0
g0
p1 jr $ra
g1
p2
S1
S2
g2
p3
S3
Invariant:
g3
p S  n.WFST(n, g S, )
Logical control stack
SCAP : Invariant Preservation

Inv(S):
p S  n.WFST(n, g S, )
c
S
p S 
n.WFST(n,g S,)
S’
p’ S’ 
n.WFST(n,g’S’,)
SCAP: call
p S  WFST(n, g S, )
p
S
g
p0
p1 jr $ra
g1
n
p0 S0  WFST(n+1, g0 S0, )
p0
S0
g0
S1
n+1
jal f
p S  g0 S0 S1  p1 S1
g1
n
S2
p S  p0 S0
p1 jr $ra
g0
S1
S2
g0 S0 S1  S0.$ra = S1.$ra
p S  g0 S0 S1  g1 S1 S2  g S S2
SCAP: ret
p S  WFST(n, g S, )
n
p1
S
g1
n-1
p1 S1  WFST(n-1, g1 S1, )
p
g
S1
jr $ra
p S  g S S1
p1
g1
n-1
SCAP: tail call
p S  WFST(n, g S, )
p
S
p0
S0
p0
g0
g0
g
n
p0 S0  WFST(n, g0 S0, )
jf
jr $ra
n
jr $ra
S1
S1
p S  p0 S0
p S  g0 S0 S1  g S S1
Outline of This Talk

Motivations and contributions

SCAP logic for verifying function call/return




Basic framework
Specifications
Stack-invariant
Instruction rules (to enforce the invariant)

Generalizations for complicated controls

Implementation & applications
SCAP: call
p S  WFST(n, g S, )
p
S
g
p0
p1 jr $ra
g1
n
p0 S0  WFST(n+1, g0 S0, )
p0
S0
g0
S1
n+1
jal f
p S  g0 S0 S1  p1 S1
g1
n
S2
p S  p0 S0
p1 jr $ra
g0
S1
S2
g0 S0 S1  S0.$ra = S1.$ra
p S  g0 S0 S1  g1 S1 S2  g S S2
Generalization: Stack unwinding/cutting
Multi-ret
p1
p
g
g1
jr ra
+
Tail-call
p1
p
g1
g
jr ra
p1
p
g
jr ra
g1
Example: setjmp/longjmp
jmp_buf env = …;
void cmp0(int x,jmp_buf env){
int rev(int x){
if (setjmp(env) == 0){
cmp0(x, env);
return 0;
cmp1(x, env);
}
void cmp1(int x,jmp_buf env){
if (x == 0)
}else{
longjmp(env, 1);
return 1;
else
}
return;
}
}
Further extensions
switch
call
switch
switch
switch
coroutines
ret
coroutines w. functions calls
Implementation & Applications

Coq implementation

Encoding of machine (370 lines)


Syntax & Operational semantics
Encoding of CAP0 framework/SCAP systems
(1800L)


Inference rules & Soundness proof
Certified programs w. proofs (10,000+ L)



malloc/free
……
garbage collectors [McCreight et al 06]
Summary


SCAP-family logics as lemmas
Function call;
tail-call optimization
SCAP
Exceptions: Stack-unwinding
SCAP-I, EUCAP
Exceptions: Stack-cutting
SCAP-II, ECAP
Weak-continuation
setjmp/longjmp
SCAP-II
Coroutines (w. function call)
CAP-CR (SCAP-CR)
Threads
FCCAP
CAP0: the generic framework

Inference rules are lemmas in CAP0