Post on 09-Jan-2016
description
Type-based confinement
content
• Introduction
• Related work
• Confinement rules
• Formalization
• Generic confined types
Introduction
• Confinement properties impose structure on object graphs to enforce encapsulation
• Confinement is based on package-level protection
• The type system is based on call-by-value object calculus as well as a generic extension.
Motivating example
class Class {private Identity[] signers;public Identity[] getSigners( ) {
return signers;}
}• The signers field holds capabilities that are
managed by the security subsystem. • By returning the object referenced by signers, the
class expose the array to updates by outside code.
Confined types
• An object of confined types is encapsulated within its defining scope
packageboundary
public class confined class
outside class
legalreference
illegalreference
A solution using confined types
@confined class SecureIdentity {
… // original implementation
}
public class Identity {
SecureIdentity target;
Identity (SecureIdentity t) { target = t; }
… // public operations on identities
}
A solution using confined types
public class Class {
private SecureIdentity[] signers;
public Identity[] getSigners ( ) {
Identity[] pub = new Identity[signers.length];
for (int i = 0; i < signers.length; i ++)
pub[i] = new Identity(signer[i]);
return pub;
}
}
Other solutions
• Return a copy of the signer array
• Using façade or wrapper objects to interpose between trusted and untrusted components
• Discretionary access control checks
Related work
• Full aliasing protection: Islands (Hoggs, 1991), Balloon types (Almeida, 1997) – representation objects are fully enclosed in the encapsulation boundary.
• Flexible alias protection (Noble et al, 1998) – distinguish representation and argument objects
• Ownership types (Clarke et al. 1998, Boyapatti et al. 2002) – all external access to the representation objects must go through their owners
Confinement rules1. A confined type must not appear in the type of a
public (or protected) field or the return type of a public (or protected) method
2. A confined type must not be public3. Methods invoked on an expression of confined type
must either be defined in a confined class or be anonymous method
4. Subtypes of a confined type must be confined5. Confined types can be widened only to other confined
types6. Overriding must preserve anonymity of methods
Anonymous method
• The this reference is used only to select fields and as the receiver in the invocation of other anonymous methods
Example
package p;
public class Table {private Bucket[] buckets;public Object get(Object key) { … }
}@confined class Bucket {
Bucket next;Object key, val;
}
class Example {
int count;
int anon ok( A arg ) {
alsoOk( arg.foo() );
return count ; }
void anon alsoOk( int i ) { count = i + count ; }
Example notOk( A arg ) {
arg.bar( this ) ;
arg.o = this ;
notOk( arg );
return this ;
} }
package inside;
public class C extends outside.B {
void putReferences() {
C c = new C();
r1 outside.B.c1 = c;
r2 outside.B.storeReference(c);
r3 outside.B.c3s = new C[] {c};
r4 calledByConfined();
r5 implementedInSubclass();
r6 throw new E();
}
void implementedInSubclass() { }
r7 public static C f = new C();
r8 public static void C m() { return new C(); } r9 public static C[] fs = new C[]{new C()};
r10 public C() { }
}
public class E extends RuntimeException { }
class D extends inside.C {
r5 void implementedInSubclass() {
// store this }
}
package outside;
public class B {
r1 static inside.C c1;
r2 static void storeReference(inside.C c2) {//store c2}
r3 static inside.C[] c3s;
r4 void calledByConfined() { // store this }
static void getReferences() {
r7 inside.C c7 = inside.C.f;
r8 inside.C c8 = inside.C.m();
r9 inside.C[] c9s = inside.C.fs;
r10 inside.C c10 = new inside.C();
D d = new D();
try { d.putReferences();
r6 } catch (inside.E ex) { // store ex }
} }
Syntax
)(new::
)(new|)(|)(.|.|::
};return{)(]anon[::
};.this);(super{)(::
};{class]conf[::
.::
vCv
eCeCemefexe
exCmCM
ffffCCK
MKfCDCL
qpC
Reduction rules
'''.. emvPemvP
P is a possibly empty sequence of stack frames:
emvPnilP .|::
A frame v m e denotes the invocation of method m on a receiverObject v where e is the body of the method being evaluated.
Evaluation context
)],[,(new|)],[,(.|
)(].[|].[|][)(|::][
eoEvCeoEvmv
emoEfoEoECooE i
Evaluation context is an expression E[o] with a hole andE[e] methods E with the hole replaced by e.
Semantics
][.][.
)()(fields).(new
i
i
vEmvPeEmvP
fDCfvCe
)](new[.][.
':)(new)'(
vCEmvPeEmvP
CCvCCe
R-Field
R-Cast
Semantics
0
0
]this',[''.][.][.
),(),'(mbody)(new')(''.
evx
vmveEmvPeEmvP
exCmuCvvmve
R-Ink
]''[.''''.][.
)(''.
vEmvPvmveEmvP
vmve
R-Ret
Safe subtyping and visibility
DC
DCDC
confined isconfined is:
),(
confinednot is
DCvisible
C
),(
package same thein are and
DCvisible
DC
True if class C is visible from class D
Expression typing rules
T-Var
T-Field
T-UCast
Expression typing rule
T-New
T-Invk
Method typing rule
Class typing rule
example
class p.Cell extends l.Object {
l.Object data;
l.Object getData() { return this.data; }
}
conf class p.Buck extends p.Cell {
p.Buck() { super(); }
}
exampleclass p.Table extends l.Object {
p.Buck buck;Table(p.Buck buck) { super(); this.buck=buck; }p.Cell get() { return this.buck; }
}class p.Factory extends l.Object {
p.Factory() { super(); }p.Table table() {
return new p.Table( new p.Buck() ); }
Confined object leaked
class o.Breach extends l.Object {
l.Object main() {
return new p.Factory().table().get();
}
}
Implicit reference wideningconf class p.Self extends o.Broken {
}
class o.Broken extends l.Object{
l.Object reveal() { return this; }
}
class p.Main extends l.Object {
Main() { super(); }
l.Object get() { return new p.Self().reveal(); }
}
Well-typed program
Confinement
• An expression e is visible from C’ relative to C if the types of all sub-terms of e are visible from C’ except sub-terms of the form v.f, v.m(…), where v may be an object of type C.
• A program P = v1 m1 e1 … vn mn en satisfies confinement iff for all i between 1 and n, the expression e is visible from C’ relative to C, where vi is an object of class C, method mi called on vi is defined in C’.
Subject reduction, progress, and confinement
• If P is well-typed and P -> P’, then P’ is well-typed
• If P is well-typed and not in the forms of nil.v m v’, then there exists P’ such that P -> P’
• If P is well-typed, satisfies confinement, and P->* P’, then P’ satisfies confinment
Generics and confinement
class p.List <X extends l.Object>
extends l.Object {
X val;
p.List<X> next;
List (X val, p.List<X> next) {
super(); this.val = val; this.next = next;
}
}
Generics and confinement
class q.A extends l.Object {
p.List<A> show;
p.List<B> hide;
…
}
conf class q.B extends l.Object { … }
Confinement violationclass p.Container <X extends l.Object>
extends l.Object {X val;Container(X val) { this.val = val; }l.Object get() { return this.val; }l.Object get2() { return this; }
}class q.A extends l.Object{p.Container<q.B> f =
new p.Container<q.B>(new q.B());l.Object reveal() { return f.get(); }
}
Additional rules
7. A generic type or type variable cannot be widened to a type containing a different set of type variables
8. A method invoked on an expression of type T must either by defined in a type with the same set of type variable as that in T or be an anonymous method.
Overriding must preserve anonymity of methods
class q.Naïve<X extends q.A> {X f;Naïve(X f) {this.f = f;}l.Object reveal() { return this.f.m(); }
}class q.A extends l.Object {anon l.Object m() { return new l.Object(); }
}class q.B extends q.A {l.Object m() { return this; }
}conf class q.C extends q.B { … }
class q.Naïve<X extends q.A> {X f;Naïve(X f) {this.f = f;}l.Object reveal() { return this.f.m(); }
}class q.A extends l.Object {anon l.Object m() { return new l.Object(); }
}class q.B extends q.A {l.Object m() { return this; }
}l.Object o = new q.Naïve<q.C>( new q.C() ).reveal()
new q.Naïve<q.C>( new q.C() ).f.m()new q.C().m()new q.C()
Subclasses of confined class must be confined as well
class q.Container <X> {
X val;
Container(X val) { this.val = val; }
X get() { return this.val; }
}
conf class p.A { … }
class p.C extends q.Container<p.A> {
C () { super(new p.A()); }
}
l.Object o = new p.C().get()
new p.A();