Automated tools for software reliability
This presentation is the property of its rightful owner.
Sponsored Links
1 / 72

Automated Tools for Software Reliability PowerPoint PPT Presentation


  • 58 Views
  • Uploaded on
  • Presentation posted in: General

Automated Tools for Software Reliability. Suhabe Bugrara [email protected] Stanford University. Problem. 80% of development cost on identifying and correcting defects Software errors cost US economy $60 billion annually (0.6% of GDP). Manual Testing.

Download Presentation

Automated Tools for Software Reliability

An Image/Link below is provided (as is) to download presentation

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.


- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -

Presentation Transcript


Automated tools for software reliability

Automated Tools for Software Reliability

Suhabe Bugrara

[email protected]

Stanford University


Problem

Problem

  • 80% of development cost on identifying and correcting defects

  • Software errors cost US economy $60 billion annually (0.6% of GDP)


Manual testing

Manual Testing

  • Traditional approach to quality assurance

  • Expensive

  • Time consuming

  • Not systematic

  • Difficult to quantify effectiveness of test suite

  • Cannot make any guarantees about reliability

  • Insufficient for safety critical systems


Automated tools

Automated Tools

  • Programs to find defects in programs

  • Automated

  • Systematic

  • Easy to quantify effectiveness

  • Provide guarantees about reliability

  • Sometimes expensive (for now…)

  • Sometimes time consuming (for now…)


Program analyzers

Program Analyzers

Complete

Incomplete

Undecidable

Decidable

Sound

  • Reports all errors

  • Reports no false alarms

  • Reports all errors

  • May report false alarms

Decidable

Decidable

Unsound

  • May not report all errors

  • Reports no false alarms

  • May not report all errors

  • May report false alarms


Static driver verifier

Static Driver Verifier

  • Program analyzer for API usage rules

  • Developed by Microsoft Research

  • Applied to device drivers in Windows

  • Sound: reports all possible errors

  • Incomplete: may report false alarms


Sdv overview

SDV: Overview

  • Write API usage rule specification

  • Instrument program with usage checks

  • Abstract program

  • Check abstraction for errors

  • If error found, see if error is false alarm

  • If false alarm, refine abstraction

  • If not false alarm, report error as bug


Api usage rules

API Usage Rules

  • Ex. locks are alternatingly acquired and released


Api usage rules1

API Usage Rules

  • Ex. locks are alternatingly acquired and released

  • Expressed as finite state machine

    • States = {locked, unlocked,error}

    • Transitions = {acquire(), release()}


Api usage rules2

API Usage Rules

  • Ex. locks are alternatingly acquired and released

  • Expressed as finite state machine

    • States = {locked, unlocked,error}

    • Transitions = {acquire(), release()}

acquire();

unlocked

locked

release();

release();

acquire();

error


Automated tools for software reliability

state {

enum { Unlocked=0; Locked=1} state = Unlocked;

}

KeAcquireSpinLock.return {

if (state == Locked)

error();

else

state = Locked;

}

KeReleaseSpinLock.return {

if (!(state == Locked))

error();

else

state = Unlocked;

}


Automated tools for software reliability

enum {Unlocked=0, Locked=1} state = Unlocked

voidKeAcquireSpinLock_return() {

if (state == Locked)

error();

else

state = Locked;

}

voidKeReleaseSpinLock_return() {

if (!(state == Locked))

error();

else

state = Unlocked;

}


Automated tools for software reliability

1: voidexample() {

2: do {

3: KeAcquireSpinLock();

4:

5:nPacketsOld = nPackets;

6:req = devExt->WLHV

7:if (req && req->status) {

8:devExt->WLHV = req->Next

9:KeReleaseSpinLock();

10:

11:irp = req->irp;

12:if (req->status > 0) {

13:irp->IoS.Status = SUCCCESS;

14:irp->IoS.Info = req->Status;

15:} else {

16:irp->IoS.Status = FAIL;

17:irp->IoS.Info = req->Status;

18:}

19:SmartDevFreeBlock(req);

20:IoCompleteRequest(irp);

21:nPackets++;

22:}

23:} while (nPackets!=nPacketsOld);

24:KeReleaseSpinLock();

25:

26: }


Automated tools for software reliability

enum {Unlocked=0, Locked=1} state = Unlocked

