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
diff --git a/Android.mk b/Android.mk
index fa6cd78..a3463bb 100644
--- a/Android.mk
+++ b/Android.mk
@@ -2,6 +2,22 @@
 
 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_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 a6e0c4e..6b48ed4 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 @@
 
 # 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 2baca81..785b204 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 112d7a1..7bc0b38 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 e0fe4ce..fbf9ce9 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 2a55d51..5115292 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 a934384..efa3a8d 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 f84a424..7589ee8 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 40f2dd3..bbbc0f7 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 6be3620..69cff19 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 5bc0b62..8de5c59 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 4cf080a..eb98352 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 e469bdd..4ab90fe 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 39781fc..edbe22f 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 63aa76c..41e446b 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 22d739b..06bca76 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 9396e4f..03c78f3 100644
--- a/te_macros
+++ b/te_macros
@@ -327,3 +327,14 @@
 # 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 2630f9e..1904249 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 12202fb..6ff1e10 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)