79
Permissive Interfaces Tom Henzinger Ranjit Jhala Rupak Majumdar

Permissive Interfaces Tom Henzinger Ranjit Jhala Rupak Majumdar

  • View
    221

  • Download
    0

Embed Size (px)

Citation preview

Permissive Interfaces

Tom Henzinger Ranjit Jhala Rupak Majumdar

A Problem with Program Analysis

Whole Program Analysis not always possible • Availability: Client code missing • Scalability: Whole system too large

Client Client LibraryLibrary

Modular Program Analysis

Modular Program Analysis • Find interface for Library• Use interface to verify client

Client Client LibraryLibrary

Modular Program Analysis

Availability: Interface independent of ClientScalability: Interface small, abstraction of Library

LibraryLibrary

Interface

What is an Interface ?

Interface : Constraints on legal uses of API

• API Calls after which library is in a legal state

LibraryLibraryLegal Error

Interface Library StatesAPI

LibraryLibrary

Legal Error

Example

Legal e=0

Errore!=0

Library StatesInterface API

n0

n1

acq rel n2acq

read

read

rel

Safe: Interface µ Legal Call Sequences

Static e=0;Static a=NULL;Static e=0;Static a=NULL;

acq(){ if(a==NULL){ a:= m_new(); } else e:=1; return;}

acq(){ if(a==NULL){ a:= m_new(); } else e:=1; return;}

read(){ if(a!=NULL){ a:= m_rd(a); } else e:=1; return;}

read(){ if(a!=NULL){ a:= m_rd(a); } else e:=1; return;}

rel(){ a:=NULL; return;}

rel(){ a:=NULL; return;}

n0

n1

acq/x rel/x n2acq/xwrite

readwrite

read

rel/x

n0

n1

acq rel n2acq

read

read

rel

Safety Not Enough!Interface API

Disallows calls to write • Useless for Modular Program Analysis

Static e=0, a=NULL, x=0;Static e=0, a=NULL, x=0;

acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;}

acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;}

read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;}

read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;}

rel(){ a:=NULL; return;}

rel(){ a:=NULL; return;}

acqx(){ if(a==NULL){ a:=m_new(); x:=1; } else e:=1;}

acqx(){ if(a==NULL){ a:=m_new(); x:=1; } else e:=1;}

write(){ if(x!=0){ m_wr(a); } else e:=1; return;}

write(){ if(x!=0){ m_wr(a); } else e:=1; return;}

relx(){ a:=NULL; x:=0;}

relx(){ a:=NULL; x:=0;}

Permissive InterfacesInterface API

n0

n1

acq

n3read

rel/x

Permissive: Legal Call Sequences µ InterfaceModular Analysis: Safe + Permissive Interfaces

Static e=0, a=NULL, x=0;Static e=0, a=NULL, x=0;

acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;}

acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;}

read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;}

read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;}

rel(){ a:=NULL; return;}

rel(){ a:=NULL; return;}

acqx(){ if(a==NULL){ a:=m_new(); x:=1; } else e:=1;}

acqx(){ if(a==NULL){ a:=m_new(); x:=1; } else e:=1;}

write(){ if(x!=0){ m_wr(a); } else e:=1; return;}

write(){ if(x!=0){ m_wr(a); } else e:=1; return;}

relx(){ a:=NULL; x:=0;}

relx(){ a:=NULL; x:=0;}

n2

acqx

relx

writeread

Plan

1. Motivation

2. Characterizing Safe, Permissive Interfaces

3. Computing Safe, Permissive Interfaces

4. Extensions

5. Experiments

Plan

1. Motivation

2. Characterizing Safe, Permissive Interfaces

3. Computing Safe, Permissive Interfaces

4. Extensions

5. Experiments

Typestate Interpretations

n0

n1

acq rel n2acq

read

read

rel

Interface is a Typestate System

- Abstraction of library’s internal state

Typestate Interpretation

- Overapprox possible internal statesa=0

a0 e0

(P2) Every edge: Post(r,f) µ r’

n n’f

r r’

(P1) Initial states in r0

n0 r0

Typestate Interpretations

acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;}

acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;}n0

n1

acq n2acq

a=0

a0 e0

