1 / 32

Policy Enforcement and Refinement

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

Download Presentation

Policy Enforcement and Refinement

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. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Policy EnforcementandRefinement Douglas R. Smith Kestrel Institute Palo Alto, California

  2. Issue: How to Handle Nonfunctional and Cross-Cutting Concerns wrtComposition 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

  3. A Generative Approach to Aspect-Oriented Programming hypothesis: aspects are invariants to maintain

  4. FigureElement incrXY() crosscutting(one form of it) Crosscutting in AspectJ * * Display Point Line 2 getX() getY() setX(int)setY(int) incrXY() getP1() getP2() setP1(Point)setP2(Point) incrXY() 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(); } }

  5. 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 theadvice 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?

  6. Maintain an Error Log Policy: Maintain an error log in a system

  7. 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, …)

  8. hist :=S0, act0 hist := hist ::S1, act1 hist := hist ::S2, act2 Virtual Variables in State key idea: extend state with a virtual history variable act0 act1 act2 S0 S3 ••• S1 S2 • Virtual variables • exist for purposes of specification • sliced away prior to code generation

  9. Maintain an Error Log Policy: Maintain an error log in a system Invariant: errlog = filter(error?, actions(hist)) Disruptive Actions: error?(act) Spec for Maintenance Code : for each error action erract, Assume: errlog = filter(error?, actions(hist)) Achieve: errlog´ = filter(error?, actions(hist´)) = filter(error?, actions(hist :: S, erract)) = filter(error?, actions(hist):: erract) = filter(error?, actions(hist)):: erract = errlog :: erract spec satisfied by: errlog :=errlog :: erract

  10. Maintaining an Error Log act0 error1 act2 S0 S3 ••• S1 S2 hist :=S0, act0 hist := hist ::S1, act1 hist := hist ::S2, act2 errlog :=errlog errlog :=errlog::error1 errlog :=errlog

  11. 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 specification • Assume: P(x)  I(x) • Achieve: Q(x, x´)  I(x´) spec typically satisfied by code of the form: act || update

  12. 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

  13. send(*) read(f ) policy automaton: Two One a read(f ) send(m) A B C D F E Enforce a Security Policy Policy: No send actions allowed after file f is read Build simulation map, then generate new code for corresponding actions Inconsistent joint action spec: send(*)  send(m) satisfied by abort action

  14. Error-Handling Policiesand their Enforcement Douglas R. Smith Klaus Havelund Kestrel Technology Palo Alto, California www.kestreltechnology.com

  15. 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; }}

  16. Generic File Management Policy FileNotFoundException / handler1 IOException / handler2 use open close Start Open Stop use Error handler3

  17. 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

  18. 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(); …

  19. 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"); } }

  20. 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 }

  21. Policy Simulation on the Example Program DoIt entry addEm entry {Start} T fileName != null {Open} F sum = 0; i= 0; source = new DataInputStreamPolicy(fileName) {Start} {Open} {Open} ambiguous analysis F T i < c {Start,Open} {Open} count = source.readInteger(); sum += source.readInteger(); i++; {Open} {Open} call addEm(source,count); {Open  Closed, Open  Open } {Open} T s.available()==0 {Open} sum = result F s.close(); {Open,Closed} {Open} {Closed} System.out.println("Sum is " + sum) {Open, Closed} {Open,Closed} return sum exit {Open, Closed} exit

  22. Program Transformation to Reduce Policy Ambiguity has ambiguous analysis if ( fileName != null ) source = new DataInputStream(new FileInputStream(fileName)); count = source.readInt(); distribute if-then-else over semicolon if ( fileName != null ){ source = new DataInputStream(new FileInputStream(fileName)); count = source.readInt(); } else { count = source.readInt(); } has unambiguous analysis! apply the policy and simplify if ( fileName == null ) throw new Error("Attempt to read from an unopen File"); source = new DataInputStream(new FileInputStream(fileName)); count = source.readInt(); unambiguous analysis, clear code

  23. 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; } }

  24. Policy-Specific Tracking Code (unambiguous case) HandlErr would generate an extension of the DataInputStream class that records the policy instance bindings for the in error-handlers. 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; } }

  25. Revised Java Program with Enforced Policy class 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); } …

  26. Policy Simulation on the Example Program DoIt entry addEm entry {Start} T fileName != null {Open} F sum = 0; i= 0; source = new DataInputStreamPolicy(fileName) {Start} {Open} {Open} ambiguous analysis F T i < c {Start,Open} {Open} count = source.readInteger(); sum += source.readInteger(); i++; {Open} {Open} call addEm(source,count); {Open  Closed, Open  Open } {Open} T s.available()==0 {Open} sum = result F s.close(); {Open,Closed} {Open} {Closed} System.out.println("Sum is " + sum) {Open, Closed} {Open,Closed} return sum exit {Open, Closed} exit

  27. 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

  28. Generic File Management Policy FileNotFoundException / handler1 IOException / handler2 use open close Start Open Stop use Error handler3

  29. 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; }

  30. 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; }

  31. Robustified Source – Ambiguous Casewith 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; } }

  32. 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

More Related