Merge "media: allow media server to add resource manager service"
diff --git a/Android.mk b/Android.mk
index 0c44f1e..af7476e 100644
--- a/Android.mk
+++ b/Android.mk
@@ -182,6 +182,23 @@
 
 ##################################
 include $(CLEAR_VARS)
+
+LOCAL_MODULE := general_file_contexts
+LOCAL_MODULE_CLASS := ETC
+LOCAL_MODULE_TAGS := tests
+
+include $(BUILD_SYSTEM)/base_rules.mk
+
+$(LOCAL_BUILT_MODULE): PRIVATE_SEPOLICY := $(built_sepolicy)
+$(LOCAL_BUILT_MODULE) : $(addprefix $(LOCAL_PATH)/, file_contexts) $(built_sepolicy) $(HOST_OUT_EXECUTABLES)/checkfc
+	@mkdir -p $(dir $@)
+	$(hide) m4 -s $< > $@
+	$(hide) $(HOST_OUT_EXECUTABLES)/checkfc $(PRIVATE_SEPOLICY) $@
+
+GENERAL_FILE_CONTEXTS := $(LOCAL_BUILT_MODULE)
+
+##################################
+include $(CLEAR_VARS)
 LOCAL_MODULE := seapp_contexts
 LOCAL_MODULE_CLASS := ETC
 LOCAL_MODULE_TAGS := optional
@@ -204,6 +221,27 @@
 
 ##################################
 include $(CLEAR_VARS)
+LOCAL_MODULE := general_seapp_contexts
+LOCAL_MODULE_CLASS := ETC
+LOCAL_MODULE_TAGS := tests
+
+include $(BUILD_SYSTEM)/base_rules.mk
+
+general_seapp_contexts.tmp := $(intermediates)/general_seapp_contexts.tmp
+$(general_seapp_contexts.tmp): $(addprefix $(LOCAL_PATH)/, seapp_contexts)
+	@mkdir -p $(dir $@)
+	$(hide) m4 -s $^ > $@
+
+$(LOCAL_BUILT_MODULE): PRIVATE_SEPOLICY := $(built_sepolicy)
+$(LOCAL_BUILT_MODULE) : $(general_seapp_contexts.tmp) $(built_sepolicy) $(HOST_OUT_EXECUTABLES)/checkseapp
+	@mkdir -p $(dir $@)
+	$(HOST_OUT_EXECUTABLES)/checkseapp -p $(PRIVATE_SEPOLICY) -o $@ $<
+
+GENERAL_SEAPP_CONTEXTS := $(LOCAL_BUILT_MODULE)
+general_seapp_contexts.tmp :=
+
+##################################
+include $(CLEAR_VARS)
 
 LOCAL_MODULE := property_contexts
 LOCAL_MODULE_CLASS := ETC
@@ -225,6 +263,23 @@
 ##################################
 include $(CLEAR_VARS)
 
+LOCAL_MODULE := general_property_contexts
+LOCAL_MODULE_CLASS := ETC
+LOCAL_MODULE_TAGS := tests
+
+include $(BUILD_SYSTEM)/base_rules.mk
+
+$(LOCAL_BUILT_MODULE): PRIVATE_SEPOLICY := $(built_sepolicy)
+$(LOCAL_BUILT_MODULE) : $(addprefix $(LOCAL_PATH)/, property_contexts) $(built_sepolicy) $(HOST_OUT_EXECUTABLES)/checkfc
+	@mkdir -p $(dir $@)
+	$(hide) m4 -s $< > $@
+	$(hide) $(HOST_OUT_EXECUTABLES)/checkfc -p $(PRIVATE_SEPOLICY) $@
+
+GENERAL_PROPERTY_CONTEXTS := $(LOCAL_BUILT_MODULE)
+
+##################################
+include $(CLEAR_VARS)
+
 LOCAL_MODULE := service_contexts
 LOCAL_MODULE_CLASS := ETC
 LOCAL_MODULE_TAGS := optional
@@ -245,6 +300,23 @@
 ##################################
 include $(CLEAR_VARS)
 