(P2) Every edge: Post(r,f) µ r’

n n’f

r r’

Typestate Interpretations

n0

n1

n2

a=0

a0 e0

rel

read

read

read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;}

read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;}

(P2) Every edge: Post(r,f) µ r’

n n’f

r r’

Typestate Interpretations

n0

n1

n2

a=0

a0 e0

rel

relrel(){ a:=NULL; return;}

rel(){ a:=NULL; return;}

(P2) Every edge: Post(r,f) µ r’

n n’f

r r’

Typestate Interpretations

n0

n1

acq rel n2acq

read

read

rel

Interface is a Typestate System

- Abstraction of library’s internal state

Typestate Interpretation

- Overapprox possible internal statesa=0

a0 e0

(P2) Every edge: Post(r,f) µ r’

n n’f

r r’

(P1) Initial states in r0

n0 r0

Safe Interpretations

Interface is a Typestate System

- Abstraction of library’s internal state

Typestate Interpretation

- Overapprox possible internal states

(P2) Every edge: Post(r,f) µ r’

n n’f

r r’

(P1) Initial states in r0

n0 r0

(P3) Every legal typestate: r µ : Err

n r

n0

n1

acq rel n2acq

read

read

rel

a=0

a0 e0

Safe Interpretations

Theorem: Safe Interpretation implies Safe Interface

(P2) Every edge: Post(r,f) µ r’

n n’f

r r’

(P1) Initial states in r0

n0 r0

(P3) Every legal typestate: r µ : Err

n r

n0

n1

acq rel n2acq

read

read

rel

a=0

a0 e0

Permissive Interpretations

Interface is a Typestate System

- Abstraction of library’s internal state

Typestate Interpretation

- Overapprox possible internal states

(P2) Every edge: Post(r,f) µ r’

n n’f

r r’

(P1) Initial states in r0

n0 r0

(P4) Every illegal typestate: r µ Err

n r

n0

n1

acq rel n2acq

read

read

rel

a=0

a0 e0

Permissive Interpretations

(P2) Every edge: Post(r,f) µ r’

n n’f

r r’

(P1) Initial states in r0

n0 r0

(P4) Every illegal typestate: r µ Err

n r

Theorem: Permissive Interpretation implies Permissive Interface

n0

n1

acq rel n2acq

read

read

rel

a=0

a0 e0

Sanity CheckAPI

n0

n1

acq/x

rel/x n2

acq/xwrite

readwrite

read

rel/x

Q: Why not a permissive interface ?

Static e=0, a=NULL, x=0;Static e=0, a=NULL, x=0;

acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;}

acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;}

read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;}

read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;}

rel(){ a:=NULL; return;}

rel(){ a:=NULL; return;}

acqx(){ if(a==NULL){ a:=m_new(); x:=1; } else e:=1;}

acqx(){ if(a==NULL){ a:=m_new(); x:=1; } else e:=1;}

write(){ if(x!=0){ m_wr(a); } else e:=1; return;}

write(){ if(x!=0){ m_wr(a); } else e:=1; return;}

relx(){ a:=NULL; x:=0;}

relx(){ a:=NULL; x:=0;}

a=0

a0 e0

Sanity Check

n1

n2

write

write(){ if(x!=0){ m_wr(a); } else e:=1; return;}

write(){ if(x!=0){ m_wr(a); } else e:=1; return;}a0

e0

A: (P2) fails! Not an Interpretation

(P2) Every edge: Post(r,f) µ r’

n n’f

r r’

Q: Why not a permissive interface ?

e0 Ç e=0

Sanity Check

n1

n2

write

write(){ if(x!=0){ m_wr(a); } else e:=1; return;}

write(){ if(x!=0){ m_wr(a); } else e:=1; return;}a0

e0 Ç e=0

(P4) Every illegal typestate: r µ Err

n r

A: (P4) fails! Not Permissive Interpretation

Q: Why not a permissive interface ?

Plan

1. Motivation

2. Characterizing Safe, Permissive Interfaces

3. Computing Safe, Permissive Interfaces

4. Extensions

5. Experiments

Computing Interfaces

Problem A: Interface Checking Given Library, candidate interface I, abstraction Check if I is safe, permissive.

