Role of SELinux in Linux Mandatory Access Control
Security-Enhanced Linux (SELinux) is a security architecture embedded within the Linux kernel that provides a robust mechanism for enforcing Mandatory Access Control (MAC). This article examines the function of SELinux in Linux environments, detailing how it replaces standard user-managed permissions with centralized, policy-driven controls. It covers the limitations of standard access models, the core architecture of SELinux—including security contexts and type enforcement—and how these mechanisms prevent privilege escalation and contain system compromises.
The Limitation of Discretionary Access Control (DAC)
Traditional Linux security relies on Discretionary Access Control (DAC). Under DAC, access to files, directories, and devices is determined by ownership: individual users own resources and assign read, write, and execute permissions.
The primary vulnerability of DAC is its reliance on user privilege.
If a malicious actor compromises a process running under the
root account or the user owning a specific file, that actor
inherits full control over the associated resources. DAC cannot restrict
a compromised process from performing actions that its user ID is
authorized to perform, leading to widespread lateral movement and system
compromise.
How SELinux Enforces Mandatory Access Control (MAC)
SELinux addresses DAC vulnerabilities by enforcing Mandatory Access Control (MAC) through the Linux Security Modules (LSM) framework. Under MAC, access rights are determined centrally by a strict security policy rather than by the discretion of individual users.
Even if a process runs with root privileges under DAC,
it must still satisfy the rules defined in the active SELinux policy. If
the policy does not explicitly permit an operation, the Linux kernel
denies access, logs the event, and protects the underlying system.
Security Labels and Contexts
SELinux manages access through labels called security contexts, applied to both subjects (processes) and objects (files, sockets, ports, and directories). A security context follows a standard format:
user:role:type:level
- User (
user): An SELinux user identity mapped to one or more Linux accounts. - Role (
role): Defines which types of processes an SELinux user can access. - Type (
type): The primary mechanism for enforcement, referred to as Type Enforcement (TE). For files, it defines the resource's type; for processes, it defines the running domain. - Level (
level): An optional attribute used in Multi-Level Security (MLS) and Multi-Category Security (MCS) to handle sensitivity ratings (such as classified tiers).
Type Enforcement (TE)
Type Enforcement is the primary method SELinux uses to enforce MAC. In a Type Enforcement model, rules specify exactly which process domains can interact with which file types.
For example, a web server process might run in the
httpd_t domain, while its static files are labeled with the
httpd_sys_content_t type. The SELinux policy contains an
explicit rule allowing httpd_t to read
httpd_sys_content_t. If an attacker exploits a
vulnerability in the web server and attempts to read
/etc/shadow (labeled shadow_t), the kernel
immediately denies the request because no rule exists permitting
httpd_t to read shadow_t, regardless of the
web server's execution privileges.
The Decision-Making Process: Policy Engine and AVC
When an operation occurs on a Linux system with SELinux enabled, the process executes as follows:
- DAC Verification: The standard Linux DAC checks run first. If DAC denies access, the operation is blocked immediately.
- Policy Evaluation: If DAC grants access, the request moves to the SELinux subsystem in the kernel.
- Access Vector Cache (AVC): To avoid performance degradation from constantly evaluating rules, SELinux checks the Access Vector Cache for previously computed decisions.
- Policy Engine Query: If the decision is not cached, the request is evaluated against the loaded security policy.
- Enforcement and Logging: The action is either
allowed or denied. Denied operations are logged to audit files (such as
/var/log/audit/audit.log) for administrative review.
Operating Modes of SELinux
SELinux operates in one of three modes:
- Enforcing: The default state where policies are strictly applied, unauthorized actions are blocked, and violations are logged.
- Permissive: SELinux does not block actions, but it logs violations that would have been denied in Enforcing mode. This mode is primarily used for troubleshooting and policy development.
- Disabled: The SELinux framework is completely turned off, reverting the system solely to DAC.
System Isolation and Blast-Radius Reduction
The ultimate role of SELinux in a Linux environment is containment. By enforcing Mandatory Access Control, SELinux adheres to the principle of least privilege at the system level. Vulnerabilities in individual applications, services, or daemon processes are constrained to their defined operational domains, preventing adversaries from escalating privileges, tampering with foreign data, or establishing persistence across the wider operating system.