voidKeAcquireSpinLock_return() {

if (state == Locked)

error();

else

state = Locked;

}

voidKeReleaseSpinLock_return() {

if (!(state == Locked))

error();

else

state = Unlocked;

}


Automated tools for software reliability

1: voidexample() {

2: do {

3: KeAcquireSpinLock();

4:KeAcquireSpinLock_return();

5:nPacketsOld = nPackets;

6:req = devExt->WLHV

7:if (req && req->status) {

8:devExt->WLHV = req->Next

9:KeReleaseSpinLock();

10:KeReleaseSpinLock_return();

11:irp = req->irp;

12:if (req->status > 0) {

13:irp->IoS.Status = SUCCCESS;

14:irp->IoS.Info = req->Status;

15:} else {

16:irp->IoS.Status = FAIL;

17:irp->IoS.Info = req->Status;

18:}

19:SmartDevFreeBlock(req);

20:IoCompleteRequest(irp);

21:nPackets++;

22:}

23:} while (nPackets!=nPacketsOld);

24:KeReleaseSpinLock();

25:KeReleaseSpinLock_return();

26: }

Program A


Sdv abstraction

SDV: Abstraction

  • Construct abstractionB of original program A

    • Over-approximates reachability

      • If error() is reachable in A,

        then it is also reachable in B

        • This characteristic makes SDV sound

      • If error() is reachable in B,

        then it may not be reachable in A

        • This characteristic makes SDV incomplete

  • Check abstraction B for any errors


Reachable states

Reachable States

Abstraction B

real bug!

error

Original A

Sound: If A has error, then B has error


Reachable states1

Reachable States

false alarm!

Abstraction B

error

Original A

Incomplete: If B has error, then A may not have error


Automated tools for software reliability

bool b1;

b1 = false; Abstract state == Locked withb1

voidKeAcquireSpinLock_return() {

if (b1)

error();

else

b1 = true;

}

voidKeReleaseSpinLock_return() {

if (!(b1))

error();

else

b1 = false;

}


Automated tools for software reliability

1: voidexample() {

2: do {

3: ;

4:KeAcquireSpinLock_return();

5:;

6:;

7:if (SdvMakeChoice()) {

8:;

9:;

10:KeReleaseSpinLock_return();

11:;

12:if (SdvMakeChoice()) {

13:;

14:;

15:} else {

16:;

17:;

18:}

19:;

20:;

21:;

22:}

23:} while (SdvMakeChoice());

24:;

25:KeReleaseSpinLock_return();

26: }

Program B


Automated tools for software reliability

1: voidexample() {

2: do {

3: ;

4:KeAcquireSpinLock_return();

5:;

6:;

7:if (SdvMakeChoice()) {

8:;

9:;

10:KeReleaseSpinLock_return();

11:;

12:if (SdvMakeChoice()) {

13:;

14:;

15:} else {

16:;

17:;

18:}

19:;

20:;

21:;

22:}

23:} while (SdvMakeChoice());

24:;

25:KeReleaseSpinLock_return();

26: }

Error trace

found!


Automated tools for software reliability

1: voidexample() {

2: do {

3: KeAcquireSpinLock();

4:KeAcquireSpinLock_return();

5:nPacketsOld = nPackets;

6:req = devExt->WLHV

7:if (req && req->status) {

8:devExt->WLHV = req->Next

9:KeReleaseSpinLock();

10:KeReleaseSpinLock_return();

11:irp = req->irp;

12:if (req->status > 0) {

13:irp->IoS.Status = SUCCCESS;

14:irp->IoS.Info = req->Status;

15:} else {

16:irp->IoS.Status = FAIL;

17:irp->IoS.Info = req->Status;

18:}

19:SmartDevFreeBlock(req);

20:IoCompleteRequest(irp);

21:nPackets++;

22:}

23:} while (nPackets!=nPacketsOld);

24:KeReleaseSpinLock();

25:KeReleaseSpinLock_return();

26: }

But, no bug in original program!


Automated tools for software reliability

1: voidexample() {

2: do {

3: ;

4:KeAcquireSpinLock_return();

5:b2 = false;

6:;

7:if (SdvMakeChoice()) {

8:;

9:;

10:KeReleaseSpinLock_return();

11:;

12:if (SdvMakeChoice()) {

13:;

14:;

15:} else {

16:;

17:;

18:}

19:;

20:;

21:b2 = !b2 ? true : SdvMakeChoice();

22:}

23:} while (b2);

24:;

25:KeReleaseSpinLock_return();

26: }