Problem B: Interface Reconstruction Given Library, abstraction , Reconstruct a safe, permissive interface I.

Problem C: Interface Inference Given Library, Infer a safe, permissive interface I.

A. Interface Checking

Check Safe, Permissive independently

Problem A: Interface Checking Given Library, candidate interface I, abstraction Check if I is safe, permissive.

A. Interface Checking [Safe]

Interface

n0

acq rel n2

acq

read

read

relStatic e=0;Static a=NULL;Static e=0;Static a=NULL;

acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;}

acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;}

read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;}

read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;}

rel(){ a:=NULL; return;}

rel(){ a:=NULL; return;}

Problem A: Interface Checking Given Library, candidate interface I, abstraction Check if I is safe, permissive.

Library

n1

A. Interface Checking [Safe]

Interface Client

Static e=0;Static a=NULL;Static e=0;Static a=NULL;

acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;}

acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;}

read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;}

read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;}

rel(){ a:=NULL; return;}

rel(){ a:=NULL; return;}

Idea: Analyze Interface Client + Library Verify assertion:

Client in legal location ) Library in legal state

Library

n0

acq rel n2

acq

read

read

rel

n1

Legal e=0

Errore!=0

Library States

n

B. Interface Checking [Permissive]

Interface

n0

acq rel n2

acq

read

read

relStatic e=0;Static a=NULL;Static e=0;Static a=NULL;

acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;}

acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;}

read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;}

read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;}

rel(){ a:=NULL; return;}

rel(){ a:=NULL; return;}

Problem B: Interface Checking Given Library, candidate interface I, abstraction Check if I is safe, permissive.

Library

n1

B. Interface Checking [Permissive]

Interface Client

Static e=0;Static a=NULL;Static e=0;Static a=NULL;

acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;}

acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;}

read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;}

read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;}

rel(){ a:=NULL; return;}

rel(){ a:=NULL; return;}

Idea: Analyze Interface Client + Library Verify assertion:

Client in illegal location ) Library in illegal state

Library

n0

acq rel n2

acq

read

read

rel

n1

Legal e=0

Errore!=0

Library States

n

A. Interface Checking

Safe, Permissive checkable by Assertion Verification!

Problem A: Interface Checking Given Library, candidate interface I, abstraction Check if I is safe, permissive.

Abstract Reachability Graphs

Safe, Permissive checkable by Assertion Verification!

Problem A: Interface Checking Given Library, candidate interface I, abstraction Check if I is safe, permissive.

Abstract Reachability Graphs

Static e=0;Static a=NULL;Static e=0;Static a=NULL;

acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;}

acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;}

read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;}

read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;}

rel(){ a:=NULL; return;}

rel(){ a:=NULL; return;}

n0

acq rel n2

acq

read

read

rel

n1

={a=0,e=0}

a=0,e=0

0

Abstract Reachability Graphs

Static e=0;Static a=NULL;Static e=0;Static a=NULL;

acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;}

acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;}

read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;}

read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;}

rel(){ a:=NULL; return;}

rel(){ a:=NULL; return;}

n0

acq rel n2

acq

read

read

rel

n1

={a=0,e=0}

a=0,e=0

0

1

acq()

: a=0, e=0

Abstract Reachability Graphs

Static e=0;Static a=NULL;Static e=0;Static a=NULL;

acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;}

acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;}

read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;}

read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;}

rel(){ a:=NULL; return;}

rel(){ a:=NULL; return;}

n0

acq rel n2

acq

read

read

rel

n1

={a=0,e=0}

a=0,e=0

0

1

acq()

: a=0, e=0

rel()

a=0,e=0

0

Abstract Reachability Graphs

Static e=0;Static a=NULL;Static e=0;Static a=NULL;

acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;}

acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;}

read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;}

read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;}

rel(){ a:=NULL; return;}

rel(){ a:=NULL; return;}

n0

acq rel n2

acq

read

read

rel

n1

={a=0,e=0}

a=0,e=0

0

1

acq()

: a=0, e=0

rel()

a=0,e=0

0

Abstract Reachability Graphs

Static e=0;Static a=NULL;Static e=0;Static a=NULL;

acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;}

acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;}

read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;}

read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;}

rel(){ a:=NULL; return;}

rel(){ a:=NULL; return;}

n0

acq rel n2

acq

read

read

rel

n1

={a=0,e=0}

a=0,e=0

0

1

acq()

: a=0, e=0

rel()

a=0,e=0

0

rel()

Abstract Reachability Graphs

Static e=0;Static a=NULL;Static e=0;Static a=NULL;

acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;}

acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;}

read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;}

read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;}

rel(){ a:=NULL; return;}

rel(){ a:=NULL; return;}

n0

acq rel n2

acq

read

read

rel

n1

={a=0,e=0}

a=0,e=0

0

1

acq()

: a=0, e=0

rel()

a=0,: e=02 : e=0

read()

Abstract Reachability Graphs

Static e=0;Static a=NULL;Static e=0;Static a=NULL;

acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;}

acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;}

read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;}

read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;}

rel(){ a:=NULL; return;}

rel(){ a:=NULL; return;}

n0

acq rel n2

acq

read

read

rel

n1

={a=0,e=0}

a=0,e=0

0

1

acq()

: a=0, e=0

rel()

2

acq()

2

: e=0

: e=0

read()

Abstract Reachability Graphs

Static e=0;Static a=NULL;Static e=0;Static a=NULL;

acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;}

acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;}

read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;}

read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;}

rel(){ a:=NULL; return;}

rel(){ a:=NULL; return;}

n0

acq rel n2

acq

read

read

rel

n1

={a=0,e=0}

a=0,e=0

0

1

acq()

: a=0, e=0

rel()

2 : e=0

read()

acq()

Abstract Reachability Graphs

Static e=0;Static a=NULL;Static e=0;Static a=NULL;

acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;}

acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;}

read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;}

read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;}

rel(){ a:=NULL; return;}

rel(){ a:=NULL; return;}

n0

acq rel n2

acq

read

read

rel

n1

={a=0,e=0}

a=0,e=0

0

1

acq()

: a=0, e=0

rel()

2 : e=0

1

read()

acq()

read()

: a=0, e=0

Abstract Reachability Graphs

Static e=0;Static a=NULL;Static e=0;Static a=NULL;

acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;}

acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;}

read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;}

read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;}

rel(){ a:=NULL; return;}

rel(){ a:=NULL; return;}

n0

acq rel n2

acq

read

read

rel

n1

={a=0,e=0}

a=0,e=0

0

1

acq()

: a=0, e=0

rel()

2 : e=0

read()

acq()

read()

Abstract Reachability Graphs

Static e=0;Static a=NULL;Static e=0;Static a=NULL;

acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;}

acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;}

read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;}

read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;}

rel(){ a:=NULL; return;}

rel(){ a:=NULL; return;}

n0

acq rel n2

acq

read

read

rel

n1

={a=0,e=0}

a=0,e=0

0

1

acq()

: a=0, e=0

rel()

2 : e=0

read()

acq()

read() rel()

a=0,e=0

0

Abstract Reachability Graphs

Static e=0;Static a=NULL;Static e=0;Static a=NULL;

acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;}

acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;}

read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;}

read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;}

rel(){ a:=NULL; return;}

rel(){ a:=NULL; return;}

n0

acq rel n2

acq

read

read

rel

n1

={a=0,e=0}

a=0,e=0

0

1

acq()

: a=0, e=0

rel()

2 : e=0

read()

acq()

read()

rel()

Abstract Reachability Graphs

Static e=0;Static a=NULL;Static e=0;Static a=NULL;

acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;}

acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;}

read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;}

read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;}

rel(){ a:=NULL; return;}

rel(){ a:=NULL; return;}

n0

acq rel n2

acq

read

read

rel

n1

a=0,e=0

0

1

acq()

: a=0, e=0

rel()

2 : e=0

read()

acq()

read()

rel()

Verify assertion: [Safe]

Client in legal location ) Library in legal staten

Legal e=0

Errore!=0

Library States

Abstract Reachability Graphs

Static e=0;Static a=NULL;Static e=0;Static a=NULL;

acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;}

acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;}

read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;}

read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;}

