1 / 36

Secure Execution of Untrusted Code

Secure Execution of Untrusted Code. Motivation. Mobile code scenarios Java applet / Javascript in web page Postscript / PDF file Email attachment BPF Active networks Agent technology. Untrusted Code. My Secure PC. Challenges. Untrusted code may

denis
Download Presentation

Secure Execution of Untrusted Code

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Secure Execution ofUntrusted Code

  2. Motivation • Mobile code scenarios • Java applet / Javascript in web page • Postscript / PDF file • Email attachment • BPF • Active networks • Agent technology Untrusted Code My Secure PC

  3. Challenges • Untrusted code may • Read sensitive memory regions(password, cryptographic keys, db records) • Write memory areas, violate integrity(overwrite public verification key) • Jump to arbitrary location (jump past password verification) • Perform arbitrary system calls (execute arbitrary local programs, access file system) • Waste resources, DoS (memory, computation, network bandwidth), thrash OS (while 1 do fork()) • Crash program, OS

  4. Solution 1: Separate Process • Run untrusted code in separate process • Advantages • Memory separation through VM system • Disadvantages • Inter-Process Communication (IPC) is expensive • Context switch has high overhead (TLB, cache) • Untrusted code can do any system calls • To protect file system, use chroot

  5. Solution 2: Signed Code • Only accept code digitally signed by trusted entity • Advantages • Simple security policy • Can be secure if trusted entity creates “secure code” • Disadvantages • Security relies on secrecy of private key • Security relies on authenticity of public key • Coarse-grained access control

  6. Solution 3: Sandboxing • Run code in limited environment • Verify each system call • Verify each memoryreference • Advantage • Fine-grained control • Disadvantages • Efficiency • Expressing security policy • Sandbox may have security vulnerabilities Sandbox Untrusted Code Application

  7. Solution 4: SFI • Provide memory safety efficiently • Can only r/w legitimate memory locations • Software fault isolation (SFI): transform untrusted code into safe code • Compiler: generates safe code • Ship source code, or • Generate code that verifier can easily check • Loader (binary patching): rewrite untrusted code

  8. SFI • Load each module into its own fault domain • Code is in read-only part • Module can r/w anything within fault domain • Code can only jump within fault domain • Two parts • Efficient Software Encapsulation • Fast Communication Across Fault Domains Untrusted Code Untrusted Code Untrusted Code Application

  9. Efficient Software Encapsulation • Goal • Only allow writes within data part of fault domain • Only allow jumps within code segment of fault domain • Mechanisms • Split memory space into segments, each segment has a segment identifier (high-order bits of address), and comprises all addresses for any low-order bits • Separate code and data segments • Dedicated registers are only used by inserted code, cannot be modified by untrusted code • Tame unsafe instructions by segment matching or address sandboxing • PC-relative jumps often safe, static stores are safe • Other stores and jumps are unsafe

  10. RISC Instruction Set Simplifies SFI • Memory accessed with load / store instruction (no add to memory) • All instructions have fixed size, and are aligned • Simplifies instruction verification • Simplifies jump target verification • Usually large number of registers • Can tolerate giving up 5 dedicated registers

  11. Segment Matching • Verifies correctness of memory accesses • Advantage • Can pinpoint address of offending instruction, useful in debugging • Disadvantage • Slow dedicated-reg target address scratch-reg  (dedicated-reg >> shift reg) compare scratch-reg and segment-reg trap if not equal store instruction uses dedicated-reg

  12. Address Sandboxing • Set segment identifier for each memory access / jump instruction • Overwrite segment identifier with fault domain’s segment identifier • Advantage: efficient • Disadvantage: cannot pinpoint flaw, only enforces that accesses are within domain dedicated-reg target-reg & and-mask-reg dedicated-reg dedicated-reg | segment-reg store instruction uses dedicated-reg

  13. Puzzles • What about the following transformation, not using dedicated register? target-reg  target-reg & and-mask-reg target-reg  target-reg | segment-reg store instruction uses target-reg • What about jumps into SFI verification instructions? Could we jump outside of fault domain? Could we write to code segment? Could we jump to data segment? • What if we only used 4 dedicated registers (sandboxing case, i.e., 1 dedicated-reg for code/data)?

  14. 4-Register Attack jump target-reg dedicated-reg target-reg & and-mask-reg dedicated-reg dedicated-reg | segment-reg-c jump instruction uses dedicated-reg target-reg = r2 dedicated-reg target-reg & and-mask-reg dedicated-reg dedicated-reg | segment-reg-d store instruction uses dedicated-reg

  15. Verification of Instrumented Code • Problem: given instrumented binary, how can we verify that all rules are met? • Verify that all unsafe stores and jumps use dedicated registers to form address • Verify that all inserted code has correct pattern (identify inserted code by use of dedicated registers)

  16. Fast Communication Across Fault Domains • Use Jump Table with legal entry points outside fault domain • For each call between fault domains, a customized stub procedure is created • Stubs run unprotected outside fault domain • Trusted stub directly copies arguments to destination domain • Switch execution stack • Set up register context and validate dedicated registers

  17. SFI Discussion • System calls from fault domain? • Issues and solutions • Allowing arbitrary memory reads? • Could we improve the granulartiy of memory protection? • Missing read protection a problem? • Is granularity of jump protection sufficient? • Flexibility for segment size? Internal fragmentation? • Can SFI prevent buffer overruns? • Is self-modifying code possible? • SFI on CISC processors? • Can we change compiler once verifier is deployed?

  18. Solution 5: PCC • Proof-carrying code (PCC) developed @ CMU by George Necula and Peter Lee • Goal: safely run code in unsafe languages • Approach: create efficiently verifiable proof that untrusted code satisfies safety policy • May not need instrumentation code (no execution overhead!) if we can prove code safety • Slides based on George Necula’s OSDI96 talk

  19. Legend: code proof oracle bits Proof-Carrying Code: An Analogy

  20. untrusted application code certification native code safety proof proof validation formal safety policy CPU Proof-Carrying Code (PCC) code producer code consumer PCC binary

  21. Benefits of PCC • Wide range of safety policies • memory safety • resource usage guarantees (CPU, locks, etc.) • concurrency properties • data abstraction boundaries • Wide range of languages • assembly languages • high-level languages • Simple, fast, easy-to-trust validation • Tamper-proof

  22. Experimentation • Goal: • Test feasibility of PCC concept • Measure costs (proof size and validation time) • Choose simple but practical applications • Network Packet Filters • IP Checksum • Extensions to the TIL run-time system for Standard ML

  23. Experimentation (2) • Use DEC Alpha assembly language (hand-optimized for speed) • Network Packet Filters • BPF safety policy: “The packet is read-only and the scratch memory is read-write. No backward branches. Only aligned memory accesses.”

  24. PCC Implementation (1) • Formalize the safety policy: • Use first-order predicate logic extended with can_rd(addr) and can_wr(addr) • Kernel specifies safety preconditions • Calling convention • Guaranteed by the kernel to hold on entry • Use tagged memory to define access

  25. PCC Implementation (2) • Compute a safety predicate for the code • Use Floyd-style verification conditions (VCgen) • One pass through the code, for example: • For each LD r,n[rb] add can_rd(rb+n) • For each ST r,n[rb] add can_wr(rb+n) • Prove the safety predicate • Use a general purpose theorem prover

  26. PCC Implementation (3) • Formal proofs are trees: • the leaves are axiom instances • the internal nodes are inference rule instances • at the root is the proved predicate • Example:

  27. PCC Implementation (4) • Proof Representation: Edinburgh Logical Framework (LF) • Proofs encoded as LF expressions • Proof Checking is LF type checking • simple, fast and easy-to-trust (14 rules) • 5 pages of C code • independent of the safety policy or application • based on well-established results from type-theory and logic • Large design space, not yet explored

  28. Packet Filter Experiments • 4 assembly language packet filters (hand-optimized for speed): • Accepts IP packets (8 instr.) • Accepts IP packets for 128.2.206 (15 instr.) • IP or ARP between 128.2.206 and 128.2.209 • TCP/IP packets for FTP (28 instr.) • Compared with: • Run-Time Checking: Software Fault Isolation • Safe Language: Modula-3 • Interpretation: Berkeley Packet Filter

  29. Performance Comparison • Off-line packet trace on a DEC Alpha 175MHz • PCC packet filters: fastest possible on the architecture • The point: Safety without sacrificing performance!

  30. Cost of PCC for Packet Filters • Proofs are approx. 3 times larger than the code • Validation time: 0.3-1.8ms

  31. Validation Cost (Filter 3) • Conclusion: One-time validation cost amortized quickly

  32. SFI PCC for Memory Safety • Continuum of choices between static checking and run-time checking: • PCC can be also used where run-time checking cannot (e.g., concurrency) Performance Penalty Static Checking Run-Time Checking Proof Complexity

  33. What Can We Check With PCC? • Any property with a sound formalization • if you can prove it, PCC can check it! • One proof-checker for many such policies! • Small commitment for open-ended extensibility • Example: policies defined by safe interpreters • E.g, security monitors, memory safety, resource usage limits, … • … can be enforced statically with PCC • Prove that all run-time checks would succeed • No run-time penalty

  34. Safety policy: • host invokes the agent with: • security clearance level • item and price fields readable only if access £ level • parent • communication permitted only back to parent • must terminate within MAX instructions • wait BNDW * SIZE instructions before sending SIZE bytes agent • level • parent PCC Beyond Memory Safety Example: database with access control access item price pricing server PCC is not limited to memory safety!

  35. Practical Difficulties • Proof generation • Similar to program verification • But: • done off-line • can use run-time checks to simplify the proofs • In restricted cases it is feasible (even automatable) • Proof-size explosion • It is exponential in the worst case • Not a problem in our experiments

  36. PCC Discussion • A very promising framework for ensuring safety of untrusted code • Limitations? • What about generating proof on the fly? • Could verify safety property based on specific arguments • Related problem: how to secure mobile code from malicious host?

More Related