automated verification of systems software with serval
play

Automated verification of systems software with Serval Xi Wang - PowerPoint PPT Presentation

Automated verification of systems software with Serval Xi Wang Joint work with Luke Nelson, James Bornholt, Ronghui Gu, Andrew Baumann, and Emina Torlak University of Washington Columbia University Microsoft Research 1 Today: eliminating


  1. Automated verification of systems software with Serval Xi Wang Joint work with Luke Nelson, James Bornholt, Ronghui Gu, Andrew Baumann, and Emina Torlak University of Washington Columbia University Microsoft Research 1

  2. Today: eliminating bugs in low-level systems software Process Process Process OS Kernel / security monitor • Low-level bugs: buffer overflow, div by zero • Logic bugs: implementation does something unintended • Design bugs: unintended design is insecure 2

  3. Example: undefined behavior uint64_t mul(uint16_t a, uint16_t b) { uint32_t c = a * b; return c; } Question: what’s the result of mul(60000, 60000)? • (a) 3,600,000,000 • (b) 18,446,744,073,014,584,320 • (c) something else 3

  4. Eliminating bugs with formal verification seL4 (SOSP’09) Process Process Process Ironclad, Jitk (OSDI’14) CertiKOS (PLDI’16) OS Kernel / security monitor Komodo (SOSP’17) 4

  5. Eliminating bugs with formal verification seL4 (SOSP’09) • Strong correctness guarantees Process Process Process Ironclad Apps (OSDI’14) • Require manual proofs FSCQ (SOSP’15) • CertiKOS 200k lines of proof CertiKOS (PLDI’16) OS Kernel / security monitor Komodo (SOSP’17) • Multiple person-years 5

  6. Prior work: automated (push-button) verification Yggdrasil Automated OSDI’16 verifier Hyperkernel SOSP'17 Finite Decidable implementation specification Nickel OSDI'18 6

  7. Prior work: automated (push-button) verification Implementation Specification • No proofs on implementation Automated verifier • Requires finite implementation • Restricts specification SMT solver ✔ ✘ 7

  8. Challenges How to lower effort of writing Implementation Specification automated verifiers? Automated verifier How to find and fix performance bottlenecks? SMT solver How to retrofit to existing ✔ ✘ systems? 8

  9. Contributions • Serval: a framework for writing automated verifiers • ARM, RISC-V, x86, LLVM, BPF • Scaling via symbolic optimizations • Experience • Retrofitted CertiKOS and Komodo for Serval • Found 30+ new bugs in Linux BPF JIT and 3 in Keystone no guarantees on concurrency or side channels 9

  10. Verifying a system with Serval System specification RISC-V instructions RISC-V verifier Serval Rosette Z3 SMT solver 10

  11. Verifying a system with Serval System specification RISC-V instructions RISC-V verifier Serval Rosette Z3 SMT solver 11

  12. Verifying a system with Serval System specification RISC-V instructions RISC-V verifier Serval Rosette Z3 SMT solver 12

  13. Verifying a system with Serval System specification RISC-V instructions RISC-V verifier Serval Rosette Z3 SMT solver 13

  14. Verifying a system with Serval System specification RISC-V instructions RISC-V verifier Serval Rosette Z3 SMT solver 14

  15. Verifying a system with Serval System specification RISC-V instructions RISC-V verifier Serval Rosette Z3 SMT solver 15

  16. Example: proving refinement for sign 0: sltz a1 a0 1: bnez a1 4 2: sgtz a0 a0 3: ret 4: li a0 -1 (define (sign x) (cond 5: ret [(negative? x) -1] [(positive? x) 1] [(zero? x) 0])) RISC-V verifier Serval 16

  17. Verifier = interpreter + symbolic optimization ✔ 2. Symbolic profiling 1. Write a verifier to find bottleneck as interpreter 3. Apply symbolic optimizations 17

  18. Verifier [1/3]: writing an interpreter (struct cpu (pc regs ...) #:mutable) System RISC-V x86-32 specification instructions instructions (define (interpret c program) (define pc (cpu-pc c)) RISC-V x86-32 (define insn (fetch pc program)) verifier verifier (match insn [('li rd imm) (set-cpu-pc! c (+ 1 pc)) (set-cpu-reg! c rd imm)] [('bnez rs imm) (if (! (= (cpu-reg c rs) 0)) (set-cpu-pc! c imm) (set-cpu-pc! c (+ 1 pc)))] ...)) 18

  19. Verifier [1/3]: writing an interpreter (struct cpu (pc regs ...) #:mutable) System RISC-V x86-32 specification instructions instructions (define (interpret c program) (define pc (cpu-pc c)) RISC-V x86-32 (define insn (fetch pc program)) verifier verifier (match insn [('li rd imm) (set-cpu-pc! c (+ 1 pc)) (set-cpu-reg! c rd imm)] [('bnez rs imm) (if (! (= (cpu-reg c rs) 0)) (set-cpu-pc! c imm) (set-cpu-pc! c (+ 1 pc)))] ...)) 19

  20. Verifier [1/3]: writing an interpreter (struct cpu (pc regs ...) #:mutable) (define (interpret c program) (define pc (cpu-pc c)) (define insn (fetch pc program)) (match insn [('li rd imm) (set-cpu-pc! c (+ 1 pc)) (set-cpu-reg! c rd imm)] [('bnez rs imm) (if (! (= (cpu-reg c rs) 0)) (set-cpu-pc! c imm) (set-cpu-pc! c (+ 1 pc)))] ...)) 20

  21. Verifier [1/3]: writing an interpreter (struct cpu (pc regs ...) #:mutable) (define (interpret c program) (define pc (cpu-pc c)) (define insn (fetch pc program)) (match insn [('li rd imm) (set-cpu-pc! c (+ 1 pc)) (set-cpu-reg! c rd imm)] [('bnez rs imm) (if (! (= (cpu-reg c rs) 0)) (set-cpu-pc! c imm) (set-cpu-pc! c (+ 1 pc)))] ...)) 21

  22. Verifier [1/3]: writing an interpreter (struct cpu (pc regs ...) #:mutable) (define (interpret c program) (define pc (cpu-pc c)) (define insn (fetch pc program)) (match insn • Easy to write [('li rd imm) • Reuse CPU test suite (set-cpu-pc! c (+ 1 pc)) (set-cpu-reg! c rd imm)] [('bnez rs imm) (if (! (= (cpu-reg c rs) 0)) (set-cpu-pc! c imm) (set-cpu-pc! c (+ 1 pc)))] ...)) 22

  23. Verifier [2/3]: identifying bottlenecks in symbolic evaluation 😁 0: sltz a1 a0 1: bnez a1 4 2: sgtz a0 a0 3: ret 4: li a0 -1 (define (sign x) (cond 5: ret [(negative? x) -1] [(positive? x) 1] RISC-V verifier [(zero? x) 0])) Serval 23

  24. Verifier [2/3]: identifying bottlenecks in symbolic evaluation 🤰 0: sltz a1 a0 1: bnez a1 4 2: sgtz a0 a0 3: ret 4: li a0 -1 (define (sign x) (cond 5: ret slow/timeout [(negative? x) -1] [(positive? x) 1] RISC-V verifier [(zero? x) 0])) Serval 24

  25. Verifier [2/3]: identifying bottlenecks in symbolic evaluation 25

  26. Verifier [2/3]: identifying bottlenecks in symbolic evaluation fetch 26

  27. Verifier [2/3]: identifying bottlenecks in symbolic evaluation (struct cpu (pc regs) #:mutable) (define (interpret c program) 0: sltz a1 a0 (define pc (cpu-pc c)) 1: bnez a1 4 (define insn (fetch pc program)) 2: sgtz a0 a0 (match insn [('li rd imm) 3: ret (set-cpu-pc! c (+ 1 pc)) 4: li a0 -1 (set-cpu-reg! c rd imm)] 5: ret [('bnez rs imm) (if (! (= (cpu-reg c rs) 0)) (set-cpu-pc! c imm) (set-cpu-pc! c (+ 1 pc)))] ...)) 27

  28. Merge states to avoid path explosion PC → 0 a0 → X X < 0 ¬(X < 0) 0: sltz a1 a0 a1 → Y 1: bnez a1 4 PC → 1 PC → 1 2: sgtz a0 a0 a0 → X a0 → X 3: ret a1 → 1 a1 → 0 4: li a0 -1 5: ret PC → 1 a0 → X a1 → if(X < 0, 1, 0) 28

  29. Bottleneck: state explosion due to symbolic PC Conditional jump PC → 1 a0 → X 0: sltz a1 a0 a1 → if(X < 0, 1, 0) 1: bnez a1 4 2: sgtz a0 a0 3: ret ... ... 4: li a0 -1 5: ret PC → if(X < 0, 4, 2) a0 → X a1 → if(X < 0, 1, 0) 29

  30. Bottleneck: state explosion due to symbolic PC Conditional jump PC → if(...) a0 → X 0: sltz a1 a0 a1 → if(...) 1: bnez a1 4 2: sgtz a0 a0 3: ret 4: li a0 -1 PC → 0 PC → 1 PC → 2 5: ret PC → 3 PC → 4 PC → 5 30

  31. Verifier [3/3]: Repairing with symbolic optimizations • Symbolic optimization: "peephole" on symbolic state • Fine-tune symbolic evaluation • Use domain knowledge 31

  32. Verifier [3/3]: Repairing with symbolic optimizations (define (interpret c program) - (define pc (cpu-pc c)) (define insn (fetch pc program)) (match insn (define (interpret c program) ...)) + ( serval:split-pc [cpu pc] c (define insn (fetch pc program)) (match insn ...))) • Match on symbolic structure of PC • Evaluate separately using each concrete PC value • Merge states afterwards 32

  33. Verifier [3/3]: Repairing with symbolic optimizations PC → if(X < 0, 4, 2) a0 → X PC → if(X < 0, 4, 2) a1 → if(...) a0 → X a1 → if(...) split-pc PC → 0 PC → 1 PC → 2 PC → 4 PC → 2 PC → 3 PC → 4 PC → 5 33

  34. Verifier [3/3]: Repairing with symbolic optimizations PC → if(X < 0, 4, 2) a0 → X PC → if(X < 0, 4, 2) a1 → if(...) Domain knowledge: a0 → X a1 → if(...) • Split PC to avoid state explosion • Merge other registers to avoid path explosion PC → 0 PC → 1 PC → 2 PC → 4 PC → 2 PC → 3 PC → 4 PC → 5 34

  35. Symbolic optimizations are essential to scaling verification • Symbolic program counter • Symbolic memory address • Symbolic system register • ... and more 35

  36. Verifier summary • Verifier = interpreter + symbolic optimizations • Easy to test verifiers • Systematic way to scale symbolic evaluation • Caveats: • Symbolic profiling cannot identify expensive SMT operations • Repair requires expertise - recent work SymFix (VMCAI'20) 36

  37. Implementation RISC-V x86 ARM LLVM BPF verifier verifier verifier verifier verifier Serval Rosette Z3 SMT solver 37

  38. Experience • Can existing systems be retrofitted for Serval? • Are Serval’s verifiers reusable? 38

  39. Retrofitting previously verified systems • Port CertiKOS (PLDI’16) and Komodo (SOSP’17) to RISC-V • Retrofit to automated verification • Apply the RISC-V verifier to binary image • Prove functional correctness and noninterference • ≈ 4 weeks each 39

Recommend


More recommend