From 623975fa5aece708032aaf29689d73e1f3a615e7 Mon Sep 17 00:00:00 2001
From: Nick Kralevich <nnk@google.com>
Date: Sat, 11 Jan 2014 01:31:03 -0800
Subject: [PATCH] Support forcing permissive domains to unconfined.

Permissive domains are only intended for development.
When a device launches, we want to ensure that all
permissive domains are in, at a minimum, unconfined+enforcing.

Add FORCE_PERMISSIVE_TO_UNCONFINED to Android.mk. During
development, this flag is false, and permissive domains
are allowed. When SELinux new feature development has been
frozen immediately before release, this flag will be flipped
to true. Any previously permissive domains will move into
unconfined+enforcing.

This will ensure that all SELinux domains have at least a
minimal level of protection.

Unconditionally enable this flag for all user builds.

Change-Id: I1632f0da0022c80170d8eb57c82499ac13fd7858
---
 Android.mk        | 21 ++++++++++++++++++++-
 bluetooth.te      |  4 ++--
 dhcp.te           |  2 +-
 drmserver.te      |  2 +-
 dumpstate.te      |  2 +-
 hci_attach.te     |  2 +-
 hostapd.te        |  2 +-
 mediaserver.te    |  2 +-
 platform_app.te   |  2 +-
 release_app.te    |  2 +-
 rild.te           |  2 +-
 sdcardd.te        |  2 +-
 shared_app.te     |  2 +-
 surfaceflinger.te |  2 +-
 system_app.te     |  2 +-
 system_server.te  |  2 +-
 te_macros         | 11 +++++++++++
 untrusted_app.te  |  2 +-
 wpa_supplicant.te |  2 +-
 19 files changed, 49 insertions(+), 19 deletions(-)

diff --git a/Android.mk b/Android.mk
index fa6cd7836..a3463bb01 100644
--- a/Android.mk
+++ b/Android.mk
@@ -2,6 +2,22 @@ LOCAL_PATH:= $(call my-dir)
 
 include $(CLEAR_VARS)
 
+# Force permissive domains to be unconfined+enforcing?
+#
+# During development, this should be set to false.
+# Permissive means permissive.
+#
+# When we're close to a release and SELinux new policy development
+# is frozen, we should flip this to true. This forces any currently
+# permissive domains into unconfined+enforcing.
+#
+FORCE_PERMISSIVE_TO_UNCONFINED:=false
+
+ifeq ($(TARGET_BUILD_VARIANT),user)
+  # User builds are always forced unconfined+enforcing
+  FORCE_PERMISSIVE_TO_UNCONFINED:=true
+endif
+
 # SELinux policy version.
 # Must be <= /selinux/policyvers reported by the Android kernel.
 # Must be within the compatibility range reported by checkpolicy -V.
@@ -69,7 +85,10 @@ $(sepolicy_policy.conf): PRIVATE_MLS_SENS := $(MLS_SENS)
 $(sepolicy_policy.conf): PRIVATE_MLS_CATS := $(MLS_CATS)
 $(sepolicy_policy.conf) : $(call build_policy, security_classes initial_sids access_vectors global_macros mls_macros mls policy_capabilities te_macros attributes *.te roles users initial_sid_contexts fs_use genfs_contexts port_contexts)
 	@mkdir -p $(dir $@)
-	$(hide) m4 -D mls_num_sens=$(PRIVATE_MLS_SENS) -D mls_num_cats=$(PRIVATE_MLS_CATS) -D target_build_variant=$(TARGET_BUILD_VARIANT) -s $^ > $@
+	$(hide) m4 -D mls_num_sens=$(PRIVATE_MLS_SENS) -D mls_num_cats=$(PRIVATE_MLS_CATS) \
+		-D target_build_variant=$(TARGET_BUILD_VARIANT) \
+		-D force_permissive_to_unconfined=$(FORCE_PERMISSIVE_TO_UNCONFINED) \
+		-s $^ > $@
 	$(hide) sed '/dontaudit/d' $@ > $@.dontaudit
 
 $(LOCAL_BUILT_MODULE) : $(sepolicy_policy.conf) $(HOST_OUT_EXECUTABLES)/checkpolicy
