VigNAT: A Formally Verified NAT Arseniy Zaostrovnykh, Solal Pirelli, Luis Pedrosa, Katerina Argyraki, George Candea
Formally verify a stateful NF with competitive performance and reasonable human effort 2
Formally verify a stateful NF with competitive performance and reasonable human effort 3
Formally verify a stateful NF with competitive performance and reasonable human effort 4
Software Network Functions: Pros and Cons ● Everywhere ○ OpenWRT/NetFilter, Click, RouteBricks ○ Vyatta, OpenVswitch, DPDK ● Flexibility, short time to market, but ... 5
Software Network Functions: Pros and Cons ● Everywhere ○ OpenWRT/NetFilter, Click, RouteBricks ○ Vyatta, OpenVswitch, DPDK ● Flexibility, short time to market, but ... ● Bugs ○ Packets of death, table exhaustion, denial of service ○ Cisco NAT, Juniper NAT, NetFilter, Windows ICS ○ Network outages already cost up to $700B /year 6
Testing: Easy but Incomplete 7
Testing: Easy but Incomplete 8
Formal Verification: Complete but Expensive 9
——?—— Formal Verification: Complete but Expensive 10
Network Verification S D 11
Network Verification S MODEL CODE D 12
Network Verification ≠ NF Code Verification S CODE D 13
How to Verify an NF (Before Vigor)? Bits Algebras Human effort quick slow (infeasible) Machine effort slow (infeasible) quick 14
How to Verify an NF (Before Vigor)? Bits Algebras Human effort quick slow (infeasible) Machine effort slow (infeasible) quick 15
How to Verify an NF (Before Vigor)? Bits Algebras Human effort quick slow (infeasible) Machine effort slow (infeasible) quick 16
How to Verify an NF (Before Vigor)? Bits Algebras Human effort quick slow (infeasible) Machine effort slow (infeasible) quick 17
Theorem Proving Bits Algebras Human effort quick high / infeasible Machine effort slow (infeasible) low 18
Theorem Proving Bits Algebras Human effort quick high / infeasible Machine effort slow (infeasible) low Too complicated [1] Klein, Gerwin, et al. "seL4: Formal verification of an OS kernel." Proceedings of the ACM SIGOPS 22nd symposium on Operating systems principles . ACM, 2009. [2] Chen, Haogang, et al. "Using Crash Hoare logic for certifying the FSCQ file system." Proceedings of the 25th 19 Symposium on Operating Systems Principles . ACM, 2015.
Exhaustive Symbolic Execution (SymbEx) Bits Algebras Human effort low high / infeasible Machine effort high / infeasible low 20
Exhaustive Symbolic Execution (SymbEx) Bits Algebras Human effort low high / infeasible Machine effort high / infeasible low Path Explosion 21 Credit to Jonas Wagner
Vigor Bits Algebras Human effort low high / infeasible Machine effort high / infeasible low 22
Vigor Bits Algebras Human effort low high / infeasible Machine effort high / infeasible low Plus runtime performance 23
Main Idea ● Split the code into two parts ● Verify each part separately ● Stitch the proofs — key challenge 24
Outline ● Problem Statement ● VigNAT Formal Proof ○ General Idea ○ Proof Stitching Example ● RFC Formalization ● Performance 25
Vigor: split code | verify parts | stitch proofs CODE 26
Vigor: split code | verify parts | stitch proofs 27
Vigor: split code | verify parts | stitch proofs 28
Vigor: split code | verify parts | stitch proofs Interface contracts Stateful code Stateless code (data structures) (application logic) 29
Vigor: split code | verify parts | stitch proofs Interface contracts Stateful code (data structures) Theorem Proving 30
Vigor: split code | verify parts | stitch proofs Interface contracts Stateful code Stateless code (data structures) (application logic) 31
Vigor: split code | verify parts | stitch proofs Interface contracts Stateful code Stateless code (data structures) (application logic) Exhaustive Symbolic Execution 32
Vigor: split code | verify parts | stitch proofs Symbolic models Stateless code Approximation (not trusted) (application logic) Exhaustive Symbolic Execution 33
Vigor: split code | verify parts | stitch proofs Symbolic models Stateless code Approximation (not trusted) (application logic) Exhaustive Symbolic Execution traces 34
Vigor: split code | verify parts | stitch proofs Interface contracts traces 35
Vigor: split code | verify parts | stitch proofs Interface contracts traces Vigor Validator 36
Vigor: split code | verify parts | stitch proofs Interface contracts Stateful code Stateless code (data structures) (application logic) Exhaustive Theorem Proving Symbolic Execution traces Vigor Validator 37
Outline ● Problem Statement ● VigNAT Formal Proof ○ General Idea ○ Proof Stitching Example ● RFC Formalization ● Performance 38
Proof Stitching: SymbEx + Theorem Proving ● Stateful code: theorem proving ● Stateless code: exhaustive symbolic execution 1. Use symbolic models — rough interpretations of contracts ● Symbolic models are written in C 2. Replay call traces in a proof checker to check contracts 39
Example NF Code if (!ring_full(r) && receive(&p) && p.port != 9) ring_push_back(r, &p); if (!ring_empty(r) && can_send()) { ring_pop_front(r, &p); send(&p); } 40
Example NF Code if (!ring_full(r) && receive(&p) && p.port != 9) ring_push_back(r, &p); if (!ring_empty(r) && can_send()) { ring_pop_front(r, &p); send(&p); } 41
Example NF Code if (!ring_full(r) && receive(&p) && p.port != 9) ring_push_back(r, &p); if (!ring_empty(r) && can_send()) { ring_pop_front(r, &p); send(&p); } 42
For Each API Function ... Formal Symbolic contract model 43
Example: Formal Contract void ring_pop_front( struct ring* r, struct packet* p); r is not empty and p points to valid memory ———————————— r contains one packet less and p points to a packet and p->port ≠ 9 Formal contract 44
Example: Symbolic Model void ring_pop_front( struct ring* r, struct packet* p) { FILL_SYMBOLIC(p, sizeof(struct packet), "popped_packet"); ASSUME(p->port != 9); } Symbolic model 45
Example NF Code if (!ring_full(r) && receive(&p) && p.port != 9) ring_push_back(r, &p); if (!ring_empty(r) && can_send()) { ring_pop_front(r, &p); send(&p); } 46
Use Symbolic Models if (!ring_full(r) && receive(&p) && p.port != 9) ring_push_back(r, &p); if (!ring_empty(r) && can_send()) { Symbolic model ring_pop_front(r, &p); Symbolic send(&p); model } Symbolic model Symbolic model 47
Execution Trace if (!ring_full(r) && receive(&p) && p.port != 9) ring_push_back(r, &p); if (!ring_empty(r) && can_send()) { ring_pop_front(r, &p); send(&p); } 48
Execution Trace if (!ring_full(r); assume(r1 → true if (!ring_full(r) && receive(&p) && p.port != 9) ring_push_back(r, &p); ring_push_back(r, &p); if (!ring_empty(r); assume(r1 → false if (!ring_empty(r) && can_send()) { ring_pop_front(r, &p): after (p.port ≠ 9) ring_pop_front(r, &p); send(&p); } 49
Over-Approximation Proof r1 = ring_full(r); assume(r1 == true ); ring_push_back(r, &p); r2 = ring_empty(r); assume(r2 == false ); ring_pop_front(r, &p); assert(p.port ≠ 9); 50
Over-Approximation Proof r1 = ring_full(r); assume(r1 == true ); ring_push_back(r, &p); r2 = ring_empty(r); assume(r2 == false ); ring_pop_front(r, &p); assert(p.port ≠ 9); Formal contract 51
Over-Approximation Proof r1 = ring_full(r); assume(r1 == true ); ring_push_back(r, &p); r2 = ring_empty(r); assume(r2 == false ); ring_pop_front(r, &p); assert(p.port ≠ 9); ⊂ Formal Symbolic contract model (covers) 52
Outline ● Problem Statement ● VigNAT Formal Proof ○ General Idea ○ Proof Stitching Example ● RFC Formalization ● Performance 53
Formalization of the NAT RFC ● Everything happens at packet arrival ● Abstract flow table summarizes history of previous interactions ● Packet arrival timestamps — the only source of time 54
Formalization of the NAT RFC flowtable time packet NAT packet flowtable 55
Formalization of the NAT RFC flowtable time packet NAT packet flowtable time packet NAT packet flowtable time packet NAT packet 56
Formalization of the NAT RFC {flowtable before , time, packet in } ➡ {flowtable after , packet out } flowtable time packet NAT packet flowtable 57
Formalization of the NAT RFC flowtable time expire_flows update/create flow packet forward/drop flowtable 58
Outline ● Problem Statement ● VigNAT Formal Proof ○ General Idea ○ Proof Stitching Example ● RFC Formalization ● Performance 59
Recommend
More recommend