scaling symbolic evaluation for automated verification of
play

Scaling symbolic evaluation for automated verification of systems - PowerPoint PPT Presentation

Scaling symbolic evaluation for automated verification of systems code with Serval Luke Nelson , James Bornholt , Ronghui Gu , Andrew Baumann , Emina Torlak , Xi Wang University of Washington, Columbia University,


  1. Scaling symbolic evaluation for automated verification of systems code with Serval Luke Nelson ¹ , James Bornholt ¹ , Ronghui Gu ² , Andrew Baumann ³ , Emina Torlak ¹ , Xi Wang ¹ ¹ University of Washington, ² Columbia University, ³ Microsoft Research 1

  2. Goal : eliminating bugs with formal verification Safety specification (e.g. noninterference) Refinement System implementation Functional specification Process Process Process OS Kernel / security monitor 2

  3. Using interactive / auto-active verification seL4 (SOSP’09) Ironclad Apps (OSDI’14) • Require manual proof annotations/tactics • Expensive: CertiKOS 200k LOC proof FSCQ (SOSP’15) • Multiple person-years CertiKOS (PLDI’16) Komodo (SOSP’17) 3

  4. This talk: automated (push-button) verification Implementation Specification • Trade-off: automation vs expressivity Automated verifier • No proofs on implementation SMT formula • Requires bounded implementation • Restricts spec to first-order logic SMT solver • Examples: Hyperkernel (SOSP’17), Nickel (OSDI’18) ✘ ✔ 4

  5. This talk: automated (push-button) verification Implementation Specification How to write and maintain automated verifiers? Automated verifier How to systematically fix SMT formula verification bottlenecks? SMT solver How to retrofit to existing systems? ✘ ✔ 5

  6. Contributions • Serval: a framework for writing automated verifiers • Lift interpreters into verifiers: RISC-V, BPF, x86-32, LLVM • Symbolic optimization for repairing verification bottlenecks • Experience with Serval • Retrofitted CertiKOS and Komodo for automated verification • Found 18 new bugs in Linux BPF JIT and Keystone • Assumption: no guarantees on concurrency or side channels 6

  7. Verification stack System BPF RISC-V x86-32 LLVM specification instructions instructions instructions instructions RISC-V x86-32 LLVM BPF verifier verifier verifier verifier Serval : Specification library, symbolic optimizations, machine code support Rosette : Symbolic evaluation, symbolic profiling, symbolic reflection SMT solver : Z3 Constraint solving, counterexample generation 7

  8. Verification stack System BPF RISC-V x86-32 LLVM specification instructions instructions instructions instructions RISC-V x86-32 LLVM BPF verifier verifier verifier verifier Serval : Specification library, symbolic optimizations, machine code support Rosette : Symbolic evaluation, symbolic profiling, symbolic reflection SMT solver : Z3 Constraint solving, counterexample generation 8

  9. Verification stack System BPF RISC-V x86-32 LLVM specification instructions instructions instructions instructions RISC-V x86-32 LLVM BPF verifier verifier verifier verifier Serval : Specification library, symbolic optimizations, machine code support Rosette : Symbolic evaluation, symbolic profiling, symbolic reflection SMT solver : Z3 Constraint solving, counterexample generation 9

  10. Verification stack System BPF RISC-V x86-32 LLVM specification instructions instructions instructions instructions RISC-V x86-32 LLVM BPF verifier verifier verifier verifier Serval : Specification library, symbolic optimizations, machine code support Rosette : Symbolic evaluation, symbolic profiling, symbolic reflection SMT solver : Z3 Constraint solving, counterexample generation 10

  11. Verification stack System BPF RISC-V x86-32 LLVM specification instructions instructions instructions instructions RISC-V x86-32 LLVM BPF verifier verifier verifier verifier Serval : Specification library, symbolic optimizations, machine code support Rosette : Symbolic evaluation, symbolic profiling, symbolic reflection SMT solver : Z3 Constraint solving, counterexample generation 11

  12. Verification stack System BPF RISC-V x86-32 LLVM specification instructions instructions instructions instructions RISC-V x86-32 LLVM BPF verifier verifier verifier verifier Serval : Specification library, symbolic optimizations, machine code support Rosette : Symbolic evaluation, symbolic profiling, symbolic reflection SMT solver : Z3 Constraint solving, counterexample generation 12

  13. Verifier = interpreter + symbolic optimization ✔ Write a verifier as Symbolic profiling to interpreter find bottleneck Develop / apply symbolic optimizations 13

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

  15. 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 c 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)))] ...)) 15

  16. 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 c 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)))] ...)) 16

  17. Verifier [1/3]: writing an interpreter (struct cpu (pc regs ...) #:mutable) (define (interpret c program) (define pc (cpu-pc c)) (define insn (fetch c 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)))] ...)) 17

  18. Verifier [1/3]: writing an interpreter (struct cpu (pc regs ...) #:mutable) (define (interpret c program) (define pc (cpu-pc c)) (define insn (fetch c 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)))] ...)) 18

  19. Verifier [1/3]: writing an interpreter (struct cpu (pc regs ...) #:mutable) (define (interpret c program) (define pc (cpu-pc c)) • Natural to write (define insn (fetch c program)) • Easy to audit (match insn • Can reuse CPU test suite [('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 [2/3]: identifying bottlenecks in symbolic evaluation 0: sltz a0 a1 1: bnez a1 4 (define (sign x) 2: sgtz a0 a0 (cond 3: ret [(negative? x) -1] 4: li a0 -1 [(positive? x) 1] [(zero? x) 0])) 5: ret Specification library RISC-V verifier Serval 20

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

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

  23. Bottleneck: state explosion due to symbolic PC (struct cpu (pc regs) #:mutable) (define (interpret c program) 0: sltz a0 a1 (define pc (cpu-pc c)) 1: bnez a1 4 (define insn (fetch c 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)))] ...)) 23

  24. Bottleneck: state explosion due to symbolic PC v 0 : X < 0 B (struct cpu (pc regs) #:mutable) v 1 : ¬ v 0 c 7! cpu(0 , X, Y ) v 2 : ite( v 0 , 1 , 0) i 7! (sltz 1 0 # f) v 3 : ite( v 0 , 4 , 2) v 0 v 1 (define (interpret c program) J I v 4 : ite( v 0 , li , sgtz) 0: sltz a0 a1 c 7! cpu(1 , X, 1) c 7! cpu(1 , X, 0) v 5 : ite( v 0 , # f , 0) (define pc (cpu-pc c)) v 6 : ite( v 0 , � 1 , # f) 1: bnez a1 4 B (define insn (fetch c program)) v 7 : ite( v 0 , 5 , 3) c 7! cpu(1 , X, v 2 ) 2: sgtz a0 a0 v 8 : X > 0 (match insn i 7! (bnez # f 1 4) v 9 : ¬ v 8 [('li rd imm) v 0 v 1 3: ret v 10 : ite( v 8 , 1 , 0) E F v 11 : ite( v 0 , � 1 , v 10 ) (set-cpu-pc! c (+ 1 pc)) c 7! cpu(4 , X, v 2 ) c 7! cpu(2 , X, v 2 ) 4: li a0 -1 (set-cpu-reg! c rd imm)] A 5: ret [('bnez rs imm) c 7! cpu( v 3 , X, v 2 ) C (if (! (= (cpu-reg c rs) 0)) v 1 v 3 = 5 (set-cpu-pc! c imm) v 0 v 3 = 0 v 3 = 1 v 3 = 3 (set-cpu-pc! c (+ 1 pc)))] vector-ref ...)) B c 7! cpu( v 3 , X, v 2 ) i 7! (v 4 0 v 5 v 6 ) v 4 = sltz 24 v 4 = bnez

  25. Bottleneck: state explosion due to symbolic PC • Conditional jump (struct cpu (pc regs) #:mutable) (define (interpret c program) 0: sltz a0 a1 (define pc (cpu-pc c)) 1: bnez a1 4 (define insn (fetch c 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)))] ...)) 25

Recommend


More recommend