diff --git a/bluetooth.te b/bluetooth.te
index a6e0c4e4d..6b48ed48d 100644
--- a/bluetooth.te
+++ b/bluetooth.te
@@ -1,6 +1,6 @@
 # bluetooth subsystem
 type bluetooth, domain;
-permissive bluetooth;
+permissive_or_unconfined(bluetooth)
 app_domain(bluetooth)
 
 # Data file accesses.
@@ -50,4 +50,4 @@ allow bluetooth bluetooth_prop:property_service set;
 
 # Superuser capabilities.
 # bluetooth requires net_admin.
-neverallow bluetooth self:capability ~net_admin;
+neverallow { bluetooth -unconfineddomain } self:capability ~net_admin;
diff --git a/dhcp.te b/dhcp.te
index 2baca81a9..785b20409 100644
--- a/dhcp.te
+++ b/dhcp.te
@@ -1,5 +1,5 @@
 type dhcp, domain;
-permissive dhcp;
+permissive_or_unconfined(dhcp)
 type dhcp_exec, exec_type, file_type;
 type dhcp_data_file, file_type, data_file_type;
 
diff --git a/drmserver.te b/drmserver.te
index 112d7a180..7bc0b3818 100644
--- a/drmserver.te
+++ b/drmserver.te
@@ -1,6 +1,6 @@
 # drmserver - DRM service
 type drmserver, domain;
-permissive drmserver;
+permissive_or_unconfined(drmserver)
 type drmserver_exec, exec_type, file_type;
 
 init_daemon_domain(drmserver)
diff --git a/dumpstate.te b/dumpstate.te
index e0fe4ceb8..fbf9ce923 100644
--- a/dumpstate.te
+++ b/dumpstate.te
@@ -1,6 +1,6 @@
 # dumpstate
 type dumpstate, domain;
-permissive dumpstate;
+permissive_or_unconfined(dumpstate)
 type dumpstate_exec, exec_type, file_type;
 
 init_daemon_domain(dumpstate)
diff --git a/hci_attach.te b/hci_attach.te
index 2a55d512b..5115292e3 100644
--- a/hci_attach.te
+++ b/hci_attach.te
@@ -1,5 +1,5 @@
 type hci_attach, domain;
-permissive hci_attach;
+permissive_or_unconfined(hci_attach)
 type hci_attach_exec, exec_type, file_type;
 
 init_daemon_domain(hci_attach)
diff --git a/hostapd.te b/hostapd.te
index a934384df..efa3a8d53 100644
--- a/hostapd.te
+++ b/hostapd.te
@@ -1,6 +1,6 @@
 # userspace wifi access points
 type hostapd, domain;
-permissive hostapd;
+permissive_or_unconfined(hostapd)
 type hostapd_exec, exec_type, file_type;
 
 allow hostapd self:capability { net_admin net_raw setuid setgid };
diff --git a/mediaserver.te b/mediaserver.te
index f84a4248c..7589ee8ba 100644
--- a/mediaserver.te
+++ b/mediaserver.te
@@ -1,6 +1,6 @@
 # mediaserver - multimedia daemon
 type mediaserver, domain;
-permissive mediaserver;
+permissive_or_unconfined(mediaserver)
 type mediaserver_exec, exec_type, file_type;
 
 typeattribute mediaserver mlstrustedsubject;
diff --git a/platform_app.te b/platform_app.te
index 40f2dd333..bbbc0f7e6 100644
--- a/platform_app.te
+++ b/platform_app.te
@@ -3,7 +3,7 @@
 ###
 
 type platform_app, domain;
-permissive platform_app;
+permissive_or_unconfined(platform_app)
 app_domain(platform_app)
 platform_app_domain(platform_app)
 # Access the network.
diff --git a/release_app.te b/release_app.te
index 6be3620ac..69cff196d 100644
--- a/release_app.te
+++ b/release_app.te
@@ -3,7 +3,7 @@
 ###
 
 type release_app, domain;
-permissive release_app;
+permissive_or_unconfined(release_app)
 app_domain(release_app)
 platform_app_domain(release_app)
 # Access the network.
diff --git a/rild.te b/rild.te
index 5bc0b6264..8de5c59ad 100644
--- a/rild.te
+++ b/rild.te
@@ -1,6 +1,6 @@
 # rild - radio interface layer daemon
 type rild, domain;
