push button verification of file systems
play

Push-Button Verification of File Systems via Crash Refinement Helgi - PowerPoint PPT Presentation

Push-Button Verification of File Systems via Crash Refinement Helgi Sigurbjarnarson , James Bornholt, Emina Torlak, Xi Wang University of Washington 1 / 24 File systems are hard to get right Complex hierarchical on-disk data structures


  1. Push-Button Verification of File Systems via Crash Refinement Helgi Sigurbjarnarson , James Bornholt, Emina Torlak, Xi Wang University of Washington 1 / 24

  2. File systems are hard to get right Complex hierarchical on-disk data structures Maintain consistency in the face of crashes 2 / 24

  3. Example: Missing flush in ext4 Bugs are hard to reproduce Hard to test fixes It’s unlikely this will be necessary [..] but we need this in order to guarantee correctness. File System Developers 3 / 24

  4. Verification: Effective at eliminating bugs, but costly Prove the absence of bugs ◮ BilbyFS [ASPLOS 2016] ◮ FSCQ [SOSP 2015] Requires expertise and are labor intensive impl 2 , 000 20 , 000 proof 4 / 24

  5. Goal: Push-button verification No manual annotation / proof of implementation Get a concrete test case for any bug Our approach: System design to leverage a state-of-the-art automated theorem prover, Z3. 5 / 24

  6. Push-button verification: Challenges Need a formalization of correctness ◮ Needs to capture crash & recovery ◮ Needs to be automatically verifiable Too many states to exhaust ◮ Disks are large ◮ Many execution paths ◮ Non-determinism Prior work focused on bug finding ◮ eXplode [OSDI ’06], EXE [CCS ’06] ◮ Useful, but incomplete 6 / 24

  7. Contributions and outlines Yggdrasil [’yg:,drasil:] : A toolkit for building verified file systems Crash refinement ◮ A new definition of file-system correctness ◮ Enable modularity to scale verification Case study: The Yxv6 file system ◮ Similar to ext3 and xv6, but guarantees functional correctness and crash safety 7 / 24

  8. Yggdrasil Overview (Green – trusted components) consistency specification implementation invariants pass fail verifier compiler visualizer C code for counterexample file system 8 / 24

  9. Yggdrasil Overview (Green – trusted components) consistency specification implementation invariants pass fail verifier compiler visualizer C code for counterexample file system 8 / 24

  10. Yggdrasil Overview (Green – trusted components) consistency specification implementation invariants class TxnDisk(BaseSpec): pass fail def begin_tx(self): verifier self._txn = [] def write_tx(self, bid, data): compiler visualizer self._cache = self._cache.update(bid, data) self._txn.append((bid, data)) C code for counterexample def commit_tx(self): file system with self._mach.transaction(): for bid, data in self._txn: self._disk = self._disk.update(bid, data) 8 / 24

  11. Yggdrasil Overview (Green – trusted components) consistency specification implementation invariants pass fail verifier compiler visualizer C code for counterexample file system 8 / 24

  12. Yggdrasil Overview (Green – trusted components) consistency specification implementation invariants pass fail verifier compiler visualizer C code for counterexample file system 8 / 24

  13. Yggdrasil Overview (Green – trusted components) consistency specification implementation invariants pass fail verifier compiler visualizer C code for counterexample file system 8 / 24

  14. Yggdrasil Overview (Green – trusted components) consistency specification implementation invariants pass fail verifier compiler visualizer C code for counterexample file system 8 / 24

  15. Summary of the Yggdrasil toolkit Easy to use, no complex logic required Useful test-cases for bugs Limitations ◮ No concurrency ◮ Unverified Python to C compiler and FUSE 9 / 24

  16. Straw-man approach to verify FS Model FS as a state machine with a set of operations { mknod , rename , etc.}. spec S0 S1 impl I0 I1 I2 I3 Limitation: Doesn’t capture crashes 10 / 24

  17. Crash refinement: Intuition spec S0 S1 I4 I5 impl I0 I1 I2 I3 Formalize this intuition Capture crashes explicitly with a crash schedule 1 Use the crash schedule to define correctness 2 11 / 24

  18. Crash refinement 1 / 2 : Crash schedule Explicit crash-schedule ◮ A set of boolean variables ◮ Captures crashes and disk reorderings 12 / 24

  19. Crash refinement 1 / 2 : Crash schedule Explicit crash-schedule ◮ A set of boolean variables ◮ Captures crashes and disk reorderings Operation Schedule Disk state write ( a 1 , v 1 ) write ( a 2 , v 2 ) 12 / 24

  20. Crash refinement 1 / 2 : Crash schedule Explicit crash-schedule ◮ A set of boolean variables ◮ Captures crashes and disk reorderings Operation Schedule Disk state ⇒ write ( a 1 , v 1 ) write ( a 2 , v 2 ) 12 / 24

  21. Crash refinement 1 / 2 : Crash schedule Explicit crash-schedule ◮ A set of boolean variables ◮ Captures crashes and disk reorderings Operation Schedule Disk state ⇒ write ( a 1 , v 1 ) { b 1 } write ( a 2 , v 2 ) 12 / 24

  22. Crash refinement 1 / 2 : Crash schedule Explicit crash-schedule ◮ A set of boolean variables ◮ Captures crashes and disk reorderings Operation Schedule Disk state ⇒ write ( a 1 , v 1 ) { b 1 } d [ a 1 �→ if b 1 then v 1 else old ( a 1 )] write ( a 2 , v 2 ) 12 / 24

  23. Crash refinement 1 / 2 : Crash schedule Explicit crash-schedule ◮ A set of boolean variables ◮ Captures crashes and disk reorderings Operation Schedule Disk state write ( a 1 , v 1 ) { b 1 } d [ a 1 �→ if b 1 then v 1 else old ( a 1 )] ⇒ write ( a 2 , v 2 ) 12 / 24

  24. Crash refinement 1 / 2 : Crash schedule Explicit crash-schedule ◮ A set of boolean variables ◮ Captures crashes and disk reorderings Operation Schedule Disk state write ( a 1 , v 1 ) { b 1 } d [ a 1 �→ if b 1 then v 1 else old ( a 1 )] ⇒ write ( a 2 , v 2 ) { b 1 , b 2 } 12 / 24

  25. Crash refinement 1 / 2 : Crash schedule Explicit crash-schedule ◮ A set of boolean variables ◮ Captures crashes and disk reorderings Operation Schedule Disk state write ( a 1 , v 1 ) { b 1 } d [ a 1 �→ if b 1 then v 1 else old ( a 1 )] � a 1 �→ if b 1 then v 1 else old ( a 1 ) � ⇒ write ( a 2 , v 2 ) { b 1 , b 2 } d a 2 �→ if b 2 then v 2 else old ( a 2 ) 12 / 24

  26. Crash refinement 1 / 2 : Crash schedule Explicit crash-schedule ◮ A set of boolean variables ◮ Captures crashes and disk reorderings Operation Schedule Disk state write ( a 1 , v 1 ) { b 1 } d [ a 1 �→ if b 1 then v 1 else old ( a 1 )] � a 1 �→ if b 1 then v 1 else old ( a 1 ) � write ( a 2 , v 2 ) { b 1 , b 2 } d a 2 �→ if b 2 then v 2 else old ( a 2 ) Note: this program can produce 4 possible states 12 / 24

  27. Crash refinement 2 / 2 : Definition 1 Augment each op in FS with an explicit crash schedule : op ( disk , inp , sched ) → disk 2 For each op ∈ FS , prove: ∀ disk , inp , sched impl . ∃ sched spec . op spec ( disk , inp , sched spec ) = op impl ( disk , inp , sched impl ) Z3 is good at solving this particular form 13 / 24

  28. Crash refinement 2 / 2 : Definition 1 Augment each op in FS with an explicit crash schedule : op ( disk , inp , sched ) → disk implementation states 2 For each op ∈ FS , prove: ∀ disk , inp , sched impl . ∃ sched spec . op spec ( disk , inp , sched spec ) = op impl ( disk , inp , sched impl ) Z3 is good at solving this particular form 13 / 24

  29. Crash refinement 2 / 2 : Definition 1 Augment each op in FS with an explicit crash schedule : op ( disk , inp , sched ) → disk specification states 2 For each op ∈ FS , prove: ∀ disk , inp , sched impl . ∃ sched spec . op spec ( disk , inp , sched spec ) = op impl ( disk , inp , sched impl ) Z3 is good at solving this particular form 13 / 24

  30. Crash refinement summary Amenable to automatic verification using Z3 Enables modular, scalable verification Example: Decouple logical / physical data layout ◮ Verify a simple layout first (ex. one inode per block) ◮ Prove a separate crash-refinement for efficient layout Example: Stacking of layered abstractions 14 / 24

  31. Verifying multiple layers: Straw-man approach regular files, symbolic links, and directories xv6 files xv6 inodes write-ahead logging disk specification implementation 15 / 24

  32. Verifying multiple layers: Straw-man approach regular files, symbolic links, and directories xv6 files xv6 inodes write-ahead logging disk specification implementation 15 / 24

  33. Yxv6 file system: Stack of layered abstractions regular files, symbolic links, and directories Crash refinement Each layer has a Yxv6 files specification inodes Crash refinement Each layer builds Yxv6 inodes upon a lower layer transactional disk specification Crash refinement write-ahead logging Limit verification to a disk single layer at a time specification implementation 16 / 24

  34. Implementation using Python and Z3 Two Yxv6 variants ◮ Yxv6+sync: similar to xv6, FSCQ and ext4+sync ◮ Yxv6+group_commit: an optimized Yxv6+sync component specification implementation consistency inv Yxv6 250 1,500 5 infrastructure – 1,500 – FUSE stub – 250 – Also built: YminLFS, Ycp and Ylog No manual proofs! 17 / 24

  35. Yxv6 evaluation 1 How long does it take to verify? 2 Is the implementation actually correct? 3 What is the development effort for Yxv6? 4 Is the performance of Yxv6 reasonable? 18 / 24

  36. Yxv6 evaluation 1 / 4 : Verification time Let’s see how many days it takes to verify Yxv6+sync 19 / 24

Recommend


More recommend