The increasing availability of network-based services and the growing popularity of mobile computing has resulted in an increased demand for execution ``sandboxes''--environments that support differentiated service and impose irrevocable restrictions on resource usage. For instance, the execution environment can ensure qualitative restrictions such as permitting an application component to only access certain portions of the file system (e.g., c:\temp), and quantitative restrictions such as limiting the component to 20% of CPU share. These qualitative and quantitative restrictions isolate the behavior of other activities on the system from a potentially malicious application component, and are desirable for the wider deployment of distributed component-based applications.
Existing approaches for enforcing qualitative and quantitative restrictions on resource usage rely on kernel support [JLDB95,MST94], binary modification [WLAG93], or active interception of the application's interactions with the operating system (OS) [BG99,ET99,GWTB96]. The kernel approaches are general-purpose but require extensive modifications to OS structure, limiting their applicability for expressing flexible resource control policies. The remainder of the approaches rely on deciding for each application interaction with the underlying system whether or not to permit this interaction to proceed; consequently, they provide qualitative restrictions (such as whether or not a file-reading operation should be allowed), but are unable to handle most kinds of quantitative restrictions, particularly since usage of some resources (e.g., the CPU) does not require explicit application requests.
This paper presents a user-level sandboxing approach for enforcing quantitative restrictions on application's resource usage. Our approach actively monitors the application's interactions with the underlying system, proactively controlling them to enforce the desired behavior. Our strategy recognizes that application access to system resources can be modeled as a sequence of requests spread out over time. These requests can be either implicit such as for a physical memory page, or explicit such as for disk access.1 This observation provides two alternatives for constraining resource utilization over a time window: either control the resources available to the application at the point of the request or control the time interval between resource requests. In both cases and for all kinds of resources, the specific control is influenced by the extent to which the application has exceeded or fallen behind a progress metric. The latter represents an estimate of the resource consumption of the application program.
For this approach, the primary challenge lies in accurately estimating the progress metric and effecting necessary control on resource requests with acceptable overhead. It might appear that appropriate monitoring and control would require extensive kernel involvement, restricting their applicability. Fortunately, most modern OSes provide a core set of user-level mechanisms that can be used to construct the required support. Presence of fine-grained timers and monitoring infrastructures such as the Windows NT Performance Counters and the UNIX /proc filesystem provides needed information for building accurate progress models. Similarly, fine-grained control can be effected using standard OS mechanisms such as debugger processes, priority-based scheduling, and page-based memory protection.
We describe the implementation of a sandbox using the above strategy to impose quantitative restrictions on three representative resources--CPU, memory, and network on Windows NT (The same approach has also been used to implement sandboxing on Linux). A detailed evaluation shows that our implementation is able to restrict resource usage of unmodified applications to within 3% of the prescribed limits with minimal run-time overhead. We also present a synthetic application that demonstrates the flexibility of a user-level sandbox. In this case, our approach permits application-specific control at fine granularity--over differentiated thread and socket groups.
The rest of this paper is organized as follows. Section 2 describes background and related work. Section 3 presents the overall sandboxing strategy and discusses its application for three example resource types: CPU, memory, and network. The concrete implementation of the sandbox on Windows NT is presented and evaluated in Section 4. Section 5 highlights the flexibility of user-level sandboxing, and we conclude in Section 6.
Next: Background and Related Work
Up: User-level Resource-constrained Sandboxing
Previous: User-level Resource-constrained Sandboxing