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.