On its face, SELinux offers a number of attractive capabilities. It
enables a Linux system to be partitioned into lots of little realms
("domains" or "types") with fine-grained control over the capabilities of
each realm. For example, the
named DNS server can be empowered to bind to the
DNS ports (but no others), write to its log and cache files (but no
others), and read from its configuration files (but from nowhere else). It
can read random numbers, but cannot access any other device files. And so
on. The end result is that, even if named falls to a remote code exploit,
there is very little that exploit can actually do. A vulnerability which,
on a current Linux system, could lead to a full system compromise is
limited to a denial of service problem, or, at worst, the provision of
bogus DNS information.
This promise is worth something. Currently, any sort of compromise of any
daemon on the system has a good chance of being escalated to full control
of the system itself. SELinux cannot prevent security holes in server
processes, but it does have the potential to strictly limit the damage
which can be done by exploiting those holes. SELinux could be the
mechanism which turns Linux into the most secure widely-used operating
system on the planet.
The only problem is that getting there could be a challenge, and, along the
way, we risk turning Linux into a system we no longer wish to use.
Like all good kernel code, SELinux does not, itself, contain a security
policy. That policy, instead, is defined by the system administrator and
loaded from user space. Defining that policy, however, is not the
easiest thing to do. The book SELinux: NSA's Open Source Security
Enhanced Linux, just reviewed by LWN,
notes that a typical set of policy files contains some 250,000 lines of
code. More to the point:
The SELinux source policy is a sophisticated software system. It
includes dozens of object classes, scores of defined permissions,
more than 1,000 type transitions, thousands of object instances,
and tens of thousands of access-vector rules.
As an aside, all of this code is written in a language which, as of this
writing, probably has no more than a few dozen expert authors. So a couple
of questions come immediately to mind: how is it possible for anybody to
truly understand a system's security policy, and how can that policy be
shown to be correct? Complexity and obscurity are enemies of security, and
SELinux has large amounts of both.
There are complications. Installing a new program on a full-blown SELinux
system required updating the security policy. There has been talk of a day
when applications are routinely shipped with SELinux policy files, just
like they currently contain makefiles. But that talk assumes that large
numbers of application developers will learn the SELinux policy language
well enough to write a secure policy for their code. It assumes that
system administrators will understand those files well enough to decide
whether they are safe to install. In an SELinux world, malicious policy
files may become a required part of any self-respecting trojan horse;
vigilance will be required.
Perhaps the biggest problem, though, is the assumption that a single policy
file will fit into the security policies running on systems worldwide. If
everybody ends up with a single, uniform security policy derived from the
SELinux sample policy, that assumption might hold. But how can a single
security policy make sense for all situations? The sheer difficulty of
creating a radically different policy will likely keep experimentation to a
minimum, but there will inevitably be pressure for different policies for
different situations. In the future, we may see new offshoot distributions
which differ mainly in their SELinux policies. Divergent security policies
will be good for user choice, and the diversity may be good for the
security of the net in general. But they will make it hard to write a
portable application policy file.
SELinux depends on "labels" applied to almost all files on the system.
Those labels define the type(s) of the files, and, thus, who can access
them, and in which way. These labels are also a crucial part of the domain
system which allows the isolation of specific daemons and utilities.
Maintaining the integrity of these labels proves to be a challenge,
however. Consider this warning from the SELinux book:
If you use vipw, vi, or some other means to
modify /etc/passwd, /etc/group, or
/etc/shadow, you'll likely remove the security context
labeling [from] the file, which will make the file inaccessible.
Relabeling files is something every SELinux administrator needs to know how
to do. The Fedora boot process checks for labeling problems, and, when
they are found, it automatically relabels things. Relabeling is a fact of
life in the SELinux world.
It turns out that the proper labels are stored in the SELinux
policy; what's on the files themselves can be thought of as a sort of
cached version. In other words, SELinux has imposed a new file permissions
scheme which is maintained outside of the kernel. If the files are
manipulated by non-aware applications, or by way of a non-SELinux kernel,
those permissions will become unsynchronized. Applications installed by
the administrator will have labeling problems of their own.
The end result is that SELinux could lead to systems which are too complex
to administer, which have a single security policy created by the
distributor, and which are highly resistant to the installation of software
not provided by the distributor - or to changes in general. That is not a
world which most of us would
like to live in; we should think carefully before we run too quickly in
that direction.
Of course, that is a worst case scenario, and the Linux community is
unlikely to let things get that bad. Some steps have already been taken in
the right direction. The Fedora Project's decision to fall back to a
"targeted" mode, where SELinux only applies to certain system daemons, is a
good start. The targeted mode reduces the complexity of the security
policy and makes experimentation easier. Fedora has also introduced
"policy booleans" to the mix. These booleans are runtime variables which
provide (relatively) high-level control over the system's security policy.
Booleans in Fedora Core 3 control whether Apache can run CGI programs
or read home directories, whether yellow pages can be used, and more.
The booleans point in an important direction. Perhaps part of the real
problem with SELinux is that policies must be written in the equivalent of
assembly language. Most programmers do not want to worry about individual
register assignments, and most system administrators would rather not deal
with domain transitions and access vectors. If, in some future day, a
system's security policy can be specified with, at most, a few hundred
lines of high-level declarations, that policy may just be manageable. If
that can be done, SELinux might just be the answer to a lot of our security
worries.
(See also: this
just-released, beta Fedora document which describes what is involved in
using SELinux to control Apache).
(
Log in to post comments)