SELinux has been through several iterations as part of the process of being
incorporated into the Linux kernel. During this time, the overall
architecture has remained the same, but many of the programmatic details
have changed. Some of the reasons for change were: requirements for
upstream acceptance; changes in LSM as part of being accepted into the
kernel; and the switch to using xattrs.
As one example of the changes between kernel versions, originally security
context was maintained through a mapping from context to SID, and managed
by the security server. In the 2.6.x Linux kernel, the security
context for a file is stored in the xattrs, allowing it to carry around
its own SELinux context.
As an implementation of the Flask architecture, SELinux also served as a
reference implementation of LSM. Originally LSM and SELinux were patches to
the 2.4.<x> series of kernels; SELinux was
never able to work as a loadable security module. Therefore, a big part
of gaining upstream acceptance into the mainline Linux kernel required
everything from fixing coding practices to changing how SELinux interacted
with the kernel.
Part of the SELinux development team was also instrumental in designing,
building, and integrating LSM into the kernel. SELinux integration into the
kernel was the motivation to start the LSM project. SELinux was an early
proof of the ability of LSM to allow security-enhancements to be connected
into, instead of strapped onto, the Linux kernel. Originally, SELinux was a
loadable module, but it became statically compiled into the 2.6.x
kernel. It is still an LSM module, using the LSM hooks in the kernel to
control and label. Because of the abstraction layer provided by both the
LSM and Flask frameworks, SELinux is highly configurable and modifiable.
Flask is flexible enough to work in many different environments, and Linux
is a natural fit for the Flask model. Access to the kernel source and a
willing, community-driven development process allow for the best
modification to fully support Flask's objectives. The wide range of
platforms Linux runs on means SELinux is extensively tested. The consensus
process of getting SELinux integrated into the kernel has improved the code
and practices. Now that it is integrated, it has a better chance of
long-term success than security-enhancement models that are strapped
on-top of the operating system.
There are a few more differences in the specific way SELinux implements
Flask in the Linux kernel, compared to traditional Flask methodology and
initial SELinux creation:
Under traditional TE, there is a distinction between types and
domains. A type is the security context for a file object, and a
domain is the security context for a process. In the SELinux
implementation, there is no real distinction programmatically. In
SELinux, domains are processes that have the
process, so the term domain is used
in the traditional way. Similarly, the term type is mostly applied to
object types, but it can mean both domains and types.
The term security server is still used for the sake of clarity,
but it is no longer a stand-alone service. The security server, the
AVC, and the policy engine are now all parts of the kernel.