Department of Computer
University of Virginia
David Evans and Andrew Twyman. Policy-Directed Code Safety. 1999 IEEE Symposium on Security and Privacy, Oakland, California, May 9-12, 1999.
In order to enforce a safety policy, the appropriate resource operations must be called when the corresponding resource is manipulated. The platform interface describes how system calls affect resources.
For each platform, we must determine an appropriate level for the platform interface. That is, we must decide which library calls are described by the platform interface, and which will be considered part of the application and transformed by the application transformer. The level of the platform interface limits the resource manipulations that can be identified, and hence, the class of safety policies that can be expressed. For example, if we place the platform interface at the level of system calls, we cannot express safety policies that constrain lower-level resources such as memory or processor usage.
For Naccio/JavaVM, we are limited by our ability to deal easily with code for native methods. This means at a minimum the platform interface must describe all Java API native methods that affect resources. We could stop there, and simply consider that rest of the Java API part of the application that needs to be considered by the application transformer. When a library native method is called, we would replace the call with a call to a wrapped version of the method that performs the necessary safety checking.
This would be unsatisfactory, however, since it allows for no distinctions regarding how the native method is called. For example, the AWT method that loads a font would call the same wrapper file open method as user code that opens a FileInputStream. To handle checking correctly, we would need to resort to using run-time mechanisms (e.g., stack introspection [Wallach98]) to identify and distinguish trusted system code. Instead, it seems clear that the platform interface for the JavaVM platform should describe all Java API methods in terms of how they affect resources. Internal API calls within API methods need not do additional safety checking since the platform interface describes all relevant resource manipulations at the level of the API method. This eliminates the need to make any run-time distinctions between unprivileged code and privileged system code.
For each Java API method or constructor that affects a system resource, we provide a corresponding platform interface wrapper that invokes the appropriate resource operations. Consider the java.io.FileOutputStream platform interface. The RFile and RFileSystem classes correspond to the RFile and RFileSystem resources. The RFileMap helper class keeps a mapping between Java files and the corresponding RFile object. We use the rfile state variable to keep track of the RFile object associated with a FileOutputStream.
Consider the wrapper for the write method shown in Figure 5. If the rfile object associated with this FileOutputStream represents a file, it calls the RFileSystem.write resource operation. If the safety policy constrains the write operation, the relevant checks will be done in the RFileSystem.write operation. If there is a safety violation, it will be detected here and the user will have the option to terminate execution before the FileOutputStream write method is called. The %%% symbol indicates the point where the original FileOutputStream.write method should be invoked.
Producing a platform interface is a somewhat tedious process and errors represent potential security holes. To make it easier to generate platform interface wrappers, we have developed a tool that analyzes the Java API source files and produces template wrappers. It analyzes dependencies to determine what native methods may be called from the method. Since all system resource manipulation relies on native methods, any method that does not call any native methods does not need a platform interface wrapper. Although we still need to examine the results by hand to produce the necessary wrappers, the automatic analysis allows us to quickly eliminate about half of the methods from the Java API, and decreases the likelihood of errors in the platform interface. At present, we have written a platform interface for a subset of the Java API including most classes that manipulate the network and file system.
For Win32, a similar argument was used to determine the level of the platform interface. The most convenient level for a Win32 platform interface is that of the Win32 API. The API has documented behavior, making the creation of platform interface wrappers relatively straightforward. Furthermore, the Win32 API is fully encapsulated into dynamic link libraries (DLLs), and thus it is easily separable from user code.
Browse Java API Platform Interface
Next - Generating Policies
Return to Policy Generation Overview
Naccio Home Page
University of Virginia, Computer Science