policy enforcement and refinement

32
Kestrel Policy Enforcement and Refinement Douglas R. Smith Kestrel Institute Palo Alto, California

Upload: gareth-sheppard

Post on 02-Jan-2016

27 views

Category:

Documents


1 download

DESCRIPTION

Policy Enforcement and Refinement. Douglas R. Smith Kestrel Institute Palo Alto, California. Issue: How to Handle Nonfunctional and Cross-Cutting Concerns wrt Composition and Refinement?. A concern is cross-cutting if its manifestation cuts across the - PowerPoint PPT Presentation

TRANSCRIPT

Kestrel

Policy Enforcementand

Refinement

Douglas R. SmithKestrel Institute

Palo Alto, California

Kestrel

Issue: How to Handle Nonfunctional and Cross-Cutting Concerns wrt

Composition and Refinement?

A concern is cross-cutting if its manifestation cuts across the

dominant hierarchical structure of a program/system.

Examples

• Log all errors that arise during system execution

• Enforce a system-wide error-handling policy

• Disallow unauthorized data accesses

• Enforce timing and resource constraints on a system design

Kestrel

A Generative Approach to

Aspect-Oriented Programming

hypothesis: aspects are invariants to maintain

Kestrel

Crosscutting in AspectJ

aspect ObserverUpdating { pointcut moves(): calls(void Line.setP1(Point)) || calls(void Line.setP2(Point)) || calls(void Point.setX(int)) || calls(void Point.setY(int)) || calls(void FigureElement.incrXY());

after(): moves() { Display.update(); }}

Point

getX()getY()setX(int)setY(int)incrXY()

Line

getP1()getP2()setP1(Point)setP2(Point)incrXY()

Display *

2

*

crosscutting(one form of it)

FigureElement

incrXY()

Kestrel

Issues with current approaches toAspect-Oriented Programming

• What is the intention of an aspect?

• When is an aspect correct?

• Is the pointcut complete?

• What if the advice needs to cater for various contexts?

• Do two aspects conflict? How do we treat them?

• What if an aspect is not a pointwise action, but a behavior?

Kestrel

Maintain an Error Log

Policy: Maintain an error log in a system

Kestrel

Expressing System Constraints

Many systems constraints refer to

• history (events, actions, state,…)

• dynamic context (i.e. the call-stack)

• environment behavior

• substrate properties (e.g. instruction timing, latence, …)

Kestrel

Virtual Variables in State

S0

act0 S1act1 S3 •••S2

act2hist := S0, act0 hist := hist ::S1, act1 hist := hist ::S2, act2

key idea: extend state with a virtual history variable

Virtual variables • exist for purposes of specification• sliced away prior to code generation

Kestrel

Maintain an Error Log

Policy: Maintain an error log in a system

Assume: errlog = filter(error?, actions(hist)) Achieve: errlog´ = filter(error?, actions(hist´))

spec satisfied by: errlog := errlog :: erract

Invariant: errlog = filter(error?, actions(hist))

Disruptive Actions: error?(act)

Spec for Maintenance Code : for each error action erract,

= filter(error?, actions(hist :: S, erract)) = filter(error?, actions(hist) :: erract)

= filter(error?, actions(hist)) :: erract = errlog :: erract

Kestrel

Maintaining an Error Log

S0

act0 S1hist := S0, act0

error1 S3 •••hist := hist ::S1, act1

S2act2

hist := hist ::S2, act2errlog := errlog errlog := errlog::error1 errlog := errlog

Kestrel

General Case

Invariant: I(x)

Disruptive Actions: any action that changes x or an alias

Spec for Maintenance Code : for each such action act with specification

Assume: P(x) Achieve: Q(x, x´)

generate and satisfy new specificationAssume: P(x) I(x) Achieve: Q(x, x´) I(x´)

spec typically satisfied by code of the form: act || update

Kestrel

Summary

• What is the intention of the aspect? expressed by an invariant

• Is the aspect code correct? yes, by construction

• Is the pointcut complete? static analysis finds all actions that disrupt the invariant

• Is the advice efficient in all contexts? specialized code generated for each context

• What if several aspects apply at a program point? attempt to satisfy the joint specification

• What if an aspect is not a pointwise action, but a behavior?enforcement of policy automata

Kestrel

Enforce a Security Policy

Policy: No send actions allowed after file f is read

aA B C D E F

read(f ) send(m)

read(f )One Two

