Lecture 01 - Introduction SOFTWARE VERIFICATION AND ABSTRACT INTERPRETATION Orna Grumberg and EranYahav Slides based on the PPA book by Nielson, Nielon and Hankin, on some slides from Mooly Sagiv, some slides from Patrick Cousot and on lecture notes by Xavier Rival 1
Goal Understand software verification with abstract interpretation What will help us lecture summaries 3-5 homework assignments Small lightweight project Will also help Taking a deep breath Focusing on material and not on your grade 2
Schedule Tue (March 2) 12:30-14:30 Thu (March 4) 10:30-12:30 Tue (March 9) 12:30-14:30 Thu (March 11) 10:30-12:30 Eran Sun (March 14) 16:30-18:30 Tue (March 16) 12:30-14:30 Tue (March 23) 12:30-14:30 Guest lecture by Dr. Noam Rinetzky Passover break Every Tuesday 12:30-14:30 – Orna 3
Why Study Software Verification? More critical software More complicated software Bigger software Security and privacy risks Lightweight verification is economically justified 4
Why Study Software Verification? 5
Slope of Enlightenment Lower expectations for automation Lower expectations of properties to be verified Lower expectations for user specifications Weaker guarantees Bounded “verification” Smart testing … 6
December 31, 2008 7
Zune Bug 1 while (days > 365) { 2 if (IsLeapYear(year)) { 3 if (days > 366) { 4 days -= 366; 5 year += 1; 6 } 7 } else { 8 days -= 365; 9 year += 1; 10 } 11 } 8
Zune Bug 1 while ( 366 > 365) { 2 if (IsLeapYear( 2008 )) { 3 if ( 366 > 366 ) { 4 days -= 366; 5 year += 1; 6 } 7 } else { 8 days -= 365; 9 year += 1; 10 } 11 } Suggested solution: wait for tomorrow 9
February 25, 1991 10
Patriot Bug - Rounding Error Time measured in 1/10 seconds Binary expansion of 1/10: 0.0001100110011001100110011001100.... 24-bit register 0.00011001100110011001100 error of 0.0000000000000000000000011001100... binary, or ~0.000000095 decimal After 100 hours of operation error is 0.000000095×100×3600×10=0.34 A Scud travels at about 1,676 meters per second, and so travels more than half a kilometer in this time Suggested solution: reboot every 10 hours 11
I just want to say LOVE YOU SAN!! (W32.Blaster.Worm) August 13, 2003 12
Windows Exploit(s) Buffer Overflow Memory addresses void foo (char *x) { char buf[2]; … strcpy(buf, x); Previous frame br } Return address da int main (int argc, char *argv[]) { foo(argv[1]); Saved FP ca } char* x ra buf[2] ab ./a.out abracadabra Segmentation fault Stack grows this way (YMMV) 13
Resource Leaks OS class ListView extends ... { Resources private Image imgView = null; // ... protected void handleResize(boolean bForce) { imgView // ... if (imgView == null || bForce) { imgView = new Image(listCanvas.getDisplay(), clientArea); lastBounds = new Rectangle(0, 0, 0, 0); bNeedsRefresh = true; } else { // ... OS Resources } // ... } } (real code from Azureus P2P client) 14
(In)correct Usage of APIs Application Trend: Increasing number of libraries and APIs – Non-trivial restrictions on permitted sequences of operations Typestate: Temporal safety properties – What sequence of operations are permitted on an object? – Encoded as DFA e.g. “Don’t use a Socket unless it is connected” close() getInputStream() getOutputStream() connect() close() init connected closed getInputStream() err getOutputStream() getInputStream() getOutputStream() * 15
Challenges class SocketHolder { Socket s; } Socket makeSocket() { return new Socket(); // A } open(Socket l) { l.connect(); } talk(Socket s) { s.getOutputStream ()).write(“hello”); } main() { Set<SocketHolder> set = new HashSet<SocketHolder>(); while(…) { SocketHolder h = new SocketHolder(); h.s = makeSocket(); set.add(h) } for (Iterator<SocketHolder> it = set.iterator (); …) { Socket g = it.next().s; I’m skeptical open(g); talk(g); } } 16
Testing is Not Enough Observe some program behaviors What can you say about other behaviors? Concurrency makes things worse Smart testing can be useful requires the techniques that we will see in the course 17
Static Analysis Reason statically (at compile time) about the possible runtime behaviors of a program “The algorithmic discovery of properties of a program by inspection of its source text 1 ” -- Manna, Pnueli 1 Does not have to literally be the source text, just means w/o running it 18
Static Analysis x = ? if (x > 0) { y = 42; } else { y = 73; foo(); } assert (y == 42); Bad news: problem is generally undecidable 19
Static Analysis Central idea: use approximation Exact set of Over configurations/ Approximation behaviors Under Approximation universe 20
Over Approximation x = ? if (x > 0) { y = 42; } else { y = 73; foo(); } assert (y == 42); Over approximation: assertion may be violated 21
Precision main(…) { printf (“assertion may be vioalted\ n”); } Lose precision only when required Understand where precision is lost 22
Static Analysis Formalize software behavior in a mathematical model (semantics) Prove properties of the mathematical model Automatically, typically with approximation of the formal semantics Develop theory and tools for program correctness and robustness 23
Static Analysis Spans a wide range from type checking to full verification General safety specifications Security properties (e.g., information flow) Concurrency correctness conditions (e.g., progress, linearizability) Correct use of libraries (e.g., typestate) Under-approximations useful for bug-finding, test- case generation,… 24
Static Analysis: Techniques Dataflow analysis Constraint-based analysis Type and effect systems … Abstract Interpretation 25
Verification Challenge I main(int i) { int x=3,y=1; do { y = y + 1; Determine what } while(--i > 0) states can arise assert 0 < x + y during any execution } Challenge: set of states is unbounded 26
Abstract Interpretation Recipe main(int i) { int x=3,y=1; 1) Abstraction 2) Transformers do { y = y + 1; 3) Exploration Determine what } while(--i > 0) states can arise assert 0 < x + y during any execution } Challenge: set of states is unbounded Solution: compute a bounded representation of (a superset) of program states 27
1) Abstraction concrete state main(int i) { : Var Z int x=3,y=1; abstract state do { y = y + 1; # : Var {+, 0, -, ?} } while(--i > 0) assert 0 < x + y x y i } 7 3 1 x y i + + + x y i 6 3 2 … 28
2) Transformers concrete transformer main(int i) { int x=3,y=1; x y i x y i y = y + 1 0 0 3 1 3 2 do { y = y + 1; abstract transformer } while(--i > 0) x y i x y i y = y + 1 assert 0 < x + y 0 0 + + + + } 0 0 + - + ? 0 0 0 + + + 0 0 + ? + ? 29
3) Exploration x y i x y i main(int i) { ? ? ? int x=3,y=1; ? + + do { y = y + 1; ? + + + + ? ? + + } while(--i > 0) ? ? ? + + + + + + assert 0 < x + y ? ? + + + + ? + + } 30
Incompleteness x y i x y i main(int i) { ? ? ? int x=3,y=1; + + ? do { y = y - 2; ? ? + ? + ? y = y + 3; ? ? + ? + ? } while(--i > 0) assert 0 < x + y ? ? + ? + ? } 31
Verification Challenge II: Stack init void init (int i) { Node* x = null; n n n t t t emp do { x x x Node t = n n n t t t t malloc (…) x x x t->n = x; n n n n n n t t t t x x x x = t; n n n n n n t t t t } while(--i>0) x x x x Top = x; n n n t assert(acyclic(Top)) top } x 32
Following the Recipe (In a Nutshell) 1) Abstraction n n n t t n x x Concrete state Abstract state 2) Transformers t->n = x n n t t n n x x 33
3) Exploration void init (int i) { Node* x = null; n n t t t emp do { x x x n Node t = n n t t t t malloc (…) n x x x t->n = x; n n n n t t t t n x x x x = t; n n n n n t t t t t } while(--i>0) x x n x x n x Top = x; n n n t t t t assert(acyclic(Top)) n n x x Top x x Top Top Top } 34
Challenge III proc MC(n:int) returns (r:int) var t1:int, t2:int; begin if (n>100) then r = n-10; else t1 = n + 11; t2 = MC(t1); r = MC(t2); endif; end var a:int, b:int; begin b = MC(a); end What is the result of this program? 35
Recommend
More recommend