ProgramC


Reachable states2

Reachable States

Abstraction B

error

Refined C

Original A

false alarm no longer reported!


Sdv summary

SDV: Summary

  • Write API usage rule specification

  • Instrument program with usage checks

  • Abstract program

  • Check abstraction for errors

  • If error found, see if error is false alarm

  • If false alarm, refine abstraction

  • If not false alarm, report error as bug


Soundness

Soundness

  • Assume memory safety

    • No buffer/integer overflows

    • Safe memory management

    • No null pointer dereferences

  • Oversimplified harness

    • Use stubs to model calls into OS procedures

    • Stubs may not represent all behavior


Research challenges in verification

Research Challenges in Verification

  • Eliminate assumption of memory safety

  • Eliminate false alarms

  • Scale to the entire operating system

  • Verify more complicated properties

    • prove consistency of file system data structures


Program analyzers1

Program Analyzers

Complete

Incomplete

Undecidable

Decidable

Sound

  • Reports all errors

  • Reports no false alarms

  • Reports all errors

  • May report false alarms

Decidable

Decidable

Unsound

  • May not report all errors

  • Reports no false alarms

  • May not report all errors

  • May report false alarms


Automated tools for software reliability

EXE

  • Automatically generate test cases that explore important program paths

  • Developed by Dawson Engler’s group

  • Bug finding tool

  • Unsound: may not report all errors

  • Complete: never reports false alarms


Automated tools for software reliability

intbad_abs (int x) {

if (x < 0)

return –x;

if (x == 12345678)

return –x;

return x;

}


Automated tools for software reliability

intbad_abs (int x) {

if (x < 0)

return –x;

if (x == 12345678)

return –x;

return x;

}


Automated tools for software reliability

intbad_abs (int x) {

if (x < 0)

return –x;

if (x == 12345678)

return –x;

return x;

}

(x >= INT_MIN) && (x <= INT_MAX) && (x < 0) && (ret = -x)

find a solution using an automatic constraint solver…

x = -1


Automated tools for software reliability

intbad_abs (int x) {

if (x < 0)

return –x;

if (x == 12345678)

return –x;

return x;

}

(x >= INT_MIN) && (x <= INT_MAX) && (x >= 0) && (x = 12345678) && (ret = -x)

find a solution using an automatic constraint solver…

x = 12345678


Automated tools for software reliability

intbad_abs (int x) {

if (x < 0)

return –x;

if (x == 12345678)

return –x;

return x;

}

(x >= INT_MIN) && (x <= INT_MAX) && (x >= 0) && (x != 12345678)

&& (ret = x)

find a solution using an automatic constraint solver…

x = 4


Automated tools for software reliability

intbad_abs (int x) {

if (x < 0)

return –x;

if (x == 12345678)

return –x;

return x;

}

EXE automatically generated test cases for each path…

x = -1

x = 12345678

x = 4


Automated tools for software reliability

intbad_abs (int x) {

if (x < 0)

return –x;

if (x == 12345678)

return –x;

return x;

}


Automated tools for software reliability

1: intsymbolic_bad_abs (int x) {

2:add_constraints(x >= INT_MIN, x <= INT_MAX);

3: ret = new symbol;

4:

5:if (fork() == child) {

6:add_constraints(x < 0, ret = -x);

7:return ret;

8://(x >= INT_MIN) && (x <= INT_MAX) && (x < 0) && (ret = -x)

9:} else

10:add_constraints(x >= 0);

11:

12:if (fork() == child) {

13:add_constraints(x = 12345678, ret = -x);

14:return ret;

15://(x >= INT_MIN) && (x <= INT_MAX) && (x >= 0) && (x = 12345678)

16://&& (ret = -x)

17:} else

18:add_constraints(x != 12345678);

19:

20:add_constraints(ret = x);

21:return ret;

22://(x >= INT_MIN) && (x <= INT_MAX) && (x >= 0) && (x != 12345678)

23:&& (ret = x)

24:}


Automated tools for software reliability

