 
              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