Check out the new USENIX Web site. next up previous
Next: Measuring Systems Up: Problem Statement Previous: Integrity Background

Example

We use as an example a server machine running an Apache Webserver and Tomcat Web Containers that serve static and dynamic content to sell books to clients running on remote systems. The system is running a RedHat 9.0 Linux environment. Figure 1 illustrates the runtime environment that affects the Web server.
Figure 1: Runtime System Components

The system is initiated by booting the operating system. The boot process is determined by the BIOS, grub bootloader, and kernel configuration file (/boot/grub.conf). The first two can alter the system in arbitrary ways, so they must be measured. An interesting point is that measurement of configuration files, such as grub.conf, is not necessary as long as they do not: (1) modify code already loaded and (2) all subsequent file loads can be seen by the measurement infrastructure. Since the BIOS and grub bootloader are unaffected, we only need to ensure that the kernel and other programs whose loads are triggered by the configuration are measured.

The boot process results in a particular kernel being run. There are a variety of different types of kernels, kernel versions, and kernel configurations that determine the actual system being booted. For example, we load Linux 2.6.5-tcg from /boot/vmlinuz-2.6.5-tcg which includes a TPM driver and our measurement hooks. Further, the kernel may be extended by loadable kernel modules. The measurement infrastructure must be able to measure the kernel and any modules that are loaded. The challenger must be able to determine whether this specific kernel booted and the dynamically loaded modules meet the desired integrity requirements.

Once the kernel is booted, then user-level services and applications may be run. In Linux, a program execution starts by loading an appropriate interpreter (i.e., a dynamic loader, such as ld.so) based on the format of the executable file. Loads of the target executable's code and supporting libraries are done by the dynamic loader. Executables include the following files on our experimental system:

All of this code impacts system integrity, so we need to measure them. The kernel knows when executable code is loaded because the related file is memory-mapped by using the executable flag. However, the kernel cannot recognize kernel modules when they are loaded from the file system because they are loaded by applications such as modprobe or insmod and are memory-mapped as executable only after they have been loaded into in memory. Finally, the kernel does not know when executable scripts are loaded into interpreters such as bash because they are read as normal files.

Some other files loaded by the application itself also define its execution behavior. For example, the Java class files that define servlets and web services must be measured because they are loaded by the Tomcat server to create dynamic content, such as shopping cart or payment pages. Application configuration files, such as the startup files for Apache (httpd.conf) and Tomcat (startup scripts) may also alter the behavior of the Web server. These files in our example system include:

While each of these files may have standard contents that can be identified by the challenger, it is difficult to determine which files are actually being used by an application and for what purpose. Even if http.conf has the expected contents, it may not be loaded as expected. For example, Apache has a command line option to load a different file, links in the file system may result in a different file being loaded, and races are possible between when the file is measured and when it is loaded. Thus, a Tripwire-like [8] measurement of the key system files is not sufficient because the users of the attesting system (attestors) may change the files that actually determine its integrity, and these users are not necessarily trusted by the challengers. As in the dynamic loader case, the integrity impact of opening a file is only known to the requesting program. However, unlike the case for the dynamic loader, the problem of determining the integrity impact of application loads involves instrumentation of many more programs, and these may be of varying trust levels.

The integrity of the Web server environment also depends on dynamic, unstructured data that is consumed by running executables. The key issue is that even if the application knows that this data can impact its integrity, its measurement is useless because the challenger cannot predict values that would preserve integrity. In the web server example, the key dynamic data are: (1) the various kinds of requests from remote clients, administrators, and other servlets and (2) the database of book orders. The sorts of things that need to be determined are whether the order data or administrator commands can be modified only by high integrity programs (i.e., Biba) and whether the low integrity requests can be converted to high integrity data or rejected (i.e., Clark-Wilson). Sealed storage is insufficient to ensure the first property, information flow based on mandatory policy is necessary in general, and enforcement of the second property requires trusted upgraders or trust in the application itself.


next up previous
Next: Measuring Systems Up: Problem Statement Previous: Integrity Background
sailer 2004-05-18