1: intmain (void) {

2:unsigned i, t, a[4] = { 1, 3, 5, 2};

3:make_symbolic(&i);

4:

5:if (i >= 4)

6:exit(0);

7:

8:char *p = (char *) a + i * 4;

9:*p = *p – 1;

10:

11:t = a[*p];

12:

13:t = t / a[i];

14:

15:if (t == 2)

16:assert(i == 1);

17:else

18:assert(i == 3);

19: }


Review

Review

  • Why does SDV produce false alarms and EXE doesn’t?

  • Why use SDV, then?


Saturn

Saturn

  • Large-scale program verification

  • Developed by Alex Aiken’s group

  • Sound: reports all errors

  • Incomplete: may report false alarms

  • Gives guarantees of reliability on systems as large as the Linux kernel with over 6.2 million lines of code


Program analyzers2

Program Analyzers

Complete

Incomplete

Undecidable

Decidable

Sound

  • Reports all errors

  • Reports no false alarms

  • Reports all errors

  • May report false alarms

Decidable

Decidable

Unsound

  • May not report all errors

  • Reports no false alarms

  • May not report all errors

  • May report false alarms


Unchecked user pointer dereferences

Unchecked User Pointer Dereferences

  • Security property of operating systems

  • Two types of pointers in operating systems

    • kernel pointer: pointer created by the operating system

    • user pointer: pointer created by a user application and passed to the operating system via an entry point such as a system call

  • Must check that a user pointer points into userspace before dereferencing it


Unchecked user pointer dereferences1

Unchecked User PointerDereferences

1: static ssize_t read_port(…, char * __user buf, …) {

2:unsigned long i = *ppos;

3:char * __user tmp = buf;

4:

5:if (!access_ok(..,buf,...)) //check

6:return -EFAULT;

7:

8: while (count-- > 0 && i < 65536) {

9: if (__put_user(inb(i),tmp) < 0) //deref

10:return -EFAULT;

11:i++;

12:tmp++;

13:}

14:

15:*ppos = i;

16:return tmp-buf;

17: }


Security vulnerability

Security Vulnerability

  • Malicious user could

    • Take control of the operating system

    • Overwrite kernel data structures

    • Read sensitive data out of kernel memory

    • Crash machine by corrupting data


Verifying the security property

Verifying the Security Property

  • Eliminate the need for annotations

  • Eliminate false positives

  • Provide guarantee that no security vulnerabilities of this kind are present


Security verifier

Security Verifier

  • Design a sound and incomplete verifier to prove statically that no unchecked user pointer dereferences exist


Security verifier1

Security Verifier

  • Compute set of facts at each program point

  • States = { user, checked, error}

  • Facts are pairs of locations and states

    • (*v,user) signifies that v is a user pointer

  • Verify that program never in error state


Security verifier2

Security Verifier

  • Pointer is in user state if created by user application

  • Pointer is in checked state if access_ok applied

  • Pointer is in error state if dereferenced when

    • Pointer is in user state, AND

    • Pointer is NOT in checked state


Example

Example