send(*)policy automaton:

Build simulation map, then generate new code for corresponding actions

Inconsistent joint action spec: send(*) send(m) satisfied by abort action

Kestrel

Error-Handling Policiesand their Enforcement

Douglas R. Smith

Klaus Havelund

Kestrel Technology

Palo Alto, California

www.kestreltechnology.com

Kestrel

NonRobust Java Program

class AddNumbersFromFile {

static void doIt(String fileName) throws IOException { DataInputStream source = null; if (fileName != null) source = new DataInputStream(new FileInputStream(fileName)); int count = source.readInt(); int sum = addEm(source,count); System.out.println("Sum is " + sum); }

static int addEm(DataInputStream s, int c) throws IOException { int sum = 0; for (int i = 0; i < c; i++) sum += s.readInt(); if (s.available() == 0) s.close(); return sum; }}

Kestrel

Generic File Management Policy

Open Stopopen close

use

FileNotFoundException / handler1

IOException / handler2

use

handler3

Start

Error

Kestrel

Generic/Library Policy for DataInputStream’s

policy DataInputStreamPolicy { string filename; DataInputStream in;

Start: { DataInputStream(FileInputStream(filename)) returns in } -> Open

Start: { in.read*() } -> Error replace {throw new Error("Attempt to read from an unopen File"); }

Start: { in.available() } -> Start replace {throw new Error("Attempt to invoke available on an unopen File");}

Start: { in.close() } -> Start replace {print("Attempt to close an unopen File"); }

policy instance variables

Kestrel

Library Policy (continued)

Open: { in.read*() } -> Open catch (EOFException e) {throw new Error("EOF: insufficient data in file " + filename); } catch (IOException e) {throw new Error("Cannot read from File " + filename); } Open: { in.available() } -> Open catch (IOException e) {throw new Error("Unable to determine whether file " + filename + " contains more data"); } Open: { in.close() } -> Closed precondition {in.available() == 0} {System.out.println("Closed file " + filename + " when it contained extra data"); } Open : { exit } -> Closed preaction { System.out.println("Performing a missing close on file " + filename); in.close();

Kestrel

Example Policy (continued)

Closed: { in.read*() } -> Closed replace {throw new Error ("File " + filename + "already closed"); } Closed: { in.available() } -> Closed replace {throw new Error ("Attempt to invoke available on a closed file: " + filename); } Closed: { in.close() } -> Closed replace {throw new Error ("File " + filename + "already closed"); }

}

Kestrel

Application-Specific subPolicy for DataInputStreams

policy AddNumbersPolicy extends DataInputStreamPolicy {

Open0: { count = in.read*() } -> Open1 postcondition (0 <= count && count <= 1000) {System.out.println("count received an illegal value: " + Integer.toString(count) + "\nsetting count to 0"); count = 0;} catch (EOFException e) {throw new Error("File " + in.filename + " contains no data!"); } Open1: { in.read*() } -> Open1 }

Kestrel

Policy Simulation on the Example ProgramDoIt entry

fileName != null

Fsource = new DataInputStreamPolicy(fileName)

T

{Start}

{Start}{Open}

{Start,Open}

count = source.readInteger();

{Open}

call addEm(source,count);

{Open Closed, Open Open }

sum = result

{Open,Closed}

System.out.println("Sum is " + sum)

{Open,Closed}

exit

addEm entry

{Open}

sum = 0; i= 0;

i < c

sum += source.readInteger();i++;

T

s.available()==0

F

Fs.close();

T

{Open}

{Closed}

{Open, Closed}

{Open}

{Open}

{Open}

{Open}

{Open}

exit

return sum

{Open, Closed}

ambiguousanalysis

Kestrel

Program Transformation to Reduce Policy Ambiguity

if ( fileName != null ) source = new DataInputStream(new FileInputStream(fileName)); count = source.readInt();

if ( fileName != null ){ source = new DataInputStream(new FileInputStream(fileName)); count = source.readInt(); } else { count = source.readInt(); }

distribute if-then-else over semicolon

if ( fileName == null ) throw new Error("Attempt to read from an unopen File"); source = new DataInputStream(new FileInputStream(fileName)); count = source.readInt();

apply the policy and simplify

hasambiguous

analysis

hasunambiguous

analysis!

unambiguousanalysis,

clear code

Kestrel

Revised Java Program with Unambiguous Analysis

class AddNumbersFromFile {

static void doIt(String fileName) throws IOException { DataInputStream source = null; if ( fileName == null ) {throw new Error("Attempt to read from an unopen File");} source = new DataInputStream(new FileInputStream(fileName)); count = source.readInt(); int sum = addEm(source,count); System.out.println("Sum is " + sum); }

static int addEm(DataInputStream s, int c) throws IOException { int sum = 0; for (int i = 0; i < c; i++) sum += s.readInt();// if (s.available()==0) s.close(); return sum; }}

Kestrel

Policy-Specific Tracking Code (unambiguous case)

public class DataInputStreamForAddNumbers1 extends DataInputStream { public String filename;

public DataInputStreamForAddNumbers1(String filename) throws FileNotFoundException { super(new FileInputStream(filename)); // field in stores the file handle this.filename = filename; }}

HandlErr would generate an extension of the DataInputStream classthat records the policy instance bindings for the in error-handlers.

Kestrel

Revised Java Program with Enforced Policyclass RobustlyAddNumbersFromFile1 {

static void doIt(String fileName) throws IOException{ DataInputStreamForAddNumbers1 source = null; if ( fileName==null ){ throw new Error("Attempt to read from an unopen File"); } try { source = new DataInputStreamForAddNumbers1(fileName); } catch (FileNotFoundException e) { throw new Error("File " + fileName + " cannot be found"); } int count = 0; try { count = source.readInt(); } catch(EOFException e){ source.close(); throw new Error("File " + source.filename + " contains no data!"); } catch(IOException e){ source.close(); throw new Error("Bad data in file" + source.filename); } …

Kestrel

Policy Simulation on the Example ProgramDoIt entry

fileName != null

Fsource = new DataInputStreamPolicy(fileName)

T

{Start}

{Start}{Open}

{Start,Open}

count = source.readInteger();

{Open}

call addEm(source,count);

{Open Closed, Open Open }

sum = result

{Open,Closed}

System.out.println("Sum is " + sum)

{Open,Closed}

exit

addEm entry

{Open}

sum = 0; i= 0;

i < c

sum += source.readInteger();i++;

T

s.available()==0

F

Fs.close();

T

{Open}

{Closed}

{Open, Closed}

{Open}

{Open}

{Open}

{Open}

{Open}

exit

return sum

{Open, Closed}

ambiguousanalysis

Kestrel

Ambiguous Analysis

If the analysis remains ambiguous,then some form of runtime tracking of state is required, and runtime enforcement decisions.

Technique: use subclassing to track state

Kestrel

Generic File Management Policy

Open Stopopen close

use

FileNotFoundException / handler1

IOException / handler2

use

handler3

Start

Error

Kestrel

Runtime State Tracking

public class DataInputStreamForAddNumbers extends DataInputStream { public static final int Start = 1; public static final int Open = 2; public static final int Closed = 3; int currentState = Start; public String filename;

public DataInputStreamForAddNumbers(String filename) throws FileNotFoundException { super(new FileInputStream(filename)); // field in stores the file handle this.filename = filename; this.currentState = Open; }

public boolean inState(int state){ return this.currentState == state; }

Kestrel

Ambiguous Analysis

public int readInteger() throws IOException, EOFException{ int x = 0; switch(currentState){ case Start: throw new Error("Attempt to read from an unopen File"); case Open: try{ x = super.readInt(); } catch (EOFException e){ throw new EOFException("File" + filename + "contains no data!"); } catch (IOException e){ throw new IOException("Cannot read from file " + filename); } break; case Closed: throw new Error("File " + filename + "already closed"); } return x; }

Kestrel

Robustified Source – Ambiguous Case with state tracking and error-handling inside method calls

public class RobustAddNumbersFromFile {

static void doIt (String fileName) throws IOException { DataInputStreamForAddNumbers source = null; if ( fileName != null ) source = new DataInputStreamForAddNumbers(fileName); int count = source.readInteger(); int sum = addEm(source,count); System.out.println("Sum is " + sum); }

static int addEm(DataInputStreamForAddNumbers s, int c) throws IOException { int sum = 0; for (int i = 0; i < c; i++) sum += source.readInteger(); if ( s.available() == 0 ) s.close(); return sum; }}

Kestrel

Conclusions?

• many aspects can be treated as invariant maintenance

• an invariant corresponds to a one-state automaton policy

• automaton-based policies applied by conservative static analysis

• error-handling policies combine normal and abnormal behaviors