kestrel policy enforcement and refinement douglas r. smith kestrel institute palo alto, california
TRANSCRIPT
Kestrel
Policy Enforcementand
Refinement
Douglas R. SmithKestrel Institute
Palo Alto, California
Kestrel
Specifications and Morphisms
spec Partial-Order is sort E op le: E, E Boolean axiom reflx is le(x,x) axiom trans is le(x,y) le(y,z) le(x,z) axiom antis is le(x,y) le(y,x) x = yend-spec
spec Integer is sort Int op : Int, Int Boolean op 0 : Int op _+_ : Int , Int Int …end-spec
Specification morphism: a language translation that preserves provability
E ↦ Int le ↦
axioms ↦ thms
Kestrel
Constructing Refinements
Scheduling0
Scheduling1
po
Scheduling2
po
1. Library of Refinements
Set
Sequence
Resource
TransportationResource
GlobalSearch
Global SearchAlgorithm
• Rewrite Simplification• Context-dependent Simplification• Finite Differencing• Case Analysis• Partial Evaluation
2. Library of Refinement Generators
GlobalSearch
Global SearchAlgorithm Set
Sequence
Scheduling3
Scheduling4
Context-dependent Simplification
Finite Differencing
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
Working Hypothesis
1. A policy is a cross-cutting constraint that reduces nondeterminism in a system.
2. Policy enforcement determines a refinement.
3. We can express policies constraint as automata or in temporal logic
4. Explore enforcement mechanisms for various classes of policies
System
Policy Constraint
Policy Conditions
RefinedSystem
showing where thepolicy applies seems torequire sound staticanalysis
Kestrel
A Generative Approach to
Aspect-Oriented Programming
hypothesis: aspects are invariants to maintain
Kestrel
Maintain an Error Log
Policy: Maintain an error log in a system
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
Error-Handling Policiesand their Enforcement
Douglas R. Smith
Klaus Havelund
Kestrel Technology/NASA Ames
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
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
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
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
Ambiguous Analysis
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 { 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
Extra slides