rel(){ a:=NULL; return;}

rel(){ a:=NULL; return;}

n0

acq rel n2

acq

read

read

rel

n1

a=0,e=0

0

1

acq()

: a=0, e=0

rel()

2 : e=0

read()

acq()

read()

rel()

Verify assertion: [Safe]

Client in legal location ) Library in legal staten

Legal e=0

Errore!=0

Library States

Abstract Reachability Graphs

Static e=0;Static a=NULL;Static e=0;Static a=NULL;

acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;}

acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;}

read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;}

read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;}

rel(){ a:=NULL; return;}

rel(){ a:=NULL; return;}

n0

acq rel n2

acq

read

read

rel

n1

a=0,e=0

0

1

acq()

: a=0, e=0

rel()

2 : e=0

read()

acq()

read()

rel()

Legal e=0

Errore!=0

Library States

Verify assertion: [Permissive]

Client in illegal location ) Library in illegal staten

Abstract Reachability Graphs

Static e=0;Static a=NULL;Static e=0;Static a=NULL;

acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;}

acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;}

read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;}

read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;}

rel(){ a:=NULL; return;}

rel(){ a:=NULL; return;}

n0

acq rel n2

acq

read

read

rel

n1

a=0,e=0

0

1

acq()

: a=0, e=0

rel()

2 : e=0

read()

acq()

read()

rel()

Legal e=0

Errore!=0

Library States

Verify assertion: [Permissive]

Client in illegal location ) Library in illegal staten

A. Interface Checking

n0

acq rel n2

acq

read

read

rel

n1

a=0,e=0

0

1

acq()

: a=0, e=0

rel()

2 : e=0

read()

acq()

read()

rel()Safe, Permissive

Permissive assertion:

Client in illegal location ) Library in illegal state

Safe assertion:

Client in legal location ) Library in legal state

A. Interface Checking

n0

acq rel n2

acq

read

read

rel

n1

a=0,e=0

0

1

acq()

: a=0, e=0

rel()

2 : e=0

read()

acq()

read()

rel()Safe, Permissive

Abstract Reach. Graph , Typestate Interpretation Safe Assertion , Safe Interpretation

Permissive Assertion , Permissive Interpretation

Computing Interfaces

Problem A: Interface Checking Given Library, candidate interface I, abstraction Check if I is safe, permissive.

Problem B: Interface Reconstruction Given Library, abstraction , Reconstruct a safe, permissive interface I.

Problem C: Interface Inference Given Library, Infer a safe, permissive interface I.

Solution: Assertion verification, Abstract Reach. Graph

B. Interface ReconstructionStatic e=0;Static a=NULL;Static e=0;Static a=NULL;

acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;}

acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;}

read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;}

read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;}

rel(){ a:=NULL; return;}

rel(){ a:=NULL; return;}

Problem B: Interface Reconstruction Given Library, abstraction , Reconstruct a safe, permissive interface I.

Library

={a=0,e=0}Abstraction

B. Interface Reconstruction

Maximal Client

Static e=0;Static a=NULL;Static e=0;Static a=NULL;

acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;}

acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;}

read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;}

read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;}

rel(){ a:=NULL; return;}

rel(){ a:=NULL; return;}

Idea: I = Abs Reach Graph of Max Client + Library (using )ARG Vertices w/ legal library state ) legal typestatesARG Vertices w/ illegal library state ) illegal typestates

Library

acq read

rel

={a=0,e=0}Abstraction

ARG of Max+Library

Maximal Client

Static e=0;Static a=NULL;Static e=0;Static a=NULL;

acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;}

acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;}

read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;}

read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;}

rel(){ a:=NULL; return;}

rel(){ a:=NULL; return;}

Library

acq read

rel

={a=0,e=0}

Abstract Reach Graph

a=0,e=0

acq()

: a=0, e=0

rel()

: e=0

read()

acq()

read()

rel()

ARG of Max+Library

Maximal Client

Static e=0;Static a=NULL;Static e=0;Static a=NULL;

acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;}

acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;}

read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;}

read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;}

rel(){ a:=NULL; return;}

rel(){ a:=NULL; return;}

Library

acq read

rel

Abstract Reach Graph

