This models Mandatory Access Control (MAC) as implemented by SELinux Type Enforcement (and, with a slightly different rule syntax, AppArmor profiles), rendered as a real, independently-evaluated 2D policy engine — genuinely separate from the Discretionary Access Control (DAC) check every Unix file already carries:
DAC: decision = allowed by owner/group/other rwx bits on the resource
MAC: decision(s, o, a) = ALLOW if (type(s), type(o), a) ∈ R
= DENY otherwise (default-deny)
Real kernel order: final = DAC-allow AND MAC-allow
A DAC allow can never override a MAC deny — that is the whole point of "mandatory".
R is the compiled policy ruleset, shown above as a real editable table: toggle any rule between allow/deny, remove it, or add a brand-new (source, target, permission) triple. Any combination with no matching row is denied by default — the opposite of a blocklist firewall model. The DAC panel above it runs a completely separate simulated Unix permission check (owner, group, mode bits) on the same resource, so you can see both verdicts side by side.
- Load compromised-httpd/shadow demo — pre-selects a compromised web-server process against
shadow_t with permission bits that would technically let it read the file (DAC allow), and shows the policy table still has no matching allow rule for that source/target pair, so MAC denies it — the canonical "MAC contains what DAC permission bits alone would not" case.
- Inject compromised process — spawns a subject with no legitimate policy rules that repeatedly targets sensitive objects (shadow_t, etc_t) in the background attempt stream.
- Enforcing vs Permissive — Permissive is a real SELinux mode used to test a new policy: nothing is ever blocked, but every would-be denial is still written to the audit log, which is why the log line is orange, not red, in that mode.
Real-world relevance: this is the actual decision function inside security_compute_av() in the Linux Security Module (LSM) hook path that SELinux and AppArmor both implement — every file open, socket bind and ptrace call on a hardened Linux box passes through a DAC check and then a policy-table check shaped exactly like these two.