Language-Based Protection in the J-kernel David Walker COS 598E: Foundations of Language-Based Security Princeton University (slides from Chris Hawblitzel, Dartmouth) Extensible applications... applet applet agent browser servlet servlet server agent host code code gateway/router ...need protection Protection virtual memory address space threads address space IPC pages language-based single address space class A { pages threads A B C – share pages – IPC, thread switch private B b; public C c; public void f() ... } class B {…} class C {…} – type safety – public/private Safe language protection • Promises: – fast IPC – fine-grained sharing – ADT enforcement – capabilities – portability single address space class A { A B C private B b; public C c; public void f() ... } class B {…} class C {…} Talk outline • Extensible applications, protection • Language-based protection – current state – problems • The J-Kernel • Luna Java thread groups • Thread groups applet 1 applet 2 thread group thread group – Terminate group of threads browser thread group Java communication • Communication – Applet-to-browser – Browser-to-applet applet 1 method invocation browser applet 2 thread switch Problem 1: wrong code interrupted • Applet stops or suspends thread – browser left in inconsistent or deadlocked state applet 1 method invocation interruption! browser applet 2 Problem 2: damaged objects • Applet stops or suspends thread – ADT left in inconsistent or deadlocked state applet 1 damaged object browser applet 2 Damaged objects • Only stopping threads leaves damaged objects virtual machine task task Damaged objects • Only stopping threads leaves damaged objects virtual machine task task Damaged objects • Only stopping threads leaves damaged objects virtual machine task task Problem 3: resource accounting • JVM does not know who to blame for denial of service attacks: class TrojanHog extends Vector { private byte[] mydata = new byte[10000000]; virtual machine public Object elementAt(int i) { attackNetwork(); return super.elementAt(i); } ... trojan hog } Problem 4: weak termination • Garbage collector won’t deallocate reachable data and code – Resources not reclaimed – Malicious code not removed applet 1 browser applet 2 Problem 4: weak termination • Only stopping threads leaves objects, code – resources not reclaimed class TrojanHog – undesired code may get run { virtual machine task extends Vector private byte[] mydata = new byte[10000000]; public Object elementAt(int i) { attackNetwork(); return super.elementAt(i); } ... task trojan hog } Tasks task = objects + threads + code – task’s threads only run task’s code – explicit cross-task communication virtual machine task task int sum(int x, int y) {return x + y;} int mom(int x, int y) {return x + y;} task int foo(int x, int y) {return x + y;} Advantages of tasks • strong termination • resource accounting • clear communication • access control at boundaries • “whole-task” optimization virtual machine task task int sum(int x, int y) {return x + y;} int mom(int x, int y) {return x + y;} task int foo(int x, int y) {return x + y;} Talk outline • Extensible applications, protection • Language-based protection • The J-Kernel – Prototype implementation of the task model • written in Java • no changes to VM, language • Luna Cross-task calls • Method invocation on capability – checks for revocation – (simulated) thread switch – passes arguments • capabilities passed by reference • ordinary objects passed by copy task method invocation task cap passed by copy J-Kernel restricts sharing • Direct, arbitrary cross-task pointers violate task model – disallowed by J-Kernel task int foo(int x, int y) {return x + y;} task int sum(int x, int y) {return x + y;} task int mom(int x, int y) {return x + y;} J-Kernel capabilities • Special capability objects shared – ordinary objects not shared • Capabilities mediate cross-task communication – method invocations on capabilities are cross-task task calls task cap cap cap int foo(int x, int y) {return x + y;} task cap int sum(int x, int y) {return x + y;} int mom(int x, int y) {return x + y;} Where are the boundaries? programmer’s intention applet 1 virtual machine run-time int sum(int x, int y) {return x + y;} applet 2 int foo(int x, int y) {return x + y;} switch domains switch domains int bar(int x, int y) {return x + y;} int mom(int x, int y) {return x + y;} – Which method calls switch domains? – Who “owns” which object? (resource accounting...) – What guarantees does programmer have? Cross-task calls • Method invocation on remote pointer switches tasks – calls another task’s code – switches threads – arguments either: • primitive types • remote pointers virtual machine task int sum(int x, int y) {return x + y;} task int mom(int x, int y) {return x + y;} Cross-task calls: RMI • Semantics similar to Java Remote method invocation – J-Kernel uses RMI API • based on Java interfaces (“remote interfaces”) – Capability.create(…) generates capability • J-Kernel generates capability classes dynamically task method invocation task cap implements Servlet implements Servlet Revocation • Task can revoke any of its capabilities at any time: – least privilege, changing trust, termination task task cap cap int foo(int x, int y) {return x + y;} revoked cap task cap int sum(int x, int y) {return x + y;} int mom(int x, int y) {return x + y;} Termination • threads stopped • capabilities revoked – code, objects become eligible for GC – damaged objects inaccessible task task cap cap cap int foo(int x, int y) {return x + y;} task cap int sum(int x, int y) {return x + y;} int mom(int x, int y) {return x + y;} The J-Kernel • Prototype implementation of the task model – written in Java – no changes to VM, language Sun javac MS jvc J-Kernel bytecode rewriter Sun VM MS VM Sample Application • Extensible Web and Telephony Server PBX J-Kernel http tapi phone J-Server T-Server priv. domains servlet voicemail user domains user DB Network packet example task 1 Network driver task task 2 task 3 accounting 1 3 2 2 3 incoming packets task 1: 200K left task 2: 80K left task 3: 300K left Similar to RMI • J-Kernel: task method invocation task cap • Remote method invocation uses stubs to marshal, unmarshal arguments: passed by copy host RMI stub passed by copy host stub Example • Based on Sun’s RMI API: – classes implement remote interfaces: public interface Servlet extends Remote { public void service(Request req); } public class MyServlet implements Servlet { public void service(Request req) {...} } Servlet ms = new MyServlet(); Capability msCap = Capability.create(ms); – capabilities implement remote interfaces: ((Servlet) msCap).service(req); Performance – Pentium II @300Mhz – Microsoft VM (MS-VM) & Sun JDK w/Symantec JIT (Sun-VM) • Null method invocation – – – – Operation MS-VM Sun-VM Normal method invocation 0.024ms 0.021ms J-Kernel “local RMI” 1.20ms 3.55ms Bottlenecks: thread lookup + 2 locks • 60% of total time with MS-VM, 79% with Sun-VM • Comparison: – Windows NT LRPC: ~100ms – L4 round-trip IPC on P5-133: 1.82ms J-Kernel on P5-133: 3.77ms – Exokernel round-trip protected control transfer on DEC-5000: 2.40ms Talk outline • • • • Extensible applications, protection Language-based protection The J-Kernel Luna – Extends Java type system • Idea: generalize J-Kernel sharing to all types – Runs on customized virtual machine • based on Marmot optimizing VM Remote pointers List List~ local pointer type (can only point to task-local objects) remote pointer type (can point to objects in other tasks) Type = PrimitiveType | ReferenceType | ReferenceType~ PrimitiveType = int | float | long | double | byte | char | short | boolean ReferenceType = ClassType | InterfaceType | Type[] Remote pointers List List~ pointer List List List i i i next next next pointer Permit revocation flag access control ... Remote pointers are revocable: class List {int i; List next;} int foo(List~ list) { return list.i + list.next.i; } run-time revocation checks of p Sharing data structures • Revocation of entire data structures task 1 class List {int i; List next;} int sum(List~ list) { int sum = 0; while(list != null) { sum += list.i; list = list.next; } return sum; } List~ pointer access control Permit List List List i i i next next next task 2 Creating remote pointers List @ List~ List l = new List(1, new List(2, new List(3, null))); Permit p1 = new Permit(); Permit p2 = new Permit(); List~ l1 = l@p1; List~ l2 = l@p2; ... p1.revoke(); // selective revocation copy into local object List copy(List~ l) { if(l == null) return null; else return new List( l.i, copy(l.next)); } Remote pointer optimization // list has type List~ while(list != null) { list.i = 0; list = list.next; } loop: • infer permit reuse • optimize/omit checks in loop • register thread with permit • permit revoked: rollforward, raise exception mov dword ptr [eax+8],0 /* list.i = 0 */ mov eax,dword ptr [eax+12] /* list = list.next */ cmp eax,0 /* if(list == 0) goto done */ je done jmp loop Remote pointer optimization • Operation on remote pointer, worst case: – acquire lock, check flag, operation, release lock – two checks per loop iteration: for(List~ l = ...; l != null; l = l.next) sum += l.i; • Faster: cache revocation flag in a “TLB” • Suspend thread to invalidate cached value Remote pointer optimization • infer permit reuse • embed inferred reuse in typed intermediate language • add code to cache/uncache permit void zero(List~ list) { while(list != null) { list.i = 0; list = list.next; } } result: very fast inner loop loop: .void zero(List{} list) { cache while(list != null) { list.i = 0; list = list.next; } uncache } mov dword ptr [eax+8],0 /* list.i = 0 */ mov eax,dword ptr [eax+12] /* list = list.next */ cmp eax,0 /* if(list == 0) goto done */ je done jmp loop Servlet example interface Servlet { servlet void service(Request~ req); } class Request {String url; byte[] content;} class ServletBox {Servlet~ servlet;} servlet servlet dispatch servlet class DispatchServlet implements Servlet { Hashtable table; server void service(Request~ req) { String url = String.copy(req.url); ServletBox forwardTo = (ServletBox) table.get(url); forwardTo.servlet.service(req); } } Whole-task optimization • Marmot performs whole-program optimizations – but no dynamic loading: would invalidate opts • Luna: whole-task optimization – dynamic servlet loading of tasks task Vector servlet task extends ColorVector inline Vector.elementAt server task Vector Vector inline Vector.elementAt Performance: JK & Luna – Pentium II @300Mhz • Null method invocation – – – – Operation Normal method invocation Cross-task call, uniprocessor Cross-task call, multiprocessor JK(MS-VM) Luna 0.024ms 0.027ms 1.20ms 0.37ms 1.20ms 0.76ms • Comparison: – Windows NT LRPC: ~100ms – L4 round-trip IPC on P5-133: 1.82ms – Exokernel round-trip protected control transfer on DEC-5000: 2.40ms Related work • DrScheme – no peer-to-peer communication – task model not guaranteed • Alta – shared data – tradeoff between flexibility, resource tracking • KaffeOS – shared data buffers Conclusions • Safe language tasks: – – – – – clear communication access control domain termination resource usage whole-task optimization • J-Kernel: Capabilities + RMI • Luna: Remote pointers virtual machine task task task local pointer capability/remote pointer