next up previous
Next: LSM Interface Up: Linux Security Module Framework Previous: Introduction


Design and Implementation

At the 2001 Linux Kernel Summit, the NSA presented their work on Security-Enhanced Linux (SELinux) [19], an implementation of a flexible access control architecture in the Linux kernel. Linus Torvalds appeared to accept that a general access control framework for the Linux kernel is needed. However, given the many Linux kernel security projects, and Linus' lack of expertise in sophisticated security policy, he preferred an approach that allowed security models to be implemented as loadable kernel modules. In fact, Linus' response provided the seeds of the LSM design. The LSM framework must be:

Figure 1: LSM Hook Architecture
\begin{figure*}
\begin{center}
\epsfxsize =4.5in
\epsfbox {design-picture}\end{center}\end{figure*}

To achieve these goals while remaining agnostic with respect to styles of access control mediation, LSM takes the approach of mediating access to the kernel's internal objects: tasks, inodes, open files, etc., as shown in Figure 1. User processes execute system calls, which first traverse the Linux kernel's existing logic for finding and allocating resources, performing error checking, and passing the classical UNIX discretionary access controls. Just before the kernel attempts to access the internal object, an LSM hook makes an out-call to the module posing the question, ``Is this access ok with you?'' The module processes this policy question and returns either ``yes'' or ``no.''

One might ask why LSM chose this approach rather than system call interposition (mediating system calls as they enter the kernel) or device mediation (mediating at access to physical devices).4 The reason is that information critical to sound security policy decisions is not available at those points. At the system call interface, userspace data, such as a path name, has yet to be translated to the kernel object it represents, such as an inode. Thus, system call interposition is both inefficient and prone to time-of-check-to-time-of-use (TOCTTOU) races [28,6]. At the device interface, some other critical information (such as the path name of the file to be accessed) has been thrown away. In between is where the full context of an access request can be seen, and where a fully informed access control decision can be made.

A subtle implication of the LSM architecture is that access control decisions are restrictive5: the module can really only say ``no'' [31]. Functional errors and classical security checks can result in an access request being denied before it is ever presented to the LSM module. This is the opposite of the way mandatory access control systems are normally implemented. This design choice limits the flexibility of the LSM framework, but substantially simplifies the impact of the LSM on the Linux kernel. To do otherwise would have required implementing many instances of the same hook throughout the kernel, to ensure that the module is consulted at every place where a system call could ``error out.''

Composition of LSM modules is another problematic issue. On the one hand, security policies do not compose in the general case because some policies may explicitly conflict [13]. On the other hand, it is clearly desirable to compose some combinations of security policies. Here, LSM effectively punts to the module writer: to be able to ``stack'' modules, the first module loaded must also export an LSM interface to subsequent LSM modules to be loaded. The first module is then responsible for composing the access control decisions that it gets back from secondary modules.


next up previous
Next: LSM Interface Up: Linux Security Module Framework Previous: Introduction
James Morris
2002-07-09