1: int sys_call (int *u, int cmd) {//u is user pointer

2: int x;

3:

4:if (cmd == 1) {

5:if (!access_ok(u)) { //check u

6:return –ERR;

7:}

8:}

9:…

10:if (cmd == 1)

11:x = *u;//dereference u

12:…


One possible approach

One Possible Approach

1: int sys_call (int *u, int cmd) {

2: int x;

3:

4:if (cmd == 1) {

5:if (!access_ok(u)) {

6:return –ERR;

7:}

8:}

9:…

10:if (cmd == 1)

11:x = *u;

12:…

(*u,user)

(*u,user)

(*u,user)

(*u,user)

(*u,checked)

(*u,user) lost precision!

(*u,user)

(*u,error) emit warning!

…, but, procedure does not contain any vulnerabilities!


Path sensitivity

Path Sensitivity

  • Ability to reason about branch correlations

  • Important for reducing false positive rate

  • Programs use substantial amount of branch correlation in practice


Example1

Example

1: int sys_call (int *u, int cmd) {//u is user pointer

2: int x;

3:

4:if (cmd == 1) {

5:if (!access_ok(u)) { //check u

6:return –ERR;

7:}

8:}

9:…

10:if (cmd == 1)

11:x = *u;//dereference u

12:…


Path sensitivity1

Path Sensitivity

1: int sys_call (int *u, int cmd) {//u is user pointer

2: int x;

3:

4:if (cmd == 1) {

5:if (!access_ok(u)) { //check u

6:return –ERR;

7:}

8:}

9:…

10:if (cmd == 1)

11:x = *u;//dereference u

12:…

Valid Path


Path sensitivity2

Path Sensitivity

1: int sys_call (int *u, int cmd) {//u is user pointer

2: int x;

3:

4:if (cmd == 1) {

5:if (!access_ok(u)) { //check u

6:return –ERR;

7:}

8:}

9:…

10:if (cmd == 1)

11:x = *u;//dereference u

12:…

Valid Path


Path sensitivity3

Path Sensitivity

1: int sys_call (int *u, int cmd) {//u is user pointer

2: int x;

3:

4:if (cmd == 1) {

5:if (!access_ok(u)) { //check u

6:return –ERR;

7:}

8:}

9:…

10:if (cmd == 1)

11:x = *u;//dereference u

12:…

Valid Path


Path sensitivity4

Path Sensitivity

1: int sys_call (int *u, int cmd) {//u is user pointer

2: int x;

3:

4:if (cmd == 1) {

5:if (!access_ok(u)) { //check u

6:return –ERR;

7:}

8:}

9:…

10:if (cmd == 1)

11:x = *u;//dereference u

12:…

Invalid Path!


Path sensitive analysis

Path Sensitive Analysis

1: int sys_call (int *u, int cmd) {

2: int x;

3:

4:if (cmd == 1) {

5:if (!access_ok(u)) {

6:return –ERR;

7:}

8:}

9:…

10:if (cmd == 1)

11:x = *u;

12:…

(*u,user)  true

(*u,user)  true

(*u,user)  true

(*u,user)  true

(*u,checked)  cmd == 1

(*u,user)  true

(*u,checked)  cmd == 1

(*u,user)  true

(*u,checked)  cmd == 1

(*u,error)  cmd == 1 && !(cmd == 1) && true

 false


Design of saturn security verifier

Design of Saturn Security Verifier

  • Generate summary of behavior for each procedure with respect to calling context

  • Apply summary of callee at call site in caller

  • Repeatedly generate and apply summaries until a fixed point is reached


Experimental setup

Experimental Setup

  • Implemented verifier for unchecked user pointer dereferences

  • Applied verifier to Linux 2.6.17.1 built for x86 architecture

  • 6.4 million lines of code

  • Analyzed in 6 hours over 50 node cluster


Results

Results

  • 91,543 procedures

  • 154 (.17%) of procedures time out

  • 627 system call parameters

  • 867,544 dereferences

  • 15,452 (1.8%) of dereferences time out


Results1

Results

  • Verified automatically

    • 620 out of 627 system call arguments (99%)

    • 851,914 out of 852,092 dereferences (99.96%)

  • Warnings

    • 7 warnings on system call arguments

    • 278 warnings on dereferences

    • 20 annotations required to verify


Saturn other analyses

Saturn: Other Analyses

  • Null pointer dereferences bug finder

    • Found hundreds of bugs in systems code

    • Isil Dillig, Thomas Dillig, and Alex Aiken. Static Error Detection Using Semantic Inconsistency Inference, PLDI 2007

  • Buffer overflow

  • Safe casting

  • Integer overflow

  • Locking

  • Safe memory management


Other tools

Other Tools

  • BLAST

  • CQual

  • Metal

  • Daikon

  • Vault

  • ESP

  • ESPX

  • MOPS

  • DART

  • CSSV

  • Alloy

  • eXplode

  • Chord

  • TVLA

  • CCured

  • Clouseau

  • STeP

  • Prefix

  • Prefast

  • Failure Oblivious Computing


References

References

  • A. Aiken et al. An Overview of the Saturn Project. PASTE 2007

  • T. Ball et al. Thorough Static Analysis of Device Drivers. EuroSys 2006

  • C. Cadar et al. EXE: Automatically Generating Inputs of Death. CCS 2006

  • C. Cadar et al. Execution Generated Test Cases: How to Make Systems Code Crash Itself. SPIN 2006

  • B. Hackett et al. Modular Checking for Buffer Overflows in the Large. ICSE 2006.

  • J. Yang et al. Automatically generating malicious disks using symbolic execution. IEEE Security and Privacy 2006

  • Software Errors Cost U.S. Economy $59.5 Billion Annually. NIST 2002. http://www.nist.gov/public_affairs/releases/n02-10.htm


  • Login