CSE 227: Lecture 8

The topics covered in this lecture are BPF, Spin, SFI, and PCC. These are methods for safe kernel extensions and have applications to other contexts where untrusted code must be run, usually for performance reasons.

Berkeley Packet Filter

In-kernel packet filter to eliminate frequent kernel-user context switches to deliver packets most of which will be filtered and discarded. Main idea: the use of a ``little language'' designed for packet filtering. Features op-codes for matching IP packet header elements, forward only branches, and of course the ability to either discard the packet or to forward it up to user-level code for more complex matching or processing.


Spin operating system permitted kernel extensions since the kernel and all extensions were written in Modula 3. (Very low level parts of the kernel was in assembler.) The key observations are that the type-safety of Modula 3 is enforced by the compiler, and the correspondance between the generated object code and the source is guaranteed by the compiler by a digital signature. Further, the confidentiality of the signature generation key embedded in the compiler binary is ensured by (standard) operating system access controls.

Drawbacks include having to choose between a master key for all compiler distributions, or not having the ability to distribute kernel extension modules in binary form.

Software Fault Isolation (SFI)

In SFI binary code is instrumented to add checks before potentially dangerous operations. Original work done on the MIPS; no public working implementation for IA32 have been demonstrated AFAIK. Key optimizations include putting data into a separate, power-of-2 sized region with two 4*32K additional (register offset) memory chunks before and after the power-of-2 region, so protection against stray memory writes can be implemented using a mask and an OR instruction to set the high-order bits of a pointer.

Control transfers are constrained to jump inside of a similar separate region of text; the control transfer targets must be the beginning of identified basic blocks so that neither the store protection instructions nor the jump protection instructions may be bypassed. Note that the original prototype required the use of a modified version of gcc which kept a register free for use by the mask/OR operations, and the only place where a jump instruction used a register is for a switch statement.

Proof Carrying Code (PCC)

In PCC, a proof-generating compiler emits a proof of security (relative to a given security policy) along with the machine code. In the original prototype, the length of the proof could be exponential on the size of the program, though there's been extensive work recently on reducing the size of the proof. The code, along with the proof, is sent to the code consumer (e.g., kernel), which uses a proof verifier -- a type checker -- to verify that the code and the proof satisfies the consumer's security policy prior to allowing control to be transferred to the code.

PCC code can be extremely efficient. A drawback is that the proof of correctness/security is relative to a given security policy, so in a system where there may be many security policies or where the security policy is not known ahead of time, the proof-generating compiler will not know what to do. An important advanntage is that the typechecker is small, so the additional complexity to the TCB is small.

Additional Info

[ search CSE | CSE | bsy's home page | links | webster | MRQE | google | yahoo | citeseer | pgp certserver | openpgp certserver ]
picture of bsy

bsy+cse227w03@cs.ucsd.edu, last updated Thu Feb 6 22:50:28 PST 2003. Copyright 2003 Bennet Yee.
email bsy.

Don't make me hand over my privacy keys!