From f53494c28e362fb7752bbc83417b9ba47cff0bf5 Mon Sep 17 00:00:00 2001 From: rsc Date: Wed, 3 Sep 2008 04:50:04 +0000 Subject: DO NOT MAIL: xv6 web pages --- web/l-xfi.html | 246 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 246 insertions(+) create mode 100644 web/l-xfi.html (limited to 'web/l-xfi.html') diff --git a/web/l-xfi.html b/web/l-xfi.html new file mode 100644 index 0000000..41ba434 --- /dev/null +++ b/web/l-xfi.html @@ -0,0 +1,246 @@ + + +XFI + + + +

XFI

+ +

Required reading: XFI: software guards for system address spaces. + +

Introduction

+ +

Problem: how to use untrusted code (an "extension") in a trusted +program? +

+ +

What are the dangers? +

+ +

Possible solutions approaches: +

+ +

Software-based sandboxing

+ +

Sandboxer. A compiler or binary-rewriter sandboxes all unsafe + instructions in an extension by inserting additional instructions. + For example, every indirect store is preceded by a few instructions + that compute and check the target of the store at runtime. + +

Verifier. When the extension is loaded in the trusted program, the + verifier checks if the extension is appropriately sandboxed (e.g., + are all indirect stores sandboxed? does it call any privileged + instructions?). If not, the extension is rejected. If yes, the + extension is loaded, and can run. If the extension runs, the + instruction that sandbox unsafe instructions check if the unsafe + instruction is used in a safe way. + +

The verifier must be trusted, but the sandboxer doesn't. We can do + without the verifier, if the trusted program can establish that the + extension has been sandboxed by a trusted sandboxer. + +

The paper refers to this setup as instance of proof-carrying code. + +

Software fault isolation

+ +

SFI +by Wahbe et al. explored out to use sandboxing for fault isolation +extensions; that is, use sandboxing to control that stores and jump +stay within a specified memory range (i.e., they don't overwrite and +jump into addresses in the trusted program unchecked). They +implemented SFI for a RISC processor, which simplify things since +memory can be written only by store instructions (other instructions +modify registers). In addition, they assumed that there were plenty +of registers, so that they can dedicate a few for sandboxing code. + +

The extension is loaded into a specific range (called a segment) + within the trusted application's address space. The segment is + identified by the upper bits of the addresses in the + segment. Separate code and data segments are necessary to prevent an + extension overwriting its code. + +

An unsafe instruction on the MIPS is an instruction that jumps or + stores to an address that cannot be statically verified to be within + the correct segment. Most control transfer operations, such + program-counter relative can be statically verified. Stores to + static variables often use an immediate addressing mode and can be + statically verified. Indirect jumps and indirect stores are unsafe. + +

To sandbox those instructions the sandboxer could generate the + following code for each unsafe instruction: +

+  DR0 <- target address
+  R0 <- DR0 >> shift-register;  // load in R0 segment id of target
+  CMP R0, segment-register;     // compare to segment id to segment's ID
+  BNE fault-isolation-error     // if not equal, branch to trusted error code
+  STORE using DR0
+
+In this code, DR0, shift-register, and segment register +are dedicated: they cannot be used by the extension code. The +verifier must check if the extension doesn't use they registers. R0 +is a scratch register, but doesn't have to be dedicated. The +dedicated registers are necessary, because otherwise extension could +load DR0 and jump to the STORE instruction directly, skipping the +check. + +

This implementation costs 4 registers, and 4 additional instructions + for each unsafe instruction. One could do better, however: +

+  DR0 <- target address & and-mask-register // mask segment ID from target
+  DR0 <- DR0 | segment register // insert this segment's ID
+  STORE using DR0
+
+This code just sets the write segment ID bits. It doesn't catch +illegal addresses; it just ensures that illegal addresses are within +the segment, harming the extension but no other code. Even if the +extension jumps to the second instruction of this sandbox sequence, +nothing bad will happen (because DR0 will already contain the correct +segment ID). + +

Optimizations include: +

+ +

XFI

+ +

XFI extends SFI in several ways: +

+ +

x86 is challenging, because limited registers and variable length + of instructions. SFI technique won't work with x86 instruction + set. For example if the binary contains: +

+  25 CD 80 00 00   # AND eax, 0x80CD
+
+and an adversary can arrange to jump to the second byte, then the +adversary calls system call on Linux, which has binary the binary +representation CD 80. Thus, XFI must control execution flow. + +

XFI policy goals: +

+ +

The binary rewriter inserts guards to ensure these properties. The + verifier check if the appropriate guards in place. The primary + mechanisms used are: +

+ +

Can XFI protect against the attack discussed in last lecture? +

+  unsigned int j;
+  p=(unsigned char *)s->init_buf->data;
+  j= *(p++);
+  s->session->session_id_length=j;
+  memcpy(s->session->session_id,p,j);
+
+Where will j be located? + +

How about the following one from the paper Beyond stack smashing: + recent advances in exploiting buffer overruns? +

+void f2b(void * arg, size_t len) {
+  char buf[100];
+  long val = ..;
+  long *ptr = ..;
+  extern void (*f)();
+  
+  memcopy(buff, arg, len);
+  *ptr = val;
+  f();
+  ...
+  return;
+}
+
+What code can (*f)() call? Code that the attacker inserted? +Code in libc? + +

How about an attack that use ptr in the above code to + overwrite a method's address in a class's dispatch table with an + address of support function? + +

How about data-only attacks? For example, attacker + overwrites pw_uid in the heap with 0 before the following + code executes (when downloading /etc/passwd and then uploading it with a + modified entry). +

+FILE *getdatasock( ... ) {
+  seteuid(0);
+  setsockeope ( ...);
+  ...
+  seteuid(pw->pw_uid);
+  ...
+}
+
+ +

How much does XFI slow down applications? How many more + instructions are executed? (see Tables 1-4) + + -- cgit v1.2.3