a=0,e=0

acq()

: a=0, e=0

rel()

: e=0

read()

acq()

read()

rel()

ARG Vertices w/ legal library state ) legal typestatesARG Vertices w/ illegal library state ) illegal typestates

ARG of Max+Library

Maximal Client

Static e=0;Static a=NULL;Static e=0;Static a=NULL;

acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;}

acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;}

read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;}

read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;}

rel(){ a:=NULL; return;}

rel(){ a:=NULL; return;}

Library

acq read

rel

Abstract Reach Graph

a=0,e=0

acq()

: a=0, e=0

rel()

: e=0

read()

acq()

read()

rel()

ARG Vertices w/ legal library state ) legal typestatesARG Vertices w/ illegal library state ) illegal typestates

n0

n1

ARG of Max+Library

Maximal Client

Static e=0;Static a=NULL;Static e=0;Static a=NULL;

acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;}

acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;}

read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;}

read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;}

rel(){ a:=NULL; return;}

rel(){ a:=NULL; return;}

Library

acq read

rel

Abstract Reach Graph

a=0,e=0

acq()

: a=0, e=0

rel()

: e=0

read()

acq()

read()

rel()

ARG Vertices w/ legal library state ) legal typestatesARG Vertices w/ illegal library state ) illegal typestates

n0

n1

n2

ARG of Max+Library

Maximal Client

Static e=0;Static a=NULL;Static e=0;Static a=NULL;

acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;}

acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;}

read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;}

read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;}

rel(){ a:=NULL; return;}

rel(){ a:=NULL; return;}

Library

acq read

rel

Interface !

a=0,e=0

: a=0, e=0

: e=0

n0

n1

n2acq rel

read

rel

acq

read

ARG of Max+Library

Interface

a=0,e=0

: a=0, e=0

: e=0Predicate Labels=

Typestate Interpretation

n0

n1

n2acq rel

read

rel

acq

read

Safe, Permissive by construction

Computing Interfaces

Problem A: Interface Checking Given Library, candidate interface I, abstraction Check if I is safe, permissive.

Problem B: Interface Reconstruction Given Library, abstraction , Reconstruct a safe, permissive interface I.

Problem C: Interface Inference Given Library, Infer a safe, permissive interface I.

Solution: Assertion verification, Abstract Reach. Graph

Solution: Interface = ARG (w.r.t. ) of Max Client + Library

Computing Interfaces

Problem A: Interface Checking Given Library, candidate interface I, abstraction Check if I is safe, permissive.

Problem B: Interface Reconstruction Given Library, abstraction , Reconstruct a safe, permissive interface I.

Problem C: Interface Inference Given Library, Infer a safe, permissive interface I.

Solution: Assertion verification, Abstract Reach. Graph

Solution: Interface = ARG (w.r.t. ) of Max Client + Library

C. Interface InferenceRequire sufficiently precise abstraction - Then B (reconstruction) suffices

Imprecise abstraction ) imprecise Abstract Reach Graph- Vertex w/ label containing both legal and illegal lib states

Q: How to deal w/ imprecise vertices ?Idea: Any call sequence into vertex is either legal or illegal• Legal sequence ) Infeasible path to Err• Illegal sequence ) Infeasible path to :ErrRefine abstraction using call sequence into imprecise vertex Repeat until ARG precise, i.e. Interface found

ExampleStatic e=0, a=NULL, x=0;Static e=0, a=NULL, x=0;

acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;}

acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;}

read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;}

read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;}

rel(){ a:=NULL; return;}

rel(){ a:=NULL; return;}

acqx(){ if(a==NULL){ a:=m_new(); x:=1; } else e:=1;}

acqx(){ if(a==NULL){ a:=m_new(); x:=1; } else e:=1;}

write(){ if(x!=0){ m_wr(a); } else e:=1; return;}

write(){ if(x!=0){ m_wr(a); } else e:=1; return;}relx(){ a:=NULL; x:=0;}

relx(){ a:=NULL; x:=0;}

={e=0}

acq/x

write

rel/x

read

Abstract Reach Graph

e=0acq/x()

e=0 Ç : e=0

rel/x()

*

read()write()

