This chapter is an overview of the SELinux architecture, building upon what
was discussed in Section 1 What Is SELinux?. The technical
information you learn here helps you accomplish your goals in an SELinux
environment. This chapter discusses the interaction of SELinux policy, the
kernel, and the rest of the OS. Chapter 2 SELinux Policy Overview
provides a more detailed look into the policy itself.
For a history of SELinux and the Flask architecture, read
Appendix A Brief Background and History of SELinux.
Flask was developed to work through some of the inherent problems with a
MAC architecture. Traditional MAC is closely integrated with the
multi-level security (MLS) model.
Access decisions in MLS are based on clearances for subjects and
classifications for objects, with the objective of no read-up,
no write-down .
This provides a very static lattice that allows the system to decide by a
subject's security clearance level which objects can be read and written
to. The focus of the MLS architecture is entirely on maintaining
confidentiality.
The inflexible aspect of this kind of MAC is the focus on confidentiality.
The MLS system does not care about integrity of data, least privilege, or
separating processes and objects by their duty, and has no mechanisms for
controlling these security needs. MLS is a mechanism for maintaining
confidentiality of files on the system, by making sure that unauthorized
users cannot read from or write to them.
Flask solves the inflexibility of MLS-based MAC by separating the policy
enforcement from the policy logic, which is also known as the
security server. In traditional Flask, the
security server holds the security policy logic, handling the
interpretation of security contexts. Security
contexts or labels are the set of security
attributes associated with a process or an object. Such security labels
have the format of
<user>:<role>:<type>,
for example,
system_u:object_r:httpd_exec_t. The
SELinux user system_u is a standard
identity used for daemons. The role
object_r is the role for system objects
such as files and devices. The type
httpd_exec_t is the type applied to the
httpd executable /usr/sbin/httpd. The label
elements user, role, and type are explained in Section 2.10 SELinux Users and Roles and Section 2.7 TE Rules - Types.
Prior to full integration with the Linux kernel, security contexts were
maintained separately in a file as a set of security
identifiers or SIDs.
Part of the change when moving to the Linux 2.6.x kernel is the usage
of extended attributes (EAs) in the file system. SIDs
are not entirely retired, but they are no longer exported to userspace
from the kernel. For example, the kernel has some initial SIDs used by
init during bootstrapping before the policy is loaded.
In addition, libselinux provides a userspace SID
abstraction for applications that enforce policy, such as
dbus-daemon and nscd. Otherwise,
users and other programs only interact with security contexts. To
minimize confusion, from here forward in this guide, the term
security context is used to include the SID.
The security server need only do a look-up with a pair of contexts on a
matrix of type-labeled subjects and objects, and the result is put in the
access vector cache
(AVC) for retrieval on subsequent
matching requests.
By adding in a generalized form of TE that is separated into its own
security subsystem, Flask can be flexible in labeling for transition and
access decisions. Instead of being tied to a rigidly defined lattice of
relationships, Flask can define other labels based on user identity
(UID), role attributes, domain or type attributes, MLS
levels, and so forth.
Similarly, access decision computations can be made using multiple methods
in the same decision. These methods could be lattice models, static
matrix lookups, historical decisions, environmental decisions, or policy
logic obtained in real time. These computations are all handled by the
policy engine and cached, leaving the policy enforcement code available to
handle requests.
One other Flask flexibility is that any of these subsystems can be swapped
out for a new or different system, and none of the other systems are even
aware of the change. The abstraction between policy enforcement and
policy decision-making is what makes this possible. This flexibility
gives Red Hat Enterprise Linux developers the control they need to make the best
architecture decisions without being tied to a particular subsystem.
Figure 1-1 describes the Flask architecture, showing
the process of an operation. In this operation, standard DAC has occurred,
which means the subject already has gained access to the object via
regular Linux file permissions based on the UID. The operation can be anything: reading from or writing to a
file/device, transitioning a process from one type to another type,
opening a socket for an operation, delivering a signal call, and so forth.
A subject, which is a process, attempts to perform an operation on
an object, such as a file, device, process, or socket.
The policy enforcement server gathers the security context from
the subject and object, and sends the pair of labels to the security
server, which is responsible for policy decision making.
The policy server first checks the AVC, and returns a decision to
the enforcement server.
If the AVC does not have a policy decision cached, it turns to the
security server, which uses the binary policy that is loaded into the
kernel during initialization. The AVC caches the decision, and
returns the decision to the enforcement server, that is, the kernel.
If the policy permits the subject to perform the desired operation
on the object, the operation is allowed to proceed.
If the policy does not permit the subject to perform the desired
operation, the action is denied, and one or more avc:
denied messages are logged to $AUDIT_LOG, which is
typically /var/log/messages in Red Hat Enterprise Linux.
With the security server handling the policy decision making, the
enforcement server handles the rest of the tasks. In this role, you can
think of the enforcement code as being an object
manager. Object management includes labeling objects with a
security context, managing object labels in memory, and managing client
and server labeling.