-permissive rild;
+permissive_or_unconfined(rild)
 type rild_exec, exec_type, file_type;
 
 init_daemon_domain(rild)
diff --git a/sdcardd.te b/sdcardd.te
index 4cf080a23..eb983522c 100644
--- a/sdcardd.te
+++ b/sdcardd.te
@@ -1,5 +1,5 @@
 type sdcardd, domain;
-permissive sdcardd;
+permissive_or_unconfined(sdcardd)
 type sdcardd_exec, exec_type, file_type;
 
 init_daemon_domain(sdcardd)
diff --git a/shared_app.te b/shared_app.te
index e469bddb3..4ab90fe26 100644
--- a/shared_app.te
+++ b/shared_app.te
@@ -3,7 +3,7 @@
 ###
 
 type shared_app, domain;
-permissive shared_app;
+permissive_or_unconfined(shared_app)
 app_domain(shared_app)
 platform_app_domain(shared_app)
 # Access the network.
diff --git a/surfaceflinger.te b/surfaceflinger.te
index 39781fc8a..edbe22ff2 100644
--- a/surfaceflinger.te
+++ b/surfaceflinger.te
@@ -1,6 +1,6 @@
 # surfaceflinger - display compositor service
 type surfaceflinger, domain;
-permissive surfaceflinger;
+permissive_or_unconfined(surfaceflinger)
 type surfaceflinger_exec, exec_type, file_type;
 
 init_daemon_domain(surfaceflinger)
diff --git a/system_app.te b/system_app.te
index 63aa76ce2..41e446be8 100644
--- a/system_app.te
+++ b/system_app.te
@@ -4,7 +4,7 @@
 # server.
 #
 type system_app, domain;
-permissive system_app;
+permissive_or_unconfined(system_app)
 app_domain(system_app)
 
 # Perform binder IPC to any app domain.
diff --git a/system_server.te b/system_server.te
index 22d739bd2..06bca76a6 100644
--- a/system_server.te
+++ b/system_server.te
@@ -3,7 +3,7 @@
 # Most of the framework services run in this process.
 #
 type system_server, domain, mlstrustedsubject;
-permissive system_server;
+permissive_or_unconfined(system_server)
 
 # Define a type for tmpfs-backed ashmem regions.
 tmpfs_domain(system_server)
diff --git a/te_macros b/te_macros
index 9396e4f74..03c78f31a 100644
--- a/te_macros
+++ b/te_macros
@@ -327,3 +327,14 @@ define(`non_system_app_set', `{ appdomain -system_app }')
 # SELinux rules which apply only to userdebug or eng builds
 #
 define(`userdebug_or_eng', ifelse(target_build_variant, `eng', $1, ifelse(target_build_variant, `userdebug', $1)))
+
+#####################################
+# permissive_or_unconfined
+# Returns "permissive $1" if FORCE_PERMISSIVE_TO_UNCONFINED is false,
+# and "unconfined($1)" otherwise.
+#
+# This is used for experimental domains, where we want to ensure
+# the domain is unconfined+enforcing once new SELinux policy development
+# has ceased.
+#
+define(`permissive_or_unconfined', ifelse(force_permissive_to_unconfined, `false', permissive $1;, unconfined_domain($1)))
diff --git a/untrusted_app.te b/untrusted_app.te
index 2630f9e14..190424999 100644
--- a/untrusted_app.te
+++ b/untrusted_app.te
@@ -10,7 +10,7 @@
 ###
 
 type untrusted_app, domain;
-permissive untrusted_app;
+permissive_or_unconfined(untrusted_app)
 app_domain(untrusted_app)
 net_domain(untrusted_app)
 bluetooth_domain(untrusted_app)
diff --git a/wpa_supplicant.te b/wpa_supplicant.te
index 12202fb71..6ff1e106f 100644
--- a/wpa_supplicant.te
+++ b/wpa_supplicant.te
@@ -1,6 +1,6 @@
 # wpa - wpa supplicant or equivalent
 type wpa, domain;
-permissive wpa;
+permissive_or_unconfined(wpa)
 type wpa_exec, exec_type, file_type;
 
 init_daemon_domain(wpa)
-- 
GitLab