Loading learning content...
In traditional Unix and Linux systems, resource access is governed by a simple principle: the owner decides. If you own a file, you choose who can read, write, or execute it. This model—called Discretionary Access Control (DAC)—has served computing well for decades. But it carries a fundamental flaw that has enabled countless security breaches.
The flaw is this: DAC trusts users to make correct security decisions. When a user runs a program, that program inherits the user's permissions. A web browser can read your private SSH keys. A text editor can transmit your documents to the internet. A malicious attachment can access everything you can access. There's no separation between what you are allowed to do and what programs running as you should be allowed to do.
Mandatory Access Control (MAC) fundamentally changes this paradigm. Under MAC, the operating system—not the user—makes access decisions based on security policies that cannot be overridden by individual users or programs. Even if you own a file, the system can prevent your applications from accessing it. This creates layers of defense that limit damage even when software is compromised.
By the end of this page, you will understand the fundamental principles of Mandatory Access Control, how it differs from DAC, the security models that underpin MAC implementations, and why MAC is essential for achieving true defense-in-depth security. You'll see how MAC transforms the security posture of systems from 'trust everything the user does' to 'verify every access according to policy'.
To appreciate MAC, we must first understand why DAC is insufficient for high-security environments. Discretionary Access Control, the default model in Unix/Linux (and Windows), is built on these principles:
This model works reasonably well when users run trusted software in trusted environments. But modern computing doesn't look like that.
A 'confused deputy' is a legitimate program tricked into misusing its authority. When you browse the web, your browser has access to your files, network, and system resources. A malicious webpage exploiting a browser vulnerability becomes a confused deputy—using the browser's legitimate access rights for illegitimate purposes. DAC cannot prevent this because the browser is running as you.
Consider these attack scenarios that DAC cannot prevent:
Scenario 1: Web Application Compromise
A web server runs as user www-data. An attacker exploits a vulnerability in the web application. Under DAC, the attacker now has access to everything www-data can access—potentially the entire document root, configuration files, database credentials, and more.
Scenario 2: Email Attachment Attack A user opens a malicious PDF. The PDF reader, running with the user's full permissions, executes embedded code. That code can now read the user's SSH keys, browser cookies, and any file the user owns—all without triggering any access control violation.
Scenario 3: Privilege Escalation A daemon runs as root (common in legacy software). Any vulnerability in that daemon gives the attacker complete system control. DAC offers no middle ground between 'powerless' and 'omnipotent'.
Scenario 4: Insider Threat A disgruntled employee copies sensitive company data to a USB drive. Since they're the owner of their home directory contents, DAC permits this—the data is 'theirs' to share.
| Attack Vector | DAC Weakness | Potential Damage |
|---|---|---|
| Browser exploit | Browser runs with user's full permissions | Complete user account compromise |
| Server-side injection | Web processes access all web user files | Database breach, lateral movement |
| Supply chain attack | Installed packages inherit installer's rights | Persistent backdoor access |
| Malicious document | Viewers inherit reader's permissions | Data exfiltration, ransomware |
| Compromised daemon | Root daemons have unlimited access | Complete system compromise |
The fundamental issue is that DAC conflates identity with authorization. Being user alice is sufficient authorization for any action alice is permitted to take. There's no concept of 'this program is alice, but should only access web-related files' or 'this process runs as root but should only manage network interfaces'.
MAC provides exactly this capability—the ability to restrict what programs can do regardless of who runs them.
Mandatory Access Control inverts the control relationship. Instead of owners deciding access, the system administrator (or security officer) defines policies that the operating system kernel enforces unconditionally. These policies cannot be modified by users or programs—they are 'mandatory.'
Principle 1: Centralized Policy Authority Access decisions are made according to a central security policy, not by individual resource owners. The policy defines what subjects (processes) can access what objects (files, sockets, devices) and how.
Principle 2: Policy Enforcement in the Kernel The kernel enforces MAC decisions. They cannot be bypassed by user-space code, regardless of privilege level. Even root must obey MAC policies (though root can modify policies in most implementations).
Principle 3: Least Privilege by Default MAC policies typically start from a 'deny all' stance. Access must be explicitly granted by policy. This is the opposite of DAC, where access is typically 'permit unless denied.'
Principle 4: Separation of Domains Programs and processes are assigned to security domains (or types, labels, compartments). Access rules are defined between domains, not between users and files. This enables fine-grained control over program behavior.
In real systems, MAC doesn't replace DAC—it adds an additional layer. Linux first checks DAC permissions (traditional Unix permissions). If DAC permits access, MAC is then consulted. Access is only granted if both DAC and MAC permit it. This is defense in depth: multiple independent security layers.
MAC implementations are grounded in formal security models developed over decades. These models provide mathematical frameworks for reasoning about information flow and access control. Understanding them illuminates why MAC systems work the way they do.
Developed in the 1970s for military systems, Bell-LaPadula focuses on confidentiality—preventing unauthorized information disclosure. It introduces the concept of security levels (e.g., Unclassified, Secret, Top Secret) and enforces two rules:
Simple Security Property (No Read Up)
A subject cannot read an object at a higher security level.
A user with Secret clearance cannot read Top Secret documents. This prevents information from flowing from high to low.
Star Property (No Write Down)
A subject cannot write to an object at a lower security level.
A process handling Top Secret data cannot write to Secret or Unclassified files. This prevents high-clearance subjects from leaking information—even accidentally.
Together, these rules ensure that information can only flow upward in the security hierarchy, never downward. This is called a lattice-based security model.
Security Levels: TOP SECRET ↑ SECRET ↑ CONFIDENTIAL ↑ UNCLASSIFIED Bell-LaPadula Rules:┌─────────────────────────────────────────────────────────────┐│ READ: Subject can read objects at SAME or LOWER level ││ (No Read Up) ││ ││ WRITE: Subject can write objects at SAME or HIGHER level ││ (No Write Down) │└─────────────────────────────────────────────────────────────┘ Example: - SECRET user CAN read CONFIDENTIAL file ✓ - SECRET user CANNOT read TOP SECRET file ✗ - SECRET user CAN write to TOP SECRET file ✓ - SECRET user CANNOT write to UNCLASSIFIED ✗While Bell-LaPadula protects confidentiality, the Biba Model protects integrity—ensuring that data is not modified by unauthorized or less-trusted sources. It inverts the Bell-LaPadula rules:
Simple Integrity Property (No Write Up)
A subject cannot write to an object at a higher integrity level.
Untrusted code cannot modify trusted system files. A web browser cannot rewrite kernel configuration.
Integrity Star Property (No Read Down)
A subject cannot read an object at a lower integrity level.
This prevents trusted processes from being 'contaminated' by untrusted data. A security-critical program shouldn't read data from an untrusted source.
Biba ensures that low-integrity data cannot corrupt high-integrity resources.
Beyond lattice-based models, Domain and Type Enforcement takes a different approach. Instead of ordering subjects and objects by security levels, DTE:
DTE is the foundation for SELinux's Type Enforcement (TE) system. It's more flexible than Bell-LaPadula/Biba because:
The significant advantage of DTE/TE is that it confines applications to precisely the resources they need—the principle of least privilege implemented at a granular level.
| Model | Primary Goal | Core Mechanism | Use Case |
|---|---|---|---|
| Bell-LaPadula | Confidentiality | Security levels, no read up/write down | Military, classified data |
| Biba | Integrity | Integrity levels, no write up/read down | Financial systems, critical infrastructure |
| Domain/Type Enforcement | Confinement | Domains, types, explicit access rules | General-purpose OS security (SELinux) |
| Multi-Level Security (MLS) | Both | Combined levels and compartments | Cross-domain systems |
| Multi-Category Security (MCS) | Isolation | Categories as virtual compartments | Container/VM isolation |
MAC enforcement occurs at the boundary between user-space and kernel-space. Every time a process requests an operation—opening a file, establishing a network connection, executing a program—the kernel mediates that request. MAC systems hook into this mediation point.
Linux implements MAC through the Linux Security Modules (LSM) framework. LSM provides security hooks—callback points in the kernel where security modules can make access decisions. These hooks are placed at strategic locations:
When any of these operations occur, the kernel calls the registered security module(s) to decide whether to permit or deny the operation.
1234567891011121314151617181920212223242526272829
// Simplified view of LSM hook invocation during file open int vfs_open(const struct path *path, struct file *file){ int error; // 1. Standard permission checks (DAC) error = inode_permission(path->dentry->d_inode, MAY_READ); if (error) return error; // 2. LSM/MAC permission check // This is where SELinux, AppArmor, etc. intercede error = security_file_open(file); if (error) return error; // MAC denies access! // 3. If both checks pass, proceed with open return do_dentry_open(file, path);} // The security_file_open() function calls all registered LSM modulesint security_file_open(struct file *file){ // Calls each LSM's file_open hook // SELinux checks: Does the process domain have permission // to open this file type with these flags? return call_int_hook(file_open, 0, file);}When a MAC-enabled system processes an access request:
Context Retrieval — The kernel retrieves the security context of the subject (process) and the object (file, socket, etc.)
Policy Lookup — The MAC module queries the loaded policy to find rules matching this subject-object pair and the requested operation
Decision Computation — Based on the policy rules, the module computes ALLOW or DENY
Audit Logging — The decision is logged for security monitoring (especially denials)
Enforcement — If denied, the kernel returns an error (typically EACCES or EPERM). If allowed, the operation proceeds.
This process is remarkably fast—SELinux is engineered to make decisions in microseconds using optimized data structures (Access Vector Cache).
Early MAC implementations were criticized for performance overhead. SELinux addresses this with the Access Vector Cache (AVC), which caches previous access decisions. Most access checks hit the cache and complete in less than a microsecond. Only novel access patterns require full policy evaluation.
Every MAC system relies on labels (also called contexts or security attributes) attached to subjects and objects. Labels are metadata that persist with the resource and travel with it. In SELinux, a label looks like:
user:role:type:level
For example:
The policy then contains rules like:
httpd_tcan readhttpd_content_tbut cannot write toetc_t
This labeling scheme is what enables fine-grained, program-specific access control. Each application has its own domain (type), and rules specify exactly what that domain can access.
MAC's theoretical foundation translates into concrete security improvements. Let's examine how MAC defends against real attacks:
Without MAC (DAC only):
www-data userWith MAC (SELinux enabled):
httpd_t domainAndroid uses SELinux extensively. Every app runs in its own SELinux domain with a unique type label. Consider what this means:
This is why Android malware, when it exists, typically exploits weaknesses in specific app permissions rather than gaining unrestricted system access. The MAC layer contains the blast radius.
In 2014, the Shellshock bug allowed remote command execution via Bash. On SELinux-protected systems, attackers who exploited Shellshock through Apache found their shells confined to httpd_t—unable to access most of the system. SELinux turned a critical vulnerability into a contained incident.
Several MAC implementations exist across operating systems, each with different design philosophies and use cases:
Developed by the NSA and contributed to the Linux kernel in 2000, SELinux is the most feature-complete MAC implementation:
SELinux is used by Red Hat/CentOS/Fedora, Android, and many security-conscious deployments.
Developed by Novell (now Canonical-maintained), AppArmor takes a simpler approach:
AppArmor is default on Ubuntu and SUSE distributions.
| Feature | SELinux | AppArmor | Smack |
|---|---|---|---|
| Labeling | Persistent inode labels | Path-based profiles | Simple labels |
| Complexity | High (comprehensive) | Medium (approachable) | Low (minimal) |
| Flexibility | Very high | Moderate | Low |
| Learning Curve | Steep | Moderate | Easy |
| Network Control | Full control | Limited | Basic |
| Default Distro | RHEL, Fedora | Ubuntu, SUSE | Embedded systems |
| Android Use | Yes (primary MAC) | No | No |
The rest of this module focuses on SELinux because it represents the most complete and widely deployed MAC implementation. Understanding SELinux provides concepts transferable to other MAC systems. If you grasp SELinux's type enforcement, you'll find AppArmor and others straightforward.
MAC provides powerful security guarantees, but adoption comes with challenges that organizations must address:
Writing MAC policies is hard. A comprehensive SELinux policy contains tens of thousands of rules. Understanding what rules are needed—and what unintended effects changes may have—requires expertise.
Mitigation: Use reference policies, policy modules, and tools like audit2allow (while understanding their security implications).
Overly restrictive policies break legitimate functionality. Users experience denials as 'things not working' without understanding why. This leads to the infamous advice: 'just disable SELinux.'
Mitigation: Thorough testing, permissive mode during development, comprehensive audit logging, and gradual rollout.
Every file and process must have the correct label. File operations that don't preserve labels (e.g., cp vs mv) can cause labeling inconsistencies.
Mitigation: Regular restorecon runs, file context policies, and consistent use of MAC-aware tools.
As software evolves, policies must evolve. New programs need new domains. Updated software may need additional permissions.
Mitigation: Policy modularization, regular policy updates from distribution maintainers, and organizational policy governance.
When faced with unexplained denials, administrators often disable SELinux entirely. This trades comprehensive security for short-term convenience. The proper response is to diagnose the denial (using audit logs), understand what access is needed, and update policy appropriately. Disabling SELinux to 'make things work' is surrendering your security perimeter.
MAC requires a security-conscious culture. Developers must understand that their software will be confined. Operations must maintain policy alongside software. Security teams must govern policy changes.
Organizations that treat security as a checkbox rather than a process will struggle with MAC. Those that integrate security into development and operations will find MAC a powerful ally.
We've established the foundation for understanding Mandatory Access Control. Let's consolidate the key insights:
What's Next:
Now that you understand the principles of Mandatory Access Control, we'll dive into SELinux specifically. The next page examines SELinux Policies—the rule systems that define what's permitted, how policies are structured, and how to work with the reference policy framework.
You now understand why MAC exists, what security problems it solves, the formal models that underpin it, and how it's enforced in Linux. This foundation is essential for understanding SELinux's architecture in the pages ahead.