ExampleStatic e=0, a=NULL, x=0;Static e=0, a=NULL, x=0;

acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;}

acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;}

read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;}

read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;}

rel(){ a:=NULL; return;}

rel(){ a:=NULL; return;}

acqx(){ if(a==NULL){ a:=m_new(); x:=1; } else e:=1;}

acqx(){ if(a==NULL){ a:=m_new(); x:=1; } else e:=1;}

write(){ if(x!=0){ m_wr(a); } else e:=1; return;}

write(){ if(x!=0){ m_wr(a); } else e:=1; return;}relx(){ a:=NULL; x:=0;}

relx(){ a:=NULL; x:=0;}

acq/x

write

rel/x

read

Imprecise !

read()

e=0 Ç : e=0

Call read() is illegal ) Paths to e=0 infeasible

New predicate a=0• New ARG prohibits immediate call to read

ExampleStatic e=0, a=NULL, x=0;Static e=0, a=NULL, x=0;

acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;}

acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;}

read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;}

read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;}

rel(){ a:=NULL; return;}

rel(){ a:=NULL; return;}

acqx(){ if(a==NULL){ a:=m_new(); x:=1; } else e:=1;}

acqx(){ if(a==NULL){ a:=m_new(); x:=1; } else e:=1;}

write(){ if(x!=0){ m_wr(a); } else e:=1; return;}

write(){ if(x!=0){ m_wr(a); } else e:=1; return;}relx(){ a:=NULL; x:=0;}

relx(){ a:=NULL; x:=0;}

={e=0,a=0}

acq/x

write

rel/x

read

Abstract Reach Graph

rel/x()

a=0,e=0

acq/x

: a=0, e=0

: e=0

read()

rel/x acq

/x

write(): e=0 Ç e=0

ExampleStatic e=0, a=NULL, x=0;Static e=0, a=NULL, x=0;

acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;}

acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;}

read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;}

read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;}

rel(){ a:=NULL; return;}

rel(){ a:=NULL; return;}

acqx(){ if(a==NULL){ a:=m_new(); x:=1; } else e:=1;}

acqx(){ if(a==NULL){ a:=m_new(); x:=1; } else e:=1;}

write(){ if(x!=0){ m_wr(a); } else e:=1; return;}

write(){ if(x!=0){ m_wr(a); } else e:=1; return;}relx(){ a:=NULL; x:=0;}

relx(){ a:=NULL; x:=0;}

acq/x

write

rel/x

read

acqx()

write(): e=0 Ç e=0

Sequence acqx();write() is legal ) Paths to e!=0 infeasible

New predicate x=0• New ARG allows sequence acqx ;write

ExampleStatic e=0, a=NULL, x=0;Static e=0, a=NULL, x=0;

acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;}

acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;}

read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;}

read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;}

rel(){ a:=NULL; return;}

rel(){ a:=NULL; return;}

acqx(){ if(a==NULL){ a:=m_new(); x:=1; } else e:=1;}

acqx(){ if(a==NULL){ a:=m_new(); x:=1; } else e:=1;}

write(){ if(x!=0){ m_wr(a); } else e:=1; return;}

write(){ if(x!=0){ m_wr(a); } else e:=1; return;}relx(){ a:=NULL; x:=0;}

relx(){ a:=NULL; x:=0;}

acq/x

write

rel/x

read

Safe, Permissive Interface

rel/x()

a=0,e=0,x=0acq

: e=0read()

rel/x

acqx

write()

rel/x

read()

: a=0 , e=0

x=0

: a=0, e=0, x=0

ExampleStatic e=0, a=NULL, x=0;Static e=0, a=NULL, x=0;

acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;}

acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;}

read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;}

read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;}

rel(){ a:=NULL; return;}

rel(){ a:=NULL; return;}

acqx(){ if(a==NULL){ a:=m_new(); x:=1; } else e:=1;}

acqx(){ if(a==NULL){ a:=m_new(); x:=1; } else e:=1;}

write(){ if(x!=0){ m_wr(a); } else e:=1; return;}

write(){ if(x!=0){ m_wr(a); } else e:=1; return;}relx(){ a:=NULL; x:=0;}

relx(){ a:=NULL; x:=0;}

