180 likes | 347 Views
Automated Verification of Practical Garbage Collectors. Chris Hawblitzel (Microsoft Research) Erez Petrank ( Technion ). Downloading safe code. Java bytecode / .NET bytecode / JavaScript / ActionScript. Web browser. JIT compiler. run-time system. x86. exception handling. threads.
E N D
Automated Verification of Practical Garbage Collectors Chris Hawblitzel (Microsoft Research) Erez Petrank (Technion)
Downloading safe code Java bytecode / .NET bytecode / JavaScript / ActionScript Web browser JIT compiler run-time system x86 exception handling threads garbage collector
GC vulnerabilities MS07-057: Cumulative security update for Internet Explorer Date: October 2007 ...Internet Explorer 6 may exit with an access violation when the JavaScript garbage collector runs and you have dynamically removed a TBODY, THEAD, or TFOOT HTML tag from a table in Windows XP... Mozilla Firefox Bug in JavaScript Garbage Collector Lets Remote Users Deny ServiceAdvisory: Mozilla Foundation Security Advisory Date: Apr 16 2008 A remote user can create specially crafted HTML that, when loaded by the target user, will trigger a flaw in the JavaScript garbage collector code and cause the target user's browser to crash. ... The vendor indicates that similar crashes have been exploitable in the past, so arbitrary code execution may be possible... From: Apple Product Security Date: Fri, 11 Jul 2008 ... Available for:iPhone v1.0 through v1.1.4,iPod touch v1.1 through v1.1.4 Description: A memory corruption issue exists in JavaScriptCore's handling of runtime garbage collection. Visiting a maliciously crafted website may lead to an unexpected application termination or arbitrary code execution. This update addresses the issue through improved garbage collection.
GC verification • New work: realistic GCs • Runsreal Bartok-compiled C# • real memory layouts • Automated verification • annotated GCs in BoogiePL • assemble BoogiePL to x86 • specifications in BoogiePL • Z3 automated SMTprover Earlier work • Small GCs • Interactive proofs
Challenges to automated verification • Reasoning about graphs • Undecidable logic • Large formulas
Outline • Background • Simple verified GC • miniature mark-sweep collector • quantifiers • Practical verified GCs
Mark-sweep and copying collectors abstract graph A (root) C B mark-sweep copying from copying to A A A C C B B B
Garbage collector properties A (root) C B • Verified: • isomorphism (McCreight, Shaoet al 2007) • effectiveness • after gc, unreached objects reclaimed • Not verified: • Termination • Efficiency A C B
Verifying Mark procedure Mark(ptr:int) requires GcInv(Color, $toAbs, $AbsMem, Mem); requires memAddr(ptr) && T(ptr); requires $toAbs[ptr] != NO_ABS; modifies Color; ensures GcInv(Color, $toAbs, $AbsMem, Mem); ensures (forall i:int::{T(i)} T(i) && !Black(Color[i]) ==> Color[i] == old(Color)[i]); ensures !White(Color[ptr]); { if (White(Color[ptr])) { Color[ptr] := 2; // make gray call Mark(Mem[ptr,0]); call Mark(Mem[ptr,1]); Color[ptr] := 3; // make black } }
Verifying Mark: abstract <--> concrete procedure Mark(ptr:int) requires GcInv(Color, $toAbs, $AbsMem, Mem); requires memAddr(ptr) && T(ptr); requires $toAbs[ptr] != NO_ABS; modifies Color; ensures GcInv(Color, $toAbs, $AbsMem, Mem); ensures (forall i:int::{T(i)} T(i) && !Black(Color[i]) ==> Color[i] == old(Color)[i]); ensures !White(Color[ptr]); { if (White(Color[ptr])) { Color[ptr] := 2; // make gray call Mark(Mem[ptr,0]); call Mark(Mem[ptr,1]); Color[ptr] := 3; // make black } } $AbsMem A B $toAbs $toAbs Mem forall i:int ::{T(i)} T(i) && memAddr(i) ==> $toAbs[Mem[i, field]] == $AbsMem[$toAbs[i], field] A B
Verifying Mark: no black-->white procedure Mark(ptr:int) requires GcInv(Color, $toAbs, $AbsMem, Mem); requires memAddr(ptr) && T(ptr); requires $toAbs[ptr] != NO_ABS; modifies Color; ensures GcInv(Color, $toAbs, $AbsMem, Mem); ensures (forall i:int::{T(i)} T(i) && !Black(Color[i]) ==> Color[i] == old(Color)[i]); ensures !White(Color[ptr]); { if (White(Color[ptr])) { Color[ptr] := 2; // make gray call Mark(Mem[ptr,0]); call Mark(Mem[ptr,1]); Color[ptr] := 3; // make black } } forall i:int::{T(i)} T(i) && memAddr(i) ==> Black(Color[i]) ==> !White(Color[Mem[i,field]])
Quantifiers and triggers procedure Mark(ptr:int) requires GcInv(Color, $toAbs, $AbsMem, Mem); requires memAddr(ptr) && T(ptr); requires $toAbs[ptr] != NO_ABS; modifies Color; ensures GcInv(Color, $toAbs, $AbsMem, Mem); ensures (forall i:int::{T(i)} T(i) && !Black(Color[i]) ==> Color[i] == old(Color)[i]); ensures !White(Color[ptr]); { if (White(Color[ptr])) { Color[ptr] := 2; // make gray (equivalent to “Color := Color[ptr := 2];” call Mark(Mem[ptr,0]); call Mark(Mem[ptr,1]); Color[ptr] := 3; // make black } } explicit introductions of T(...) to provoke quantifier instantiations “trigger” quantifier instantiation i =e when T(e) seen T is a dummy function: T(e) <==> true forall i:int::{$toAbs[i]}{$toAbs’[i]} ... $toAbs[i] != NO_ABS ==>$toAbs[i] == $toAbs’[i] ... also trigger on old, new $toAbs (and split $toAbs into “regions”)
Outline • Background • Simple verified GC • Practical verified GCs • Object layouts, GC tags, static data, stacks, interior pointers, ... • Mark-sweep collector • Free list + cache • Mark stack • Table of color bits (2 bits per color) • Copying collector • Simple (non-generational) 2-space Cheney queue algorithm • Mutator-GC interface: • Initialize • read, write • AllocateObject, AllocateString, AllocateVector, AllocateArray
procedure CopyAndForward($ptr:int, $_tj:int) requires ecx == $ptr; requires CopyGcInv(...); requires Pointer($r1, $ptr, $r1[$ptr]); ... { call edx := GcRead(ecx + 4); esp := esp - 4; call GetSize($ptr, edx, $r1, $r1); ebp := eax; ... edi := 0; edx := 0; loop: assert 4 * edi == edx; assert CopyGcInv(...); ... if (edx >= ebp) { gotoloopEnd; } call copyWord($ptr, $_tj, esi, edi, ebp); call edi := Add(edi, 1); call edx := Add(edx, 4); goto loop; loopEnd: call eax := Lea(esi + 4); call GcWrite(ecx + 4, eax); ... Practical, verified copying collector code automatic translation movedi, 0 movedx, 0 CopyAndForward$loop: cmpedx, ebp jaeCopyAndForward$loopEnd
Performance (2 of 10 benchmarks) Asmlc Bartok execution time (seconds) execution time (seconds) available memory(MB) available memory (MB) caveat: Bartok collectors support more features (e.g. threads, pinning) than verified collectors
Code size, verification time lines of proof script: 0
Conclusions http://www.codeplex.com/singularity Source Code: base/Imported/Bartok/runtime/verified/GCs • Verified run-time status: two practical GCs • Reasoning about graphs ==> isomorphism • Undecidable logic ==> triggers • Large formulas ==> modern automated prover (Z3) • Original mutator-GC interface specification had two bugs, so: • Copying collector: • crashed 1st time (spec bug: Initialize not asked to save ebp) • crashed 2nd time (spec bug: preheader vs. header confusion) • worked 3rd time • Mark-sweep (with corrected spec): worked 1st time