Check out the new USENIX Web site.

next up previous
Next: Certifying the Safety of Up: Defining a Safety Policy Previous: An abstract machine for

A sample application and its precondition

The abstract machine as given above describes safety in terms of the abstract notions of readable and writable memory locations. For this to be useful, the code consumer must specify an interface to binaries that identifies the readable and writable memory locations. We do this by specifying a precondition, which is a predicate in first-order logic that the code consumer guarantees to be valid when the binary is invoked.

Consider the following simple example. Suppose an operating-system kernel maintains an internal table with data pertaining to various user processes. Each table entry consists of two consecutive memory words--a tag and a data word. The tag describes whether the data word is user writable or not. The kernel also provides a resource access service through which user processes are given permission to access their table entry by installing native code in the kernel. To make this possible the kernel invokes the user-installed code with the address of the table entry corresponding to the parent process in machine register tex2html_wrap_inline1376 . This address is guaranteed by the kernel to be valid and aligned on an 8-byte boundary.

Although this example is somewhat contrived, we can imagine that entries in the table represent capabilities (perhaps file descriptors), and so we would like to provide user-installed code with full access to the correct table entries, while maintaining the integrity of the rest of the table and other parts of the kernel state.

Informally, the safety policy for the resource access service requires that: (1) the user code cannot access other table entries besides the one pointed to by tex2html_wrap_inline1378 , (2) the tag is read only, (3) the data word is also read only unless the tag value is non zero, and, (4) the code does not modify reserved and callee-saves registers. The last condition ensures that the kernel can safely invoke the user code using a normal C function call.

More formally, the kernel specifies a precondition tex2html_wrap_inline1380 , which states that it is safe to read the tag pointed to by tex2html_wrap_inline1382 , and that it is also safe to write the data at offset 8 from tex2html_wrap_inline1384 if the contents of the tag is not 0. In formal notation, this is written as follows:

displaymath1386

What remains now is to prove for a particular client of the resource access service that all tex2html_wrap_inline1388 and tex2html_wrap_inline1390 checks will always succeed, given this precondition and abstract machine. In general, we can also specify a postcondition as part of the safety policy, which would require particular invariants to be valid when the user code terminates. Conceptually, in our example the postcondition is the predicate tex2html_wrap_inline1392 , meaning that no additional conditions are imposed on the final machine state.

Before moving on to a discussion of the proof generation process, we note that the safety policy we have described here can be thought of as enforcing fine-grained memory protection. In general, one could imagine having much more involved safety requirements. For example, we could change the tag word in the table entry to be a semaphore that the user code must acquire (e.g., atomically test-and-set to zero) before trying to write the data word; furthermore, we could also require (via a simple postcondition) that the code releases the semaphore before returning. Again, for purposes of the current presentation, we stick to the simpler memory-safety requirements.



next up previous
Next: Certifying the Safety of Up: Defining a Safety Policy Previous: An abstract machine for



Peter Lee
Tue Sep 17 15:37:44 EDT 1996