Least Privilege Enforcement through Secure Memory Views

Research Areas: End System Security

Principal Investigator: Patrick Eugster

Application architectures involving components, plugins, and mashups are becoming increasingly prevalent in today’s complex computer systems. Nn-monolithic applications often host and execute untrusted code obtained from various third parties. For example, web browsers simultaneously host web applications and components written in JavaScript, Flash, HTML5, or “native” plugins (e.g., ActiveX) downloaded from different domains. Security requires isolation to be provided between both the host application (e.g., web browser) and the components as well as between the components themselves. Differing instances of the same plugin must also be isolated from each other in some cases. In most cases, rather than being fully isolated, these components need to be able to communicate with the host application and with each other in structured, controlled ways. For example, JavaScript can control Flash scripts running on a web page and vice-versa. These architectures and isolation requirements also exist in applications written in heap-safe languages, such as JBoss, a J2EE application container written in Java.
Additionally, many applications (or sub-components) continue to be developed in lower-level languages that allow unsafe manipulation of the heap (e.g., pointer arithmetic). This gives rise to a significant number of application exploits, including many “zero-day” exploits. Other types of exploits are also possible even in “heap-safe” languages, such as input validation exploits, where existing functionality within the application is leveraged in unexpected ways to produce malicious behavior. 
Efficient and secure implementation of plugin-based architectures and the need to guard against malicious application manipulation are both tied to a common denominator: the ability to divide a program, and more importantly the data manipulated by that program, into fine-grained “domains” and then to programmatically model the allowed interactions between these fine-grained domains with precision. Such an ability naturally allows relationships between plugin components to be defined and securely enforced. 
We propose practical fine-grained least privilege enforcement through the following three-fold strategy. First, the heap can be divided into a dynamic number of memory domains. Second, security contexts termed secure memory views (SMVs) can be defined that map privileges of code executing within them onto memory domains. Third, threads are allowed to dynamically switch their set of privileges (i.e., switching which SMV the thread is bound to) following a secure and controlled fashion, termed security context switching. These switches happen at carefully defined points termed secure call sites. Allowing threads to switch their set of privileges in a controlled fashion allows certain pieces of execution to be partially or fully isolated from the rest of the application. For example, in the case of a web browser, each tab may operate independently on its own thread, but many different sub-components may execute on that same thread for a particular tab.
More specifically, this project pursues the following three goals:
1. First, the proposed concepts of secure memory views, memory domains, and security context switching need to be explored in detailed. It is crucial that enough flexibility is given to the application programmer to easily apply the proposed techniques to existing and new applications, while also providing enough structure so as to be secure at runtime. Additionally, different types of secure calls will be needed, including upcalls (decreasing privileges), downcalls (increasing privileges), and crosscalls (neither the old or new set of privileges is a subset of the other). This initiative involves exploring the most effective definitions of these concepts, modeling these concepts in a formal language framework, and studying the resulting theoretical properties.
2. With the formal concept defined, many details must be worked out as to how to reify the new concepts within a modern mainstream programming language, such as Java. This includes development of a compiler supporting the language extensions, as well as modifying the supporting language runtime. The language runtime will need to cooperate closely with the new kernel-level services provided by the system support.
3. Efficient implementation of security context switching will require extensive support in both the language runtime and the operating system kernel itself. This includes automatic privilege changes upon calls of application-level functions, proper marshaling of arguments and return values, and cache-friendly memory privilege modifications. Existing mandatory access control mechanisms in the kernel (e.g., SELinux) would need to be modified to have different security contexts for each secure memory view, so that constraints on OS resources and system calls could be enforced through security context switching (and not just memory privileges).
Security context switching will also facilitate simplification of architectures that use multiple processes and inter-process communication to accomplish component isolation, as everything can be brought back into a single process or even single thread as appropriate. Implementation of security context switching will additionally lay a foundation for a fundamental shift in the design of modern operating system kernels, where there are arbitrary levels of isolation, rather than just two – “kernel-space” and “user-space.”


Students: Kevin John Hoffman Ching-Hsiang (Terry) Hsu

Representative Publications

  • K. Hoffman, H. Metzger, P. Eugster. 
    Ribbons: a Partially Shared Memory Programming Model
    ACM Conf. on Object Oriented Programming Systems Languages and Applications

Keywords: access control, browser, operating system, policy, zero-day