Safe, Permissive Interface

n0

n1

acq

n3read

rel/x

n2

acqx

relx

writeread

: a=0 , e=0

x=0

rel/x()

a=0,e=0,x=0acq

: a=0, e=0, x=0

: e=0read()

rel/x

acqx

write()

rel/x

read()

Computing Interfaces

Problem A: Interface Checking Given Library, candidate interface I, abstraction Check if I is safe, permissive.

Problem B: Interface Reconstruction Given Library, abstraction , Reconstruct a safe, permissive interface I.

Problem C: Interface Inference Given Library, Infer a safe, permissive interface I.

Solution: Assertion verification, Abstract Reach. Graph

Solution: Interface = ARG (w.r.t. ) of Max Client + Library

Solution: Refine abstraction using imprecise ARG vertices

Two Requirements, Two Abstractions

Safe, Permissive: Orthogonal– Different abstractions suffice to prove each

= safe [ permissive– safe : calls allowed µ legal calls – permissive : calls disallowed µ illegal calls

1. Build largest safe Interface I ,using safe Build ARG, imprecise vertices illegal

2. Check I is permissive, using permissive Fails: possibly legal, prohibited sequence to imprecise

3. If sequence illegal then Refine permissive

legal then Refine safe

Safety Verification vs Interface Construction

1. Error not reachable

2. Show always legal Find one illegal

sequence

3. Refine: Infeasible path to Error

5. Refine: Fewer behaviors

1. Error reachable

2. Find all legal sequences Find all illegal sequences

3. Refine:Infeasible path to Error

(Safe) OR

Infeasible path to Legal (Perm)

5. Refine: More behaviors

Plan

1. Motivation

2. Characterizing Safe, Permissive Interfaces

3. Computing Safe, Permissive Interfaces

4. Extensions

5. Experiments

Extensions: OutputsOutputs allow non-determinism in library

n0

n1

acq,1 rel n2acq,*

read

read

relacq,0

Static e=0;Static a=NULL;Static e=0;Static a=NULL;

acq(){ if (...) return 0; else { if(a==NULL){ a:=m_new(); } else e:=1; return 1;}

acq(){ if (...) return 0; else { if(a==NULL){ a:=m_new(); } else e:=1; return 1;}

read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;}

read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;}rel(){ a:=NULL; return;}

rel(){ a:=NULL; return;}

LibrarySafe, Permissive Interface

ExtensionsHeirarchy: Library built using of sub-libraries• Construct interface using sub-interfaces

Decomposition:Complex illegal States give large Interface• Partition: small interface per partition

Multiple Correlated Libraries:• Interface = Typestate Hypergraph

Plan

1. Motivation

2. Characterizing Safe, Permissive Interfaces

3. Computing Safe, Permissive Interfaces

4. Extensions

5. Experiments

Experiments• Implemented inside BLAST• Find interfaces for Java classes (JDK 1.4)

– Input: Class, Error states (Exception raised)– Tool Automatically finds predicates, interfaces

• Classes- Signature, ServerTableEntry, ListItr, Socket

– Private state variables determine interface– Partition methods by which variables they affect

• Socket: 6 Predicates, <30s connect ! getInputStream ! shutDownInput ! Close

To sum up…• Modular PA requires Safe,Permissive Interfaces

– Safe : I µ legal sequences– Perm: legal sequences µ I

• Interface = Typestate Graph– Safe, Permissive via Typestate Interpretation

• Compute Interface via Abs. Reach. Graph– Issue: Permissive “lower bound” requirement– Solution: : I µ illegal sequences

• Implementation: – Safe, Permissive Interfaces for Java classes– Automatic synthesis of Typestate Systems

Related Work• Whaley-Lam [ISSTA 02]

Use data-flow analysis, Error condition via exceptions Bar call to b if a modifies a variable guarding exn branchNot permissive

• Alur et. al. [POPL 05]Use machine learning to find set of legal sequences afterManually supplied finite abstractionNot permissive

• Fahndrich-Deline [ECOOP 04] Typestate interpretation

• Counterexample-Guided Refinement …

www.eecs.berkeley.edu/~blast/www.eecs.berkeley.edu/~blast/

Thank youThank you