Date post: | 19-Dec-2015 |
Category: |
Documents |
View: | 216 times |
Download: | 0 times |
Extensible Verification of Extensible Verification of Untrusted CodeUntrusted Code
Bor-Yuh Evan Chang, Adam Chlipala, Kun Gao,George Necula, and Robert Schneck
May 14, 2004OSQ Retreat
Santa Cruz, California
5/14/2004 2
Type Safety as an Assurance Type Safety as an Assurance MechanismMechanism
• Type safety is an accepted assurance mechanism
• Today– Good:Type check source code in a strongly-typed
high-level language (e.g. ML, C#, Java)– Better: Type check intermediate code (e.g., MS-
CLI, JVML)
OR codecode
untrusted trusted
typechecker
5/14/2004 3
Type Systems Today (JVML,MS-Type Systems Today (JVML,MS-CLI,TAL)CLI,TAL)• Hard-wired in the verifier• High-level and tailored to particular source
languages– E.g, built-in object-oriented features
• Hard to compile other source languages– Unnatural, loss of performance or
expressiveness– E.g, ML ! JVML or Java ! TAL
• Under constant pressure to become more complex– To handle more source languages– To be able to check more complex code (e.g.
optimizations)
5/14/2004 4
Generality by CustomizationGenerality by Customization• MS-CLI is designed for a multiple languages, but
– quite complex (e.g. 6-9 versions of function call)– not complex enough (the ILX project adds more calls)
• Still not general enough!– JVML: native code interface– MS-CLI: unverifiable subset of the language
• Proposal: Allow multiple type systems and other verification methods (e.g. PCC) to co-exist– Fix only the safety policy (e.g. memory safety)– Not the enforcement mechanism (e.g. a type system)
5/14/2004 5
Design Goals of the Open VerifierDesign Goals of the Open Verifier
• Should be easy to develop “verifier extensions”– Only incrementally more complicated than a
conventional verifier for the same language– Be able to retrofit existing compilers or
conventional verifiers
• Client should have complete control over the type system or other conventions– Calling conventions, exceptions, stack
usage, data layout
5/14/2004 6
Bytecode Verification ExampleBytecode Verification Example
2 rarg = 0
3 rrv à rrv + 1
4 rarg à m[rarg]
1 rrv à 0
5 jump [rra]
T
F
0
::= int | list | nelist
len : list ! int
5/14/2004 7
Bytecode Verification ExampleBytecode Verification Example
2 rarg = 0
3 rrv à rrv + 1
4 rarg à m[rarg]
1 rrv à 0
5 jump [rra]
arg : list
arg : list Æ rv : int
T
F
Why?
arg : list Ærv : int
arg : nelist Æ rv : int
arg : nelist Æ rv : int
5/14/2004 8
Bytecode Verifier CorrectnessBytecode Verifier Correctness
• How do we know the verifier didn’t forget any checks?– Should not need to provide proofs involving
the model of the machine semantics
• Use strongest post-condition generation to eliminate proof obligations about machine transitions– Show at each program point i with next
states N,
post(Ii) ) Çj2N Ij
5/14/2004 9
Verified Bytecode VerificationVerified Bytecode Verification
2 rarg = 0
3 rrv à rrv + 1
4 rarg à m[rarg]
1 rrv à 0
5 jump [rra]
I1 = arg : list
I2 = arg : list Æ rv : int
Why?
pc = 2 Æ arg : list Æ rv = 0
post(I1)
post(I1) ) I2new I2 = post(I1) with add (rv : int) by imm_int with drop (rv = 0)
T
F
5/14/2004 10
BranchBranch
2 rarg = 0
3 rrv à rrv + 1
4 rarg à m[rarg]
1 rrv à 0
5 jump [rra]
arg : list
I2 = arg : list Æ rv : int
I5 =arg : list Ærv : int
Why?
pc = 3 Æ arg : list Æ rv : int Æ arg 0Ç
pc = 5 Æ arg : list Æ rv : int Æ arg = 0
post(I2)
case post(I2) of Ifalse where (pc = 3) ) new I3 = Ifalse with let h,h’ = find (arg : list), find (arg 0) in add (arg : nelist) by (cons h h’) with drop (arg : list) with drop (arg 0)| Itrue where (pc = 5) ) new I5 = Itrue with drop (arg = 0)
post(I2) ) I3 Ç I5
T
FI3 = arg : nelist Æ rv : int
5/14/2004 11
ArithmeticArithmetic
2 rarg = 0
3 rrv à rrv + 1
4 rarg à m[rarg]
1 rrv à 0
5 jump [rra]
arg : list
arg : list Æ rv : int
arg : list Ærv : int
I3 = arg : nelist Æ rv : int
Why?
9rv3. pc = 4 Æ arg : nelist Æ rv3 : int Æ rv = rv3 + 1
post(I3)
new I4 = post(I3) with let h = find (rv3 : int) in add (rv : int) by (plus h (imm_int)) with drop (rv3 : int) with drop (rv = rv3 + 1)
post(I3) ) I4
T
F
I4 = arg : nelist Æ rv : int
5/14/2004 12
Memory ReadMemory Read
2 rarg = 0
3 rrv à rrv + 1
4 rarg à m[rarg]
1 rrv à 0
5 jump [rra]
arg : list
I2 = arg : list Æ rv : int
arg : list Ærv : int
arg : nelist Æ rv : int
I4 = arg : nelist Æ rv : int
Why?
9 arg4. pc = 2 Æ arg4 : nelist Æ rv : intÆ addr arg4 Æ arg = m[arg4]
Çpc = err Æ arg : nelist Æ rv : int Æ : (addr arg)
post(I4)
case post(I4) of Iok where _ ) Iok with let h = find (arg4 : nelist) in add (arg : list) by (lem2 h) with …| Ierr where : (addr arg) by bad ) Ierr with let h = … in add ? by (bad (lem1 h)) with …
post(I4) ) I2 Ç F
T
F
lem1: If (arg : nelist) then (addr arg)lem2: If (arg : nelist) then (m[arg] : list)
F = pc = err Æ ?
5/14/2004 13
Customizability Yields Controlled TrustCustomizability Yields Controlled Trust
Trust Meter
Trust Any Binary (*.exe)
Trust Specialized Verifiers (JVM)
Trust Compilers (javac)
Trust Typing Rules
Trust Model of Machine Semantics
5/14/2004 14
SummarySummary
• Provide a “natural” language for the verifier to describe in a checkable form the reasoning it makes– Close to conventional type-based verifiers– Amenable to other safety enforcement
mechanisms, such as PCC
• PCC– Most of the time, just goes along with post(¢)– When proof is required, give the proof attached
with the code– Proof representation can be chosen by the client
5/14/2004 15
typechecker
SummarySummary
• Towards practical extensible verification of untrusted code– Ask only for reasoning already done by
conventional verifiers
OR
untrusted trusted
typecheckercodecode
post(¢)
“preservationand progress”
5/14/2004 16
ConclusionConclusion
• We have verifier extensions for– Cool (“mini-Java”) [Aiken et al.]
• can verify output of existing Cool compilers
– TAL (functional typed assembly language)• retrofitted TALx86 [Morrisett et al.]
– PCC• Philosophy:
– To verify complete software systems, • not a general, super-expressive type system• rather a framework to allow existing ones to
work together
5/14/2004 18
ReturnReturn
2 rarg = 0
3 rrv à rrv + 1
4 rarg à m[rarg]
1 rrv à 0
5 jump [rra]
arg : list
arg : list Æ rv : int
I5 =arg : list Ærv : int
arg : nelist Æ rv : int
arg : nelist Æ rv : int
Why?
pc = ra0 Æ arg : list Æ rv : int
post(I5)
post(I5) withdrop (arg : list)
post(I5) ) R
T
F
R = pc = ra0 Æ rv : int