Introduction

Operating system security is fundamental to the security of every computing system because operating systems are a critical point of failure for the entire system. Unfortunately, attempts to secure computer systems continue to be based on the flawed assumption that adequate security can be provided in applications with the existing security mechanisms of mainstream operating systems. The reality is that secure applications require secure operating systems, and any effort to provide system security which ignores this premise is doomed to fail. The integration of Mandatory Access Control (MAC) is a necessary step in the complex task of building a completely secure operating system. It would significantly improve system security and enable protection from many vulnerabilities that plague systems today [14].

A general purpose MAC architecture needs the ability to enforce an administratively-set security policy over all subjects and objects in the system, basing decisions on labels containing a variety of security-relevant information. When properly implemented, it enables a system to adequately defend itself and offers critical support for application security by protecting against the tampering with, and bypassing of, secured applications. It allows critical processing pipelines to be established and guaranteed. MAC provides strong separation of applications that permits the safe execution of untrustworthy applications. Its ability to limit the privileges associated with executing processes limits the scope of potential damage that can result from the exploitation of vulnerabilities in applications and system services. MAC enables information to be protected from legitimate users with limited authorization as well as from authorized users who have unwittingly executed malicious applications. The ability for the system to do these types of things is necessary before the construction of secure systems will be possible.

It is impossible to obtain the benefits derived from MAC with existing Discretionary Access Controls (DAC) like those currently found in Unix systems. It is not adequate to base access decisions only on user identity and ownership. It must be possible to consider additional security-relevant criteria such as the role of the user, the function and trustworthiness of programs, or the sensitivity or integrity of the data. As long as users have complete discretion over objects, it will not be possible to control data flows or enforce a system-wide security policy.

Protection against malicious code is not possible using existing DAC mechanisms because every program executed by the user inherits all of the privileges associated with that user. Malicious programs are free to change the permissions associated with all of the user's objects, as well as disclose or alter the objects themselves. This problem is exacerbated by the fact that only two categories of users are supported, completely trusted administrators and completely untrusted ordinary users. Many system services and privileged programs must run with coarse-grained privileges that far exceed their requirements. A flaw in any one of these programs can be exploited to obtain complete system access.

Traditional MAC mechanisms have typically been too limiting to serve as a general security solution. They have tended to be too tightly coupled to a multi-level security (MLS) [5] policy which bases its access decisions on clearances for subjects and classifications for objects. This traditional approach is too limiting to meet many security requirements [6,7,8]. It provides poor support for data and application integrity, separation of duty, and least privilege requirements. It requires special trusted subjects that act outside of the access control model. It fails to tightly control the relationship between a subject and the code it executes. Thus, traditional MAC systems have limited ability to offer protection based on the function and trustworthiness of the code, to correctly manage permissions required for execution, and to minimize the likelihood of malicious code execution.

The Flask Architecture [17] was created as an attempt to serve as a general architecture for MAC. An important design goal was to provide flexible support for security policies, since no single MAC policy model is likely to satisfy everyone's security requirements. This goal was achieved by cleanly separating the security policy logic from the enforcement mechanism. Care was taken to ensure that well-defined policy interfaces were specified that could support the widest set of useful security policies. The architecture provides support for policy changes and allows security policies to be expressed naturally in terms that make sense to the particular security policy that is implemented. In addition, with the Flask architecture, the enforcement of the security policy can be transparent to applications because it is possible to define default security behavior.

Security-Enhanced Linux [13,12], or SELinux for short, is an application of the Flask architecture in the Linux operating system. MAC has been integrated into the major subsystems of the Linux kernel, including fine-grained controls for operations on processes, files, and sockets. The security policy decision logic has been encapsulated into a new kernel component called the Security Server (SS) which makes labeling, access and polyinstantiation decisions in response to policy-independent requests that have been placed throughout the kernel. This architecture enables the kernel to enforce policy decisions without needing access to the details of the policy.

The SS implemented for SELinux was designed with a particular model of MAC selected to address the limitations of traditional MAC implementations. Because of the flexibility of the Flask architecture, this model is easily modified, or even replaced, to support other models as well. In general, this will not be necessary because the SS released with SELinux is capable of supporting many security policies that meet a wide variety of security objectives. It achieves significant policy flexibility using configuration files to define security policies that are easily tailored to meet specific installation needs.

The remainder of this paper is a discussion of how SELinux with its current SS implementation can be used to dramatically increase the level of security possible in a Linux system. It begins with a description of the model of security that the current SS implements. It is then shown how SELinux was used to meet some general security objectives. The paper ends with a short discussion of related work and some concluding remarks.