400 likes | 590 Views
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
E N D
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 outside class package boundary legal reference public class confined class illegal reference
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 rules • 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 • A confined type must not be public • Methods invoked on an expression of confined type must either be defined in a confined class or be anonymous method • Subtypes of a confined type must be confined • Confined types can be widened only to other confined types • 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 } } }
Reduction rules P is a possibly empty sequence of stack frames: A frame v m e denotes the invocation of method m on a receiver Object v where e is the body of the method being evaluated.
Evaluation context Evaluation context is an expression E[o] with a hole and E[e] methods E with the hole replaced by e.
Semantics R-Field R-Cast
Semantics R-Ink R-Ret
Safe subtyping and visibility 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
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(); } }
example class 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 widening conf 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(); } }
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 violation class 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();