+LOCAL_MODULE := general_service_contexts
+LOCAL_MODULE_CLASS := ETC
+LOCAL_MODULE_TAGS := tests
+
+include $(BUILD_SYSTEM)/base_rules.mk
+
+$(LOCAL_BUILT_MODULE): PRIVATE_SEPOLICY := $(built_sepolicy)
+$(LOCAL_BUILT_MODULE) : $(addprefix $(LOCAL_PATH)/, service_contexts) $(built_sepolicy) $(HOST_OUT_EXECUTABLES)/checkfc
+	@mkdir -p $(dir $@)
+	$(hide) m4 -s $< > $@
+	$(hide) $(HOST_OUT_EXECUTABLES)/checkfc -p $(PRIVATE_SEPOLICY) $@
+
+GENERAL_SERVICE_CONTEXTS := $(LOCAL_BUILT_MODULE)
+
+##################################
+include $(CLEAR_VARS)
+
 LOCAL_MODULE := mac_permissions.xml
 LOCAL_MODULE_CLASS := ETC
 LOCAL_MODULE_TAGS := optional
diff --git a/access_vectors b/access_vectors
index 320a1c8..43b81e9 100644
--- a/access_vectors
+++ b/access_vectors
@@ -876,14 +876,6 @@
 	transfer
 }
 
-class zygote
-{
-	specifyids
-	specifyrlimits
-	specifyinvokewith
-	specifyseinfo
-}
-
 class property_service
 {
 	set
diff --git a/app.te b/app.te
index 40ec610..27ec14b 100644
--- a/app.te
+++ b/app.te
@@ -155,6 +155,16 @@
 allow appdomain resourcecache_data_file:file r_file_perms;
 allow appdomain resourcecache_data_file:dir r_dir_perms;
 
+# logd access
+read_logd(appdomain)
+control_logd(appdomain)
+# application inherit logd write socket (urge is to deprecate this long term)
+allow appdomain zygote:unix_dgram_socket write;
+
+allow { appdomain -isolated_app } keystore:keystore_key { test get insert delete exist saw sign verify };
+
+use_keystore({ appdomain -isolated_app })
+
 ###
 ### CTS-specific rules
 ###
@@ -168,18 +178,6 @@
 # Check SELinux policy and contexts.
 selinux_check_access(appdomain)
 selinux_check_context(appdomain)
-# Validate that each process is running in the correct security context.
-allow appdomain domain:process getattr;
-
-# logd access
-read_logd(appdomain)
-control_logd(appdomain)
-# application inherit logd write socket (urge is to deprecate this long term)
-allow appdomain zygote:unix_dgram_socket write;
-
-allow { appdomain -isolated_app } keystore:keystore_key { test get insert delete exist saw sign verify };
-
-use_keystore({ appdomain -isolated_app })
 
 ###
 ### Neverallow rules
diff --git a/bluetooth.te b/bluetooth.te
index 4d9b4ab..a91f6b2 100644
--- a/bluetooth.te
+++ b/bluetooth.te
@@ -56,6 +56,22 @@
 allow bluetooth system_server_service:service_manager find;
 allow bluetooth tmp_system_server_service:service_manager find;
 
+service_manager_local_audit_domain(bluetooth)
+auditallow bluetooth {
+    tmp_system_server_service
+    -activity_service
+    -appops_service
+    -audio_service
+    -bluetooth_manager_service
+    -connectivity_service
+    -display_service
+    -dropbox_service
+    -media_session_service
+    -network_management_service
+    -power_service
+    -registry_service
+}:service_manager find;
+
 # already open bugreport file descriptors may be shared with
 # the bluetooth process, from a file in
 # /data/data/com.android.shell/files/bugreports/bugreport-*.
diff --git a/domain.te b/domain.te
index 005b2b3..a67a855 100644
--- a/domain.te
+++ b/domain.te
@@ -92,6 +92,7 @@
 allow domain urandom_device:chr_file rw_file_perms;
 allow domain random_device:chr_file rw_file_perms;
 allow domain properties_device:file r_file_perms;
+allow domain init:key search;
 
 # logd access
 write_logd(domain)
@@ -344,6 +345,10 @@
   -dex2oat
 } dalvikcache_data_file:file no_w_file_perms;
 
+# Only system_server should be able to send commands via the zygote socket
+neverallow { domain -zygote -system_server } zygote:unix_stream_socket connectto;
+neverallow { domain -system_server } zygote_socket:sock_file write;
+
 # Android does not support System V IPCs.
 #
 # The reason for this is due to the fact that, by design, they lead to global
@@ -365,3 +370,8 @@
 # Do not mount on top of symlinks, fifos, or sockets.
 # Feature parity with Chromium LSM.
 neverallow domain { file_type fs_type dev_type }:{ lnk_file fifo_file sock_file } mounton;
+
+# Nobody should be able to execute su on user builds.
+# On userdebug/eng builds, only dumpstate, shell, and
+# su itself execute su.
+neverallow { domain userdebug_or_eng(`-dumpstate -shell -su') } su_exec:file no_x_file_perms;
diff --git a/file.te b/file.te
index 5ac2b66..fa4c482 100644
--- a/file.te
+++ b/file.te
@@ -49,6 +49,8 @@
 type coredump_file, file_type;
 # Default type for anything under /data.
 type system_data_file, file_type, data_file_type;
+# Unencrypted data
+type unencrypted_data_file, file_type, data_file_type;
 # /data/.layout_version or other installd-created files that
 # are created in a system_data_file directory.
 type install_data_file, file_type, data_file_type;
@@ -142,7 +144,6 @@
 type gps_socket, file_type;
 type installd_socket, file_type;
 type lmkd_socket, file_type;
-type logd_debug, file_type, mlstrustedobject;
 type logd_socket, file_type, mlstrustedobject;
 type logdr_socket, file_type, mlstrustedobject;
 type logdw_socket, file_type, mlstrustedobject;
diff --git a/file_contexts b/file_contexts
index d510476..e540042 100644
--- a/file_contexts
+++ b/file_contexts
@@ -86,7 +86,6 @@
 /dev/socket/gps		u:object_r:gps_socket:s0
 /dev/socket/installd	u:object_r:installd_socket:s0
 /dev/socket/lmkd        u:object_r:lmkd_socket:s0
-/dev/logd_debug		u:object_r:logd_debug:s0
 /dev/socket/logd	u:object_r:logd_socket:s0
 /dev/socket/logdr	u:object_r:logdr_socket:s0
 /dev/socket/logdw	u:object_r:logdw_socket:s0
@@ -182,6 +181,7 @@
 #
 /data(/.*)?		u:object_r:system_data_file:s0
 /data/.layout_version		u:object_r:install_data_file:s0
+/data/unencrypted(/.*)?         u:object_r:unencrypted_data_file:s0
 /data/backup(/.*)?		u:object_r:backup_data_file:s0
 /data/secure/backup(/.*)?	u:object_r:backup_data_file:s0
 /data/security(/.*)?	u:object_r:security_file:s0
diff --git a/init.te b/init.te
index da9a722..909490d 100644
--- a/init.te
+++ b/init.te
@@ -234,6 +234,18 @@
 allow init pstorefs:dir search;
 allow init pstorefs:file r_file_perms;
 
+# linux keyring configuration
+allow init init:key { write search setattr };
+
+# Allow init to link temp fs to unencrypted data on userdata
+allow init tmpfs:lnk_file { create read getattr relabelfrom };
+
+# Allow init to manipulate /data/unencrypted
+allow init unencrypted_data_file:{ file lnk_file } create_file_perms;
+allow init unencrypted_data_file:dir create_dir_perms;
+
+unix_socket_connect(init, vold, vold)
+
 ###
 ### neverallow rules
 ###
diff --git a/installd.te b/installd.te
index 6b1b2b8..46e6b81 100644
--- a/installd.te
+++ b/installd.te
@@ -61,9 +61,6 @@
 
 # Run dex2oat in its own sandbox.
 domain_auto_trans(installd, dex2oat_exec, dex2oat)
-# dex2oat needs LD_PRELOAD, passed down from init
-# https://android-review.googlesource.com/94851
-allow installd dex2oat:process noatsecure;
 
 # Upgrade from unlabeled userdata.
 # Just need enough to remove and/or relabel it.
diff --git a/keystore.te b/keystore.te
index 6a89df3..3561fed 100644
--- a/keystore.te
+++ b/keystore.te
@@ -12,6 +12,11 @@
 allow keystore tee_device:chr_file rw_file_perms;
 allow keystore tee:unix_stream_socket connectto;
 
+allow keystore keystore_service:service_manager { add find };
+
+# Check SELinux permissions.
+selinux_check_access(keystore)
+
 ###
 ### Neverallow rules
 ###
@@ -25,8 +30,3 @@
 neverallow { domain -keystore -init } keystore_data_file:notdevfile_class_set *;
 
 neverallow domain keystore:process ptrace;
-
-allow keystore keystore_service:service_manager { add find };
-
-# Check SELinux permissions.
-selinux_check_access(keystore)
diff --git a/logd.te b/logd.te
index 70a894c..8c28b48 100644
--- a/logd.te
+++ b/logd.te
@@ -9,18 +9,14 @@
 allow logd self:netlink_audit_socket { create_socket_perms nlmsg_write };
 allow logd kernel:system syslog_read;
 allow logd kmsg_device:chr_file w_file_perms;
+allow logd system_data_file:file r_file_perms;
 
 r_dir_file(logd, domain)
 
-userdebug_or_eng(`
-  # Debug output
-  type_transition logd device:file logd_debug;
-  allow logd device:dir rw_dir_perms;
-  allow logd logd_debug:file create_file_perms;
-')
-
 allow logd kernel:system syslog_mod;
 
+control_logd(logd)
+
 ###
 ### Neverallow rules
 ###
diff --git a/neverallow_macros b/neverallow_macros
index 3593dd1..b36cceb 100644
--- a/neverallow_macros
+++ b/neverallow_macros
@@ -1,5 +1,6 @@
 #
 # Common neverallow permissions
 define(`no_w_file_perms', `{ append create link unlink relabelfrom rename setattr write }')
+define(`no_rw_file_perms', `{ no_w_file_perms open read ioctl lock }')
 define(`no_x_file_perms', `{ execute execute_no_trans }')
 define(`no_w_dir_perms',  `{ add_name create link relabelfrom remove_name rename reparent rmdir setattr write }')
diff --git a/system_server.te b/system_server.te
index 0663239..b93a5cb 100644
--- a/system_server.te
+++ b/system_server.te
@@ -75,10 +75,6 @@
 # Kill apps.
 allow system_server appdomain:process { sigkill signal };
 
-# This line seems suspect, as it should not really need to
-# set scheduling parameters for a kernel domain task.
-allow system_server kernel:process setsched;
-
 # Set scheduling info for apps.
 allow system_server appdomain:process { getsched setsched };
 allow system_server mediaserver:process { getsched setsched };
@@ -88,9 +84,6 @@
 # all processes on the device.
 r_dir_file(system_server, domain)
 
-# Write to /proc/pid/oom_adj_score for apps.
-allow system_server appdomain:file write;
-
 # Read/Write to /proc/net/xt_qtaguid/ctrl and and /dev/xt_qtaguid.
 allow system_server qtaguid_proc:file rw_file_perms;
 allow system_server qtaguid_device:chr_file rw_file_perms;
@@ -302,9 +295,6 @@
 type_transition system_server system_data_file:sock_file system_ndebug_socket "ndebugsocket";
 allow system_server system_ndebug_socket:sock_file create_file_perms;
 
-# Specify any arguments to zygote.
-allow system_server self:zygote { specifyids specifyrlimits specifyseinfo };
-
 # Manage cache files.
 allow system_server cache_file:dir { relabelfrom create_dir_perms };
 allow system_server cache_file:file { relabelfrom create_file_perms };
@@ -319,7 +309,7 @@
 
 # Allow system_server to use app-created sockets and pipes.
 allow system_server appdomain:{ tcp_socket udp_socket } { getattr getopt setopt read write shutdown };
-allow system_server appdomain:fifo_file { getattr read write };
+allow system_server appdomain:{ fifo_file unix_stream_socket } { getattr read write };
 
 # Allow abstract socket connection
 allow system_server rild:unix_stream_socket connectto;
@@ -500,3 +490,8 @@
 # system server to dynamically load a dex file, something we do not
 # want to allow.
 neverallow system_server dex2oat_exec:file no_x_file_perms;
+
+# The only block device system_server should be accessing is
+# the frp_block_device. This helps avoid a system_server to root
+# escalation by writing to raw block devices.
+neverallow system_server { dev_type -frp_block_device }:blk_file no_rw_file_perms;
diff --git a/te_macros b/te_macros
index 35dfb4d..fae0e3a 100644
--- a/te_macros
+++ b/te_macros
@@ -301,9 +301,6 @@
 # Ability to write to android log
 # daemon via sockets
 define(`write_logd', `
-userdebug_or_eng(`
-  allow $1 logd_debug:file w_file_perms;
-')
 unix_socket_send($1, logdw, logd)
 allow $1 pmsg_device:chr_file w_file_perms;
 ')
diff --git a/tools/sepolicy-analyze/Android.mk b/tools/sepolicy-analyze/Android.mk
index 2667d56..e65efe9 100644
--- a/tools/sepolicy-analyze/Android.mk
+++ b/tools/sepolicy-analyze/Android.mk
@@ -7,7 +7,7 @@
 LOCAL_MODULE_TAGS := optional
 LOCAL_C_INCLUDES := external/libsepol/include
 LOCAL_CFLAGS := -Wall -Werror
-LOCAL_SRC_FILES := sepolicy-analyze.c dups.c neverallow.c perm.c typecmp.c utils.c
+LOCAL_SRC_FILES := sepolicy-analyze.c dups.c neverallow.c perm.c typecmp.c booleans.c attribute.c utils.c
 LOCAL_STATIC_LIBRARIES := libsepol
 
 include $(BUILD_HOST_EXECUTABLE)
diff --git a/tools/sepolicy-analyze/README b/tools/sepolicy-analyze/README
index f78eb66..d18609a 100644
--- a/tools/sepolicy-analyze/README
+++ b/tools/sepolicy-analyze/README
@@ -53,6 +53,18 @@
     permissive domains can be helpful during development, they
     should not be present in a final -user build.
 
+    BOOLEANS (booleans)
+    sepolicy-analyze out/target/product/<board>/root/sepolicy booleans
+
+    Displays the boolean names in the policy (if any).
+    Policy booleans are forbidden in Android policy, so if there is any
+    output, the policy will fail CTS.
+
+    ATTRIBUTE (attribute)
+    sepolicy-analyze out/target/product/<board>/root/sepolicy attribute <name>
+
+    Displays the types associated with the specified attribute name.
+
     NEVERALLOW CHECKING (neverallow)
     sepolicy-analyze out/target/product/<board>/root/sepolicy neverallow \
     [-w] [-d] [-f neverallows.conf] | [-n "neverallow string"]
diff --git a/tools/sepolicy-analyze/attribute.c b/tools/sepolicy-analyze/attribute.c
new file mode 100644
index 0000000..474bda2
--- /dev/null
+++ b/tools/sepolicy-analyze/attribute.c
@@ -0,0 +1,39 @@
+#include "attribute.h"
+
+void attribute_usage() {
+    fprintf(stderr, "\tattribute <attribute-name>\n");
+}
+
+static int list_attribute(policydb_t * policydb, char *name)
+{
+    struct type_datum *attr;
+    struct ebitmap_node *n;
+    unsigned int bit;
+
+    attr = hashtab_search(policydb->p_types.table, name);
+    if (!attr) {
+        fprintf(stderr, "%s is not defined in this policy.\n", name);
+        return -1;
+    }
+
+    if (attr->flavor != TYPE_ATTRIB) {
+        fprintf(stderr, "%s is a type not an attribute in this policy.\n", name);
+        return -1;
+    }
+
+    ebitmap_for_each_bit(&policydb->attr_type_map[attr->s.value - 1], n, bit) {
+        if (!ebitmap_node_get_bit(n, bit))
+            continue;
+        printf("%s\n", policydb->p_type_val_to_name[bit]);
+    }
+
+    return 0;
+}
+
+int attribute_func (int argc, char **argv, policydb_t *policydb) {
+    if (argc != 2) {
+        USAGE_ERROR = true;
+        return -1;
+    }
+    return list_attribute(policydb, argv[1]);
+}
diff --git a/tools/sepolicy-analyze/attribute.h b/tools/sepolicy-analyze/attribute.h
new file mode 100644
index 0000000..05adcbd
--- /dev/null
+++ b/tools/sepolicy-analyze/attribute.h
@@ -0,0 +1,11 @@
+#ifndef ATTRIBUTE_H
+#define ATTRIBUTE_H
+
+#include <sepol/policydb/policydb.h>
+
+#include "utils.h"
+
+void attribute_usage(void);
+int attribute_func(int argc, char **argv, policydb_t *policydb);
+
+#endif /* ATTRIBUTE_H */
diff --git a/tools/sepolicy-analyze/booleans.c b/tools/sepolicy-analyze/booleans.c
new file mode 100644
index 0000000..c3b605d
--- /dev/null
+++ b/tools/sepolicy-analyze/booleans.c
@@ -0,0 +1,22 @@
+#include "booleans.h"
+
+void booleans_usage() {
+    fprintf(stderr, "\tbooleans\n");
+}
+
+static int list_booleans(hashtab_key_t k,
+                         __attribute__ ((unused)) hashtab_datum_t d,
+                         __attribute__ ((unused)) void *args)
+{
+    const char *name = k;
+    printf("%s\n", name);
+    return 0;
+}
+
+int booleans_func (int argc, __attribute__ ((unused)) char **argv, policydb_t *policydb) {
+    if (argc != 1) {
+        USAGE_ERROR = true;
+        return -1;
+    }
+    return hashtab_map(policydb->p_bools.table, list_booleans, NULL);
+}
diff --git a/tools/sepolicy-analyze/booleans.h b/tools/sepolicy-analyze/booleans.h
new file mode 100644
index 0000000..bfbe0e1
--- /dev/null
+++ b/tools/sepolicy-analyze/booleans.h
@@ -0,0 +1,11 @@
+#ifndef BOOLEANS_H
+#define BOOLEANS_H
+
+#include <sepol/policydb/policydb.h>
+
+#include "utils.h"
+
+void booleans_usage(void);
+int booleans_func(int argc, char **argv, policydb_t *policydb);
+
+#endif /* BOOLEANS_H */
diff --git a/tools/sepolicy-analyze/sepolicy-analyze.c b/tools/sepolicy-analyze/sepolicy-analyze.c
index 8c0c423..b70eaaa 100644
--- a/tools/sepolicy-analyze/sepolicy-analyze.c
+++ b/tools/sepolicy-analyze/sepolicy-analyze.c
@@ -6,6 +6,8 @@
 #include "neverallow.h"
 #include "perm.h"
 #include "typecmp.h"
+#include "booleans.h"
+#include "attribute.h"
 #include "utils.h"
 
 #define NUM_COMPONENTS (int) (sizeof(analyze_components)/sizeof(analyze_components[0]))
@@ -20,7 +22,9 @@
     COMP(dups),
     COMP(neverallow),
     COMP(permissive),
-    COMP(typecmp)
+    COMP(typecmp),
+    COMP(booleans),
+    COMP(attribute)
 };
 
 void usage(char *arg0)
diff --git a/untrusted_app.te b/untrusted_app.te
index abcba78..d88414c 100644
--- a/untrusted_app.te
+++ b/untrusted_app.te
@@ -125,6 +125,7 @@
     -registry_service
     -search_service
     -sensorservice_service
+    -statusbar_service
     -textservices_service
     -trust_service
     -uimode_service
@@ -137,6 +138,10 @@
     -wifip2p_service
 }:service_manager find;
 
+# Allow verifier to access staged apks.
+allow untrusted_app { apk_tmp_file apk_private_tmp_file }:dir r_dir_perms;
+allow untrusted_app { apk_tmp_file apk_private_tmp_file }:file r_file_perms;
+
 ###
 ### neverallow rules
 ###
@@ -162,6 +167,12 @@
 neverallow untrusted_app init:unix_stream_socket connectto;
 neverallow untrusted_app property_type:property_service set;
 
-# Allow verifier to access staged apks.
-allow untrusted_app { apk_tmp_file apk_private_tmp_file }:dir r_dir_perms;
-allow untrusted_app { apk_tmp_file apk_private_tmp_file }:file r_file_perms;
+# Do not allow untrusted_app to be assigned mlstrustedsubject.
+# This would undermine the per-user isolation model being
+# enforced via levelFrom=user in seapp_contexts and the mls
+# constraints.  As there is no direct way to specify a neverallow
+# on attribute assignment, this relies on the fact that fork
+# permission only makes sense within a domain (hence should
+# never be granted to any other domain within mlstrustedsubject)
+# and untrusted_app is allowed fork permission to itself.
+neverallow untrusted_app mlstrustedsubject:process fork;
diff --git a/vold.te b/vold.te
index f605f8a..17ddd61 100644
--- a/vold.te
+++ b/vold.te
@@ -101,3 +101,7 @@
 
 # Access metadata block device used for encryption meta-data.
 allow vold metadata_block_device:blk_file rw_file_perms;
+
+# Allow init to manipulate /data/unencrypted
+allow vold unencrypted_data_file:{ file lnk_file } create_file_perms;
+allow vold unencrypted_data_file:dir create_dir_perms;