From 648c0d343c5b1b90e2dec5019a754b36e7791c3f Mon Sep 17 00:00:00 2001
From: Stephen Smalley <sds@tycho.nsa.gov>
Date: Thu, 30 Jan 2014 13:23:08 -0500
Subject: [PATCH] Remove MAC capabilities from unconfined domains.

Linux defines two capabilities for Mandatory Access Control (MAC)
security modules, CAP_MAC_OVERRIDE (override MAC access restrictions)
and CAP_MAC_ADMIN (allow MAC configuration or state changes).
SELinux predates these capabilities and did not originally use them,
but later made use of CAP_MAC_ADMIN as a way to control the ability
to set security context values unknown to the currently loaded
SELinux policy on files.  That facility is used in Linux for e.g.
livecd creation where a file security context that is being set
on a generated filesystem is not known to the build host policy.
Internally, files with such labels are treated as having the unlabeled
security context for permission checking purposes until/unless the
context is later defined through a policy reload.

CAP_MAC_OVERRIDE is never checked by SELinux, so it never needs
to be allowed.  CAP_MAC_ADMIN is only checked if setting an
unknown security context value; the only legitimate use I can see
in Android is the recovery console, where a context may need to be set
on /system that is not defined in the recovery policy.

Remove these capabilities from unconfined domains, allow
mac_admin for the recovery domain, and add neverallow rules.

Signed-off-by: Stephen Smalley <sds@tycho.nsa.gov>

(cherry picked from commit 04ee5dfb80491f8493fedcd099bd4551c9503c83)

Change-Id: I353fbe5da80f194cf1fd35053f91499ad0336692
---
 domain.te     | 3 +++
 recovery.te   | 2 ++
 unconfined.te | 3 ++-
 3 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/domain.te b/domain.te
index 705482410..abd11584b 100644
--- a/domain.te
+++ b/domain.te
@@ -151,6 +151,9 @@ neverallow { domain -relabeltodomain } *:dir_file_class_set relabelto;
 ### neverallow rules
 ###
 
+neverallow domain self:capability2 mac_override;
+neverallow { domain -recovery } self:capability2 mac_admin;
+
 # Only init should be able to load SELinux policies.
 # The first load technically occurs while still in the kernel domain,
 # but this does not trigger a denial since there is no policy yet.
diff --git a/recovery.te b/recovery.te
index eb2a2b0ae..abcf0cfd4 100644
--- a/recovery.te
+++ b/recovery.te
@@ -4,6 +4,8 @@ allow recovery rootfs:file entrypoint;
 unconfined_domain(recovery)
 relabelto_domain(recovery)
 
+allow recovery self:capability2 mac_admin;
+
 allow recovery {fs_type dev_type -kmem_device file_type}:dir_file_class_set relabelto;
 allow recovery unlabeled:filesystem mount;
 
diff --git a/unconfined.te b/unconfined.te
index 9facc2e18..8d424f3ee 100644
--- a/unconfined.te
+++ b/unconfined.te
@@ -16,7 +16,8 @@
 # The use of this template is discouraged.
 ######################################################
 
-allow unconfineddomain self:capability_class_set *;
+allow unconfineddomain self:capability *;
+allow unconfineddomain self:capability2 ~{ mac_override mac_admin };
 allow unconfineddomain kernel:security ~{ load_policy setenforce setcheckreqprot };
 allow unconfineddomain kernel:system *;
 allow unconfineddomain domain:process ~{ execmem execstack execheap ptrace transition dyntransition };
-- 
GitLab