170 likes | 189 Views
This paper discusses the challenges of verifying programs that involve meta-programming and the use of a Security Manager. The paper proposes a framework for verifying such programs using aspects and meta-programming techniques.
E N D
Verifying with a Security Manager Taking into account meta-programming concerns in static program verification Julien Charles
… that fails A classic scenario package b; class A { /*@ modifies \nothing; @ exsures false; @*/ public A() { // it does nothing basically } } $ java different.Main > Exception in thread "main" java.lang.SecurityException: at a.b.Main$1.checkPackageAccess(Main.java:9) …. package different; class Main { /*@ modifies \nothing; @ exsures false; @*/ public main(String [] args) { b.A a = new b.A(); } }
Interference • The semantic is unexpected: • A JVM level component interfere • It is specified nowhere • How to verify correctly this program? (which semantic?) • AOP is all about that
Aspects • It really looks like a cross cutting concern… • The Security Manager is an aspect • An invasive aspect • We need a framework to verify that!
A framework for meta-programming concerns • What are meta-programming concerns? • Meta-programs change the semantic of your virtual machine(s) • Meta-programs are invasive • Meta-programs are non-modular • Meta-programs are aspects • AspectJ programs
Modelling a Security Manager with Aspects For our 2 lines program: public void main(…) { b.A b = new b.A(); } public aspect SecurityManager { Set<String> s = new HashSet<String>(); pointcut anyPublicMethod(Object o): target(o) && call( public *(*)); before(Object o) : anyPublicMethod(o) { String pkg = o.getClass().getPackage().toString(); if(!s.contains(pkg)) { s.add(pkg); if(pkg.equals("b")) throw new SecurityException(); } } } pkg = "b"; s is empty, so it doesn’t contain b yet pkg == "b": the exception is thrown
What verification process? • Fully annotate the program and advices • Abstract the advices • Transform everything into BoogiePL • Weave the abstracted advices • Compute the weakest precondition
Specifications • We annotate the program code and the advices • Language used: Pipa • Pipa vs. JML • Here we will limit to before specs…
The annotated base program /*@ requires o != null && s != null; @ assignable \nothing; @ ensures s.contains(o.getClass().getPackage()) @ && !(o.getClass().getPackage().equals("b")); @ exsures (SecurityException) !s.contains("b") @ && (o.getClass().getPackage().equals("b")); @*/ before(Object o) : anyPublicMethod(o) { ... } /*@ assignable \nothing @ ensures s.contains("b"); @ exsures (SecurityException) @ !s.contains("b"); @*/ public static void main(String[] args) { b.A a = new b.A(); }
Abstraction • Lighter manipulation • Aspects become models /*@ public model class SecurityManager { @ public invariant s != null; @ model Set<String> s; @ @ requires o != null && s != null; @ assignable \nothing; @ ensures s.contains(o.getClass().getPackage().toString()) @ && !(o.getClass().getPackage().equals("b")); @ exsures (SecurityException) !s.contains("b") @ && (o.getClass().getPackage().equals("b")); @ public model void beforeAnyPublicMethod (Object o); @*/
Go Boogie! • Bytecode verification • The only semantic of weaving for AspectJ • Using BML annotation language • Transform everything in BoogiePL guarded commands [Lehner & Müller 07]
Base program Boogied init: // initialization of the method old heap := heap; reg0 := #0; assume requires(main, (old heap, #0)); // true start: // beginning of the program heap := add(heap, b.A); // new call stack[0] := new(heap, b.A); arg0 := stack[0]; // constructor call pre heap := heap; assert arg0 != null; assert requires(b.A.<init>, pre heap, arg0); havoc heap; goto b.A.<init> normal, b.A.<init> excp; b.A.<init> excp: havoc stack[0] assume alloc (stack[0], heap) ^ typeof(stack[0]) <:Throwable; assume exsures(b.A.<init>, (pre heap, arg0), (heap, stack[0])); goto handler; b.A.<init> normal: havoc stack[0]; assume ensures(b.A.<init>, (pre heap, arg0), (heap, stack[0])); post: // post condition and exception handler assert ensures(main, (old heap, #0), (heap, stack[0])); // s.contains("b") goto; handler: assert exsures(main, (old heap, #0), (heap, stack[0])); // !s.contains("b"); goto;
Verification conditions • Weaving rules [Belblidia & Debbabi 06] • How weaving is done? • The wp used is the one that is described in Leino’s paper: [Weakest precondition over unstructured programs]
Related work • Static verification usually modular, with restrictions: • Clifton’s PhD thesis • Kunz’ Hoare logic • Krishnamurti model checking framework • No implementation available, and often unrealistic frameworks
Conclusion • Non-modular verification framework • Simple • Realistic • Using lots of existing technologies • Targets a real language
Future work • Specification with aspects is hard • Implementation as soon as JML AST gets stable again • The other half of the framework depends the realization of Mobius PVE
For more infos, you can read my paper "Taking into account Java’s…." on my webpage