Project import
diff --git a/sepolicy/Android.mk b/sepolicy/Android.mk
new file mode 100644
index 0000000..5cc4a24
--- /dev/null
+++ b/sepolicy/Android.mk
@@ -0,0 +1,507 @@
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+# SELinux policy version.
+# Must be <= /sys/fs/selinux/policyvers reported by the Android kernel.
+# Must be within the compatibility range reported by checkpolicy -V.
+POLICYVERS ?= 29
+
+MLS_SENS=1
+MLS_CATS=1024
+
+ifdef BOARD_SEPOLICY_REPLACE
+$(error BOARD_SEPOLICY_REPLACE is no longer supported; please remove from your BoardConfig.mk or other .mk file.)
+endif
+
+ifdef BOARD_SEPOLICY_IGNORE
+$(error BOARD_SEPOLICY_IGNORE is no longer supported; please remove from your BoardConfig.mk or other .mk file.)
+endif
+
+ifdef BOARD_SEPOLICY_UNION
+$(warning BOARD_SEPOLICY_UNION is no longer required - all files found in BOARD_SEPOLICY_DIRS are implicitly unioned; please remove from your BoardConfig.mk or other .mk file.)
+endif
+
+ifdef BOARD_SEPOLICY_M4DEFS
+LOCAL_ADDITIONAL_M4DEFS := $(addprefix -D, $(BOARD_SEPOLICY_M4DEFS))
+endif
+
+# Builds paths for all policy files found in BOARD_SEPOLICY_DIRS and the LOCAL_PATH.
+# $(1): the set of policy name paths to build
+build_policy = $(foreach type, $(1), $(foreach file, $(addsuffix /$(type), $(LOCAL_PATH) $(BOARD_SEPOLICY_DIRS)), $(sort $(wildcard $(file)))))
+
+# Builds paths for all policy files found in BOARD_SEPOLICY_DIRS.
+# $(1): the set of policy name paths to build
+build_device_policy = $(foreach type, $(1), $(foreach file, $(addsuffix /$(type), $(BOARD_SEPOLICY_DIRS)), $(sort $(wildcard $(file)))))
+
+# Add a file containing only a newline in-between each policy configuration
+# 'contexts' file. This will allow OEM policy configuration files without a
+# final newline (0x0A) to be built correctly by the m4(1) macro processor.
+# $(1): the set of contexts file names.
+# $(2): the file containing only 0x0A.
+add_nl = $(foreach entry, $(1), $(subst $(entry), $(entry) $(2), $(entry)))
+
+sepolicy_build_files := security_classes \
+                        initial_sids \
+                        access_vectors \
+                        global_macros \
+                        neverallow_macros \
+                        mls_macros \
+                        mls \
+                        policy_capabilities \
+                        te_macros \
+                        attributes \
+                        ioctl_macros \
+                        *.te \
+                        roles \
+                        users \
+                        initial_sid_contexts \
+                        fs_use \
+                        genfs_contexts \
+                        port_contexts
+
+##################################
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := sectxfile_nl
+LOCAL_MODULE_CLASS := ETC
+LOCAL_MODULE_TAGS := optional
+
+# Create a file containing newline only to add between context config files
+include $(BUILD_SYSTEM)/base_rules.mk
+$(LOCAL_BUILT_MODULE):
+	@mkdir -p $(dir $@)
+	$(hide) echo > $@
+
+built_nl := $(LOCAL_BUILT_MODULE)
+
+#################################
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := sepolicy
+LOCAL_MODULE_CLASS := ETC
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_PATH := $(TARGET_ROOT_OUT)
+
+include $(BUILD_SYSTEM)/base_rules.mk
+
+sepolicy_policy.conf := $(intermediates)/policy.conf
+$(sepolicy_policy.conf): PRIVATE_MLS_SENS := $(MLS_SENS)
+$(sepolicy_policy.conf): PRIVATE_MLS_CATS := $(MLS_CATS)
+$(sepolicy_policy.conf): PRIVATE_ADDITIONAL_M4DEFS := $(LOCAL_ADDITIONAL_M4DEFS)
+$(sepolicy_policy.conf): $(call build_policy, $(sepolicy_build_files))
+	@mkdir -p $(dir $@)
+	$(hide) m4 $(PRIVATE_ADDITIONAL_M4DEFS) \
+		-D mls_num_sens=$(PRIVATE_MLS_SENS) -D mls_num_cats=$(PRIVATE_MLS_CATS) \
+		-D target_build_variant=$(TARGET_BUILD_VARIANT) \
+		-s $^ > $@
+	$(hide) sed '/dontaudit/d' $@ > $@.dontaudit
+
+$(LOCAL_BUILT_MODULE): $(sepolicy_policy.conf) $(HOST_OUT_EXECUTABLES)/checkpolicy $(HOST_OUT_EXECUTABLES)/sepolicy-analyze
+	@mkdir -p $(dir $@)
+	$(hide) $(HOST_OUT_EXECUTABLES)/checkpolicy -M -c $(POLICYVERS) -o $@.tmp $< > /dev/null
+	$(hide) $(HOST_OUT_EXECUTABLES)/checkpolicy -M -c $(POLICYVERS) -o $(dir $<)/$(notdir $@).dontaudit $<.dontaudit > /dev/null
+	$(hide) $(HOST_OUT_EXECUTABLES)/sepolicy-analyze $@.tmp permissive > $@.permissivedomains
+	$(hide) if [ "$(TARGET_BUILD_VARIANT)" = "user" -a -s $@.permissivedomains ]; then \
+		echo "==========" 1>&2; \
+		echo "ERROR: permissive domains not allowed in user builds" 1>&2; \
+		echo "List of invalid domains:" 1>&2; \
+		cat $@.permissivedomains 1>&2; \
+		exit 1; \
+		fi
+	$(hide) mv $@.tmp $@
+
+built_sepolicy := $(LOCAL_BUILT_MODULE)
+sepolicy_policy.conf :=
+
+##################################
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := sepolicy.recovery
+LOCAL_MODULE_CLASS := ETC
+LOCAL_MODULE_TAGS := eng
+
+include $(BUILD_SYSTEM)/base_rules.mk
+
+sepolicy_policy_recovery.conf := $(intermediates)/policy_recovery.conf
+$(sepolicy_policy_recovery.conf): PRIVATE_MLS_SENS := $(MLS_SENS)
+$(sepolicy_policy_recovery.conf): PRIVATE_MLS_CATS := $(MLS_CATS)
+$(sepolicy_policy_recovery.conf): PRIVATE_ADDITIONAL_M4DEFS := $(LOCAL_ADDITIONAL_M4DEFS)
+$(sepolicy_policy_recovery.conf): $(call build_policy, $(sepolicy_build_files))
+	@mkdir -p $(dir $@)
+	$(hide) m4 $(PRIVATE_ADDITIONAL_M4DEFS) \
+		-D mls_num_sens=$(PRIVATE_MLS_SENS) -D mls_num_cats=$(PRIVATE_MLS_CATS) \
+		-D target_build_variant=$(TARGET_BUILD_VARIANT) \
+		-D target_recovery=true \
+		-s $^ > $@
+
+$(LOCAL_BUILT_MODULE): $(sepolicy_policy_recovery.conf) $(HOST_OUT_EXECUTABLES)/checkpolicy $(HOST_OUT_EXECUTABLES)/sepolicy-analyze
+	@mkdir -p $(dir $@)
+	$(hide) $(HOST_OUT_EXECUTABLES)/checkpolicy -M -c $(POLICYVERS) -o $@.tmp $< > /dev/null
+	$(hide) $(HOST_OUT_EXECUTABLES)/sepolicy-analyze $@.tmp permissive > $@.permissivedomains
+	$(hide) if [ "$(TARGET_BUILD_VARIANT)" = "user" -a -s $@.permissivedomains ]; then \
+		echo "==========" 1>&2; \
+		echo "ERROR: permissive domains not allowed in user builds" 1>&2; \
+		echo "List of invalid domains:" 1>&2; \
+		cat $@.permissivedomains 1>&2; \
+		exit 1; \
+		fi
+	$(hide) mv $@.tmp $@
+
+built_sepolicy_recovery := $(LOCAL_BUILT_MODULE)
+sepolicy_policy_recovery.conf :=
+
+##################################
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := general_sepolicy.conf
+LOCAL_MODULE_CLASS := ETC
+LOCAL_MODULE_TAGS := tests
+
+include $(BUILD_SYSTEM)/base_rules.mk
+
+exp_sepolicy_build_files :=\
+  $(foreach file, $(addprefix $(LOCAL_PATH)/, $(sepolicy_build_files)), $(sort $(wildcard $(file))))
+
+$(LOCAL_BUILT_MODULE): PRIVATE_MLS_SENS := $(MLS_SENS)
+$(LOCAL_BUILT_MODULE): PRIVATE_MLS_CATS := $(MLS_CATS)
+$(LOCAL_BUILT_MODULE): $(exp_sepolicy_build_files)
+	mkdir -p $(dir $@)
+	$(hide) m4 -D mls_num_sens=$(PRIVATE_MLS_SENS) -D mls_num_cats=$(PRIVATE_MLS_CATS) \
+		-D target_build_variant=user \
+		-s $^ > $@
+	$(hide) sed '/dontaudit/d' $@ > $@.dontaudit
+
+built_general_sepolicy.conf := $(LOCAL_BUILT_MODULE)
+exp_sepolicy_build_files :=
+
+##################################
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := sepolicy.general
+LOCAL_MODULE_CLASS := ETC
+LOCAL_MODULE_TAGS := tests
+
+include $(BUILD_SYSTEM)/base_rules.mk
+
+$(LOCAL_BUILT_MODULE): PRIVATE_BUILT_SEPOLICY.CONF := $(built_general_sepolicy.conf)
+$(LOCAL_BUILT_MODULE): $(built_general_sepolicy.conf) $(HOST_OUT_EXECUTABLES)/checkpolicy
+	@mkdir -p $(dir $@)
+	$(hide) $(HOST_OUT_EXECUTABLES)/checkpolicy -M -c $(POLICYVERS) -o $@ $(PRIVATE_BUILT_SEPOLICY.CONF) > /dev/null
+
+built_general_sepolicy := $(LOCAL_BUILT_MODULE)
+##################################
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := file_contexts.bin
+LOCAL_MODULE_CLASS := ETC
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_PATH := $(TARGET_ROOT_OUT)
+
+include $(BUILD_SYSTEM)/base_rules.mk
+
+# The file_contexts.bin is built in the following way:
+# 1. Collect all file_contexts files in THIS repository and process them with
+#    m4 into a tmp file called file_contexts.local.tmp.
+# 2. Collect all device specific file_contexts files and process them with m4
+#    into a tmp file called file_contexts.device.tmp.
+# 3. Run checkfc -e (allow no device fc entries ie empty) and fc_sort on
+#    file_contexts.device.tmp and output to file_contexts.device.sorted.tmp.
+# 4. Concatenate file_contexts.local.tmp and file_contexts.device.tmp into
+#    file_contexts.concat.tmp.
+# 5. Run checkfc and sefcontext_compile on file_contexts.concat.tmp to produce
+#    file_contexts.bin.
+#
+#  Note: That a newline file is placed between each file_context file found to
+#        ensure a proper build when an fc file is missing an ending newline.
+
+local_fc_files := $(LOCAL_PATH)/file_contexts
+ifneq ($(filter address,$(SANITIZE_TARGET)),)
+  local_fc_files := $(local_fc_files) $(LOCAL_PATH)/file_contexts_asan
+endif
+local_fcfiles_with_nl := $(call add_nl, $(local_fc_files), $(built_nl))
+
+file_contexts.local.tmp := $(intermediates)/file_contexts.local.tmp
+$(file_contexts.local.tmp): $(local_fcfiles_with_nl)
+	@mkdir -p $(dir $@)
+	$(hide) m4 -s $^ > $@
+
+device_fc_files := $(call build_device_policy, file_contexts)
+device_fcfiles_with_nl := $(call add_nl, $(device_fc_files), $(built_nl))
+
+file_contexts.device.tmp := $(intermediates)/file_contexts.device.tmp
+$(file_contexts.device.tmp): PRIVATE_ADDITIONAL_M4DEFS := $(LOCAL_ADDITIONAL_M4DEFS)
+$(file_contexts.device.tmp): $(device_fcfiles_with_nl)
+	@mkdir -p $(dir $@)
+	$(hide) m4 -s $(PRIVATE_ADDITIONAL_M4DEFS) $^ > $@
+
+file_contexts.device.sorted.tmp := $(intermediates)/file_contexts.device.sorted.tmp
+$(file_contexts.device.sorted.tmp): PRIVATE_SEPOLICY := $(built_sepolicy)
+$(file_contexts.device.sorted.tmp): $(file_contexts.device.tmp) $(built_sepolicy) $(HOST_OUT_EXECUTABLES)/fc_sort $(HOST_OUT_EXECUTABLES)/checkfc
+	@mkdir -p $(dir $@)
+	$(hide) $(HOST_OUT_EXECUTABLES)/checkfc -e $(PRIVATE_SEPOLICY) $<
+	$(hide) $(HOST_OUT_EXECUTABLES)/fc_sort $< $@
+
+file_contexts.concat.tmp := $(intermediates)/file_contexts.concat.tmp
+$(file_contexts.concat.tmp): $(file_contexts.local.tmp) $(file_contexts.device.sorted.tmp)
+	@mkdir -p $(dir $@)
+	$(hide) m4 -s $^ > $@
+
+$(LOCAL_BUILT_MODULE): PRIVATE_SEPOLICY := $(built_sepolicy)
+$(LOCAL_BUILT_MODULE): $(file_contexts.concat.tmp) $(built_sepolicy) $(HOST_OUT_EXECUTABLES)/sefcontext_compile $(HOST_OUT_EXECUTABLES)/checkfc
+	@mkdir -p $(dir $@)
+	$(hide) $(HOST_OUT_EXECUTABLES)/checkfc $(PRIVATE_SEPOLICY) $<
+	$(hide) $(HOST_OUT_EXECUTABLES)/sefcontext_compile -o $@ $<
+
+built_fc := $(LOCAL_BUILT_MODULE)
+local_fc_files :=
+local_fcfiles_with_nl :=
+device_fc_files :=
+device_fcfiles_with_nl :=
+file_contexts.concat.tmp :=
+file_contexts.device.sorted.tmp :=
+file_contexts.device.tmp :=
+file_contexts.local.tmp :=
+
+##################################
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := general_file_contexts.bin
+LOCAL_MODULE_CLASS := ETC
+LOCAL_MODULE_TAGS := tests
+
+include $(BUILD_SYSTEM)/base_rules.mk
+
+general_file_contexts.tmp := $(intermediates)/general_file_contexts.tmp
+$(general_file_contexts.tmp): $(addprefix $(LOCAL_PATH)/, file_contexts)
+	@mkdir -p $(dir $@)
+	$(hide) m4 -s $< > $@
+
+$(LOCAL_BUILT_MODULE): PRIVATE_SEPOLICY := $(built_general_sepolicy)
+$(LOCAL_BUILT_MODULE): $(general_file_contexts.tmp) $(built_general_sepolicy) $(HOST_OUT_EXECUTABLES)/sefcontext_compile $(HOST_OUT_EXECUTABLES)/checkfc
+	@mkdir -p $(dir $@)
+	$(hide) $(HOST_OUT_EXECUTABLES)/checkfc $(PRIVATE_SEPOLICY) $<
+	$(hide) $(HOST_OUT_EXECUTABLES)/sefcontext_compile -o $@ $<
+
+general_file_contexts.tmp :=
+
+##################################
+include $(CLEAR_VARS)
+LOCAL_MODULE := seapp_contexts
+LOCAL_MODULE_CLASS := ETC
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_PATH := $(TARGET_ROOT_OUT)
+
+include $(BUILD_SYSTEM)/base_rules.mk
+
+all_sc_files := $(call build_policy, seapp_contexts)
+
+$(LOCAL_BUILT_MODULE): PRIVATE_SEPOLICY := $(built_sepolicy)
+$(LOCAL_BUILT_MODULE): PRIVATE_SC_FILES := $(all_sc_files)
+$(LOCAL_BUILT_MODULE): $(built_sepolicy) $(all_sc_files) $(HOST_OUT_EXECUTABLES)/checkseapp
+	@mkdir -p $(dir $@)
+	$(hide) $(HOST_OUT_EXECUTABLES)/checkseapp -p $(PRIVATE_SEPOLICY) -o $@ $(PRIVATE_SC_FILES)
+
+built_sc := $(LOCAL_BUILT_MODULE)
+all_sc_files :=
+
+##################################
+include $(CLEAR_VARS)
+LOCAL_MODULE := general_seapp_contexts
+LOCAL_MODULE_CLASS := ETC
+LOCAL_MODULE_TAGS := tests
+
+include $(BUILD_SYSTEM)/base_rules.mk
+
+all_sc_files := $(addprefix $(LOCAL_PATH)/, seapp_contexts)
+
+$(LOCAL_BUILT_MODULE): PRIVATE_SEPOLICY := $(built_general_sepolicy)
+$(LOCAL_BUILT_MODULE): PRIVATE_SC_FILE := $(all_sc_files)
+$(LOCAL_BUILT_MODULE): $(built_general_sepolicy) $(all_sc_files) $(HOST_OUT_EXECUTABLES)/checkseapp
+	@mkdir -p $(dir $@)
+	$(hide) $(HOST_OUT_EXECUTABLES)/checkseapp -p $(PRIVATE_SEPOLICY) -o $@ $(PRIVATE_SC_FILE)
+
+all_sc_files :=
+
+##################################
+include $(CLEAR_VARS)
+LOCAL_MODULE := general_seapp_neverallows
+LOCAL_MODULE_CLASS := ETC
+LOCAL_MODULE_TAGS := tests
+
+include $(BUILD_SYSTEM)/base_rules.mk
+
+$(LOCAL_BUILT_MODULE): $(addprefix $(LOCAL_PATH)/, seapp_contexts)
+	@mkdir -p $(dir $@)
+	- $(hide) grep -ie '^neverallow' $< > $@
+
+
+##################################
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := property_contexts
+LOCAL_MODULE_CLASS := ETC
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_PATH := $(TARGET_ROOT_OUT)
+
+include $(BUILD_SYSTEM)/base_rules.mk
+
+all_pc_files := $(call build_policy, property_contexts)
+all_pcfiles_with_nl := $(call add_nl, $(all_pc_files), $(built_nl))
+
+property_contexts.tmp := $(intermediates)/property_contexts.tmp
+$(property_contexts.tmp): PRIVATE_PC_FILES := $(all_pcfiles_with_nl)
+$(property_contexts.tmp): PRIVATE_ADDITIONAL_M4DEFS := $(LOCAL_ADDITIONAL_M4DEFS)
+$(property_contexts.tmp): $(all_pcfiles_with_nl)
+	@mkdir -p $(dir $@)
+	$(hide) m4 -s $(PRIVATE_ADDITIONAL_M4DEFS) $(PRIVATE_PC_FILES) > $@
+
+
+$(LOCAL_BUILT_MODULE): PRIVATE_SEPOLICY := $(built_sepolicy)
+$(LOCAL_BUILT_MODULE): $(property_contexts.tmp) $(built_sepolicy) $(HOST_OUT_EXECUTABLES)/checkfc
+	@mkdir -p $(dir $@)
+	$(hide) sed -e 's/#.*$$//' -e '/^$$/d' $< > $@
+	$(hide) $(HOST_OUT_EXECUTABLES)/checkfc -p $(PRIVATE_SEPOLICY) $@
+
+built_pc := $(LOCAL_BUILT_MODULE)
+all_pc_files :=
+all_pcfiles_with_nl :=
+property_contexts.tmp :=
+
+##################################
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := general_property_contexts
+LOCAL_MODULE_CLASS := ETC
+LOCAL_MODULE_TAGS := tests
+
+include $(BUILD_SYSTEM)/base_rules.mk
+
+general_property_contexts.tmp := $(intermediates)/general_property_contexts.tmp
+$(general_property_contexts.tmp): $(addprefix $(LOCAL_PATH)/, property_contexts)
+	@mkdir -p $(dir $@)
+	$(hide) m4 -s $< > $@
+
+$(LOCAL_BUILT_MODULE): PRIVATE_SEPOLICY := $(built_general_sepolicy)
+$(LOCAL_BUILT_MODULE): $(general_property_contexts.tmp) $(built_general_sepolicy) $(HOST_OUT_EXECUTABLES)/checkfc $(ACP)
+	@mkdir -p $(dir $@)
+	$(hide) sed -e 's/#.*$$//' -e '/^$$/d' $< > $@
+	$(hide) $(HOST_OUT_EXECUTABLES)/checkfc -p $(PRIVATE_SEPOLICY) $@
+
+general_property_contexts.tmp :=
+
+##################################
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := service_contexts
+LOCAL_MODULE_CLASS := ETC
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_PATH := $(TARGET_ROOT_OUT)
+
+include $(BUILD_SYSTEM)/base_rules.mk
+
+all_svc_files := $(call build_policy, service_contexts)
+all_svcfiles_with_nl := $(call add_nl, $(all_svc_files), $(built_nl))
+
+service_contexts.tmp := $(intermediates)/service_contexts.tmp
+$(service_contexts.tmp): PRIVATE_SVC_FILES := $(all_svcfiles_with_nl)
+$(service_contexts.tmp): PRIVATE_ADDITIONAL_M4DEFS := $(LOCAL_ADDITIONAL_M4DEFS)
+$(service_contexts.tmp): $(all_svcfiles_with_nl)
+	@mkdir -p $(dir $@)
+	$(hide) m4 -s $(PRIVATE_ADDITIONAL_M4DEFS) $(PRIVATE_SVC_FILES) > $@
+
+$(LOCAL_BUILT_MODULE): PRIVATE_SEPOLICY := $(built_sepolicy)
+$(LOCAL_BUILT_MODULE): $(service_contexts.tmp) $(built_sepolicy) $(HOST_OUT_EXECUTABLES)/checkfc $(ACP)
+	@mkdir -p $(dir $@)
+	sed -e 's/#.*$$//' -e '/^$$/d' $< > $@
+	$(hide) $(HOST_OUT_EXECUTABLES)/checkfc -s $(PRIVATE_SEPOLICY) $@
+
+built_svc := $(LOCAL_BUILT_MODULE)
+all_svc_files :=
+all_svcfiles_with_nl :=
+service_contexts.tmp :=
+
+##################################
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := general_service_contexts
+LOCAL_MODULE_CLASS := ETC
+LOCAL_MODULE_TAGS := tests
+
+include $(BUILD_SYSTEM)/base_rules.mk
+
+general_service_contexts.tmp := $(intermediates)/general_service_contexts.tmp
+$(general_service_contexts.tmp): $(addprefix $(LOCAL_PATH)/, service_contexts)
+	@mkdir -p $(dir $@)
+	$(hide) m4 -s $< > $@
+
+$(LOCAL_BUILT_MODULE): PRIVATE_SEPOLICY := $(built_general_sepolicy)
+$(LOCAL_BUILT_MODULE): $(general_service_contexts.tmp) $(built_general_sepolicy) $(HOST_OUT_EXECUTABLES)/checkfc $(ACP)
+	@mkdir -p $(dir $@)
+	sed -e 's/#.*$$//' -e '/^$$/d' $< > $@
+	$(hide) $(HOST_OUT_EXECUTABLES)/checkfc -s $(PRIVATE_SEPOLICY) $@
+
+general_service_contexts.tmp :=
+
+##################################
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := mac_permissions.xml
+LOCAL_MODULE_CLASS := ETC
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/security
+
+include $(BUILD_SYSTEM)/base_rules.mk
+
+# Build keys.conf
+mac_perms_keys.tmp := $(intermediates)/keys.tmp
+$(mac_perms_keys.tmp): PRIVATE_ADDITIONAL_M4DEFS := $(LOCAL_ADDITIONAL_M4DEFS)
+$(mac_perms_keys.tmp): $(call build_policy, keys.conf)
+	@mkdir -p $(dir $@)
+	$(hide) m4 -s $(PRIVATE_ADDITIONAL_M4DEFS) $^ > $@
+
+all_mac_perms_files := $(call build_policy, $(LOCAL_MODULE))
+
+# Should be synced with keys.conf.
+all_keys := platform media shared testkey
+all_keys := $(all_keys:%=$(dir $(DEFAULT_SYSTEM_DEV_CERTIFICATE))/%.x509.pem)
+
+$(LOCAL_BUILT_MODULE): PRIVATE_MAC_PERMS_FILES := $(all_mac_perms_files)
+$(LOCAL_BUILT_MODULE): $(mac_perms_keys.tmp) $(HOST_OUT_EXECUTABLES)/insertkeys.py $(all_mac_perms_files) $(all_keys)
+	@mkdir -p $(dir $@)
+	$(hide) DEFAULT_SYSTEM_DEV_CERTIFICATE="$(dir $(DEFAULT_SYSTEM_DEV_CERTIFICATE))" \
+		$(HOST_OUT_EXECUTABLES)/insertkeys.py -t $(TARGET_BUILD_VARIANT) -c $(TOP) $< -o $@ $(PRIVATE_MAC_PERMS_FILES)
+
+mac_perms_keys.tmp :=
+all_mac_perms_files :=
+
+##################################
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := selinux_version
+LOCAL_MODULE_CLASS := ETC
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_PATH := $(TARGET_ROOT_OUT)
+
+include $(BUILD_SYSTEM)/base_rules.mk
+$(LOCAL_BUILT_MODULE): $(built_sepolicy) $(built_pc) $(built_fc) $(built_sc) $(built_svc)
+	@mkdir -p $(dir $@)
+	$(hide) echo -n $(BUILD_FINGERPRINT_FROM_FILE) > $@
+
+##################################
+
+build_policy :=
+build_device_policy :=
+sepolicy_build_files :=
+built_sepolicy :=
+built_sepolicy_recovery :=
+built_sc :=
+built_fc :=
+built_pc :=
+built_svc :=
+built_general_sepolicy :=
+built_general_sepolicy.conf :=
+built_nl :=
+add_nl :=
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/sepolicy/CleanSpec.mk b/sepolicy/CleanSpec.mk
new file mode 100644
index 0000000..f141e34
--- /dev/null
+++ b/sepolicy/CleanSpec.mk
@@ -0,0 +1,52 @@
+# Copyright (C) 2015 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# If you don't need to do a full clean build but would like to touch
+# a file or delete some intermediate files, add a clean step to the end
+# of the list.  These steps will only be run once, if they haven't been
+# run before.
+#
+# E.g.:
+#     $(call add-clean-step, touch -c external/sqlite/sqlite3.h)
+#     $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/STATIC_LIBRARIES/libz_intermediates)
+#
+# Always use "touch -c" and "rm -f" or "rm -rf" to gracefully deal with
+# files that are missing or have been moved.
+#
+# Use $(PRODUCT_OUT) to get to the "out/target/product/blah/" directory.
+# Use $(OUT_DIR) to refer to the "out" directory.
+#
+# If you need to re-do something that's already mentioned, just copy
+# the command and add it to the bottom of the list.  E.g., if a change
+# that you made last week required touching a file and a change you
+# made today requires touching the same file, just copy the old
+# touch step and add it to the end of the list.
+#
+# ************************************************
+# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
+# ************************************************
+
+# For example:
+#$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/APPS/AndroidTests_intermediates)
+#$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/core_intermediates)
+#$(call add-clean-step, find $(OUT_DIR) -type f -name "IGTalkSession*" -print0 | xargs -0 rm -f)
+#$(call add-clean-step, rm -rf $(PRODUCT_OUT)/data/*)
+
+# ************************************************
+# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
+# ************************************************
+
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/root/file_contexts)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/recovery/root/file_contexts)
diff --git a/sepolicy/MODULE_LICENSE_PUBLIC_DOMAIN b/sepolicy/MODULE_LICENSE_PUBLIC_DOMAIN
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/sepolicy/MODULE_LICENSE_PUBLIC_DOMAIN
diff --git a/sepolicy/NOTICE b/sepolicy/NOTICE
new file mode 100644
index 0000000..e4ebf52
--- /dev/null
+++ b/sepolicy/NOTICE
@@ -0,0 +1,21 @@
+This configuration (sepolicy) is public domain, i.e. not copyrighted.
+
+Warranty Exclusion
+------------------
+You agree that this software is a
+non-commercially developed program that may contain "bugs" (as that
+term is used in the industry) and that it may not function as intended.
+The software is licensed "as is". NSA makes no, and hereby expressly
+disclaims all, warranties, express, implied, statutory, or otherwise
+with respect to the software, including noninfringement and the implied
+warranties of merchantability and fitness for a particular purpose.
+
+Limitation of Liability
+-----------------------
+In no event will NSA be liable for any damages, including loss of data,
+lost profits, cost of cover, or other special, incidental,
+consequential, direct or indirect damages arising from the software or
+the use thereof, however caused and on any theory of liability. This
+limitation will apply even if NSA has been advised of the possibility
+of such damage. You acknowledge that this is a reasonable allocation of
+risk.
diff --git a/sepolicy/README b/sepolicy/README
new file mode 100644
index 0000000..a3c75b8
--- /dev/null
+++ b/sepolicy/README
@@ -0,0 +1,103 @@
+This directory contains the core Android SELinux policy configuration.
+It defines the domains and types for the AOSP services and apps common to
+all devices.  Device-specific policy should be placed under a
+separate device/<vendor>/<board>/sepolicy subdirectory and linked
+into the policy build as described below.
+
+Policy Generation:
+
+Additional, per device, policy files can be added into the
+policy build. These files should have each line including the
+final line terminated by a newline character (0x0A).  This
+will allow files to be concatenated and processed whenever
+the m4(1) macro processor is called by the build process.
+Adding the newline will also make the intermediate text files
+easier to read when debugging build failures.  The sets of file,
+service and property contexts files will automatically have a
+newline inserted between each file as these are common failure
+points.
+
+These device policy files can be configured through the use of
+the BOARD_SEPOLICY_DIRS variable. This variable should be set
+in the BoardConfig.mk file in the device or vendor directories.
+
+BOARD_SEPOLICY_DIRS contains a list of directories to search
+for additional policy files. Order matters in this list.
+For example, if you have 2 instances of widget.te files in the
+BOARD_SEPOLICY_DIRS search path, then the first one found (at the
+first search dir containing the file) will be concatenated first.
+Reviewing out/target/product/<device>/etc/sepolicy_intermediates/policy.conf
+will help sort out ordering issues.
+
+Example BoardConfig.mk Usage:
+From the Tuna device BoardConfig.mk, device/samsung/tuna/BoardConfig.mk
+
+BOARD_SEPOLICY_DIRS += device/samsung/tuna/sepolicy
+
+Additionally, OEMs can specify BOARD_SEPOLICY_M4DEFS to pass arbitrary m4
+definitions during the build. A definition consists of a string in the form
+of macro-name=value. Spaces must NOT be present. This is useful for building modular
+policies, policy generation, conditional file paths, etc. It is supported in
+the following file types:
+ * All *.te and SE Linux policy files as passed to checkpolicy
+ * file_contexts
+ * service_contexts
+ * property_contexts
+ * keys.conf
+
+Example BoardConfig.mk Usage:
+BOARD_SEPOLICY_M4DEFS += btmodule=foomatic \
+                         btdevice=/dev/gps
+
+SPECIFIC POLICY FILE INFORMATION
+
+mac_permissions.xml:
+  ABOUT:
+    The mac_permissions.xml file is used for controlling the mmac solutions
+    as well as mapping a public base16 signing key with an arbitrary seinfo
+    string. Details of the files contents can be found in a comment at the
+    top of that file. The seinfo string, previously mentioned, is the same string
+    that is referenced in seapp_contexts.
+
+    It is important to note the final processed version of this file
+    is stripped of comments and whitespace. This is to preserve space on the
+    system.img. If one wishes to view it in a more human friendly format,
+    the "tidy" or "xmllint" command will assist you.
+
+  TOOLING:
+    insertkeys.py
+      Is a helper script for mapping arbitrary tags in the signature stanzas of
+      mac_permissions.xml to public keys found in pem files. This script takes
+      a mac_permissions.xml file(s) and configuration file in order to operate.
+      Details of the configuration file (keys.conf) can be found in the subsection
+      keys.conf. This tool is also responsible for stripping the comments and
+      whitespace during processing.
+
+      keys.conf
+        The keys.conf file is used for controlling the mapping of "tags" found in
+        the mac_permissions.xml signature stanzas with actual public keys found in
+        pem files. The configuration file is processed via m4.
+
+        The script allows for mapping any string contained in TARGET_BUILD_VARIANT
+        with specific path to a pem file. Typically TARGET_BUILD_VARIANT is either
+        user, eng or userdebug. Additionally, one can specify "ALL" to map a path to
+        any string specified in TARGET_BUILD_VARIANT. All tags are matched verbatim
+        and all options are matched lowercase. The options are "tolowered" automatically
+        for the user, it is convention to specify tags and options in all uppercase
+        and tags start with @. The option arguments can also use environment variables
+        via the familiar $VARIABLE syntax. This is often useful for setting a location
+        to ones release keys.
+
+        Often times, one will need to integrate an application that was signed by a separate
+        organization and may need to extract the pem file for the insertkeys/keys.conf tools.
+        Extraction of the public key in the pem format is possible via openssl. First you need
+        to unzip the apk, once it is unzipped, cd into the META_INF directory and then execute
+        openssl pkcs7 -inform DER -in CERT.RSA -out CERT.pem -outform PEM  -print_certs
+        On some occasions CERT.RSA has a different name, and you will need to adjust for that.
+        After extracting the pem, you can rename it, and configure keys.conf and
+        mac_permissions.xml to pick up the change. You MUST open the generated pem file in a text
+        editor and strip out anything outside the opening and closing scissor lines. Failure to do
+        so WILL cause a compile time issue thrown by insertkeys.py
+
+        NOTE: The pem files are base64 encoded and PackageManagerService, mac_permissions.xml
+              and setool all use base16 encodings.
diff --git a/sepolicy/access_vectors b/sepolicy/access_vectors
new file mode 100644
index 0000000..26286b2
--- /dev/null
+++ b/sepolicy/access_vectors
@@ -0,0 +1,621 @@
+#
+# Define common prefixes for access vectors
+#
+# common common_name { permission_name ... }
+
+
+#
+# Define a common prefix for file access vectors.
+#
+
+common file
+{
+	ioctl
+	read
+	write
+	create
+	getattr
+	setattr
+	lock
+	relabelfrom
+	relabelto
+	append
+	unlink
+	link
+	rename
+	execute
+	swapon
+	quotaon
+	mounton
+}
+
+
+#
+# Define a common prefix for socket access vectors.
+#
+
+common socket
+{
+# inherited from file
+	ioctl
+	read
+	write
+	create
+	getattr
+	setattr
+	lock
+	relabelfrom
+	relabelto
+	append
+# socket-specific
+	bind
+	connect
+	listen
+	accept
+	getopt
+	setopt
+	shutdown
+	recvfrom
+	sendto
+	recv_msg
+	send_msg
+	name_bind
+}
+
+#
+# Define a common prefix for ipc access vectors.
+#
+
+common ipc
+{
+	create
+	destroy
+	getattr
+	setattr
+	read
+	write
+	associate
+	unix_read
+	unix_write
+}
+
+#
+# Define the access vectors.
+#
+# class class_name [ inherits common_name ] { permission_name ... }
+
+
+#
+# Define the access vector interpretation for file-related objects.
+#
+
+class filesystem
+{
+	mount
+	remount
+	unmount
+	getattr
+	relabelfrom
+	relabelto
+	transition
+	associate
+	quotamod
+	quotaget
+}
+
+class dir
+inherits file
+{
+	add_name
+	remove_name
+	reparent
+	search
+	rmdir
+	open
+	audit_access
+	execmod
+}
+
+class file
+inherits file
+{
+	execute_no_trans
+	entrypoint
+	execmod
+	open
+	audit_access
+}
+
+class lnk_file
+inherits file
+{
+	open
+	audit_access
+	execmod
+}
+
+class chr_file
+inherits file
+{
+	execute_no_trans
+	entrypoint
+	execmod
+	open
+	audit_access
+}
+
+class blk_file
+inherits file
+{
+	open
+	audit_access
+	execmod
+}
+
+class sock_file
+inherits file
+{
+	open
+	audit_access
+	execmod
+}
+
+class fifo_file
+inherits file
+{
+	open
+	audit_access
+	execmod
+}
+
+class fd
+{
+	use
+}
+
+
+#
+# Define the access vector interpretation for network-related objects.
+#
+
+class socket
+inherits socket
+
+class tcp_socket
+inherits socket
+{
+	connectto
+	newconn
+	acceptfrom
+	node_bind
+	name_connect
+}
+
+class udp_socket
+inherits socket
+{
+	node_bind
+}
+
+class rawip_socket
+inherits socket
+{
+	node_bind
+}
+
+class node
+{
+	tcp_recv
+	tcp_send
+	udp_recv
+	udp_send
+	rawip_recv
+	rawip_send
+	enforce_dest
+	dccp_recv
+	dccp_send
+	recvfrom
+	sendto
+}
+
+class netif
+{
+	tcp_recv
+	tcp_send
+	udp_recv
+	udp_send
+	rawip_recv
+	rawip_send
+	dccp_recv
+	dccp_send
+	ingress
+	egress
+}
+
+class netlink_socket
+inherits socket
+
+class packet_socket
+inherits socket
+
+class key_socket
+inherits socket
+
+class unix_stream_socket
+inherits socket
+{
+	connectto
+	newconn
+	acceptfrom
+}
+
+class unix_dgram_socket
+inherits socket
+
+#
+# Define the access vector interpretation for process-related objects
+#
+
+class process
+{
+	fork
+	transition
+	sigchld # commonly granted from child to parent
+	sigkill # cannot be caught or ignored
+	sigstop # cannot be caught or ignored
+	signull # for kill(pid, 0)
+	signal  # all other signals
+	ptrace
+	getsched
+	setsched
+	getsession
+	getpgid
+	setpgid
+	getcap
+	setcap
+	share
+	getattr
+	setexec
+	setfscreate
+	noatsecure
+	siginh
+	setrlimit
+	rlimitinh
+	dyntransition
+	setcurrent
+	execmem
+	execstack
+	execheap
+	setkeycreate
+	setsockcreate
+}
+
+
+#
+# Define the access vector interpretation for ipc-related objects
+#
+
+class ipc
+inherits ipc
+
+class sem
+inherits ipc
+
+class msgq
+inherits ipc
+{
+	enqueue
+}
+
+class msg
+{
+	send
+	receive
+}
+
+class shm
+inherits ipc
+{
+	lock
+}
+
+
+#
+# Define the access vector interpretation for the security server.
+#
+
+class security
+{
+	compute_av
+	compute_create
+	compute_member
+	check_context
+	load_policy
+	compute_relabel
+	compute_user
+	setenforce     # was avc_toggle in system class
+	setbool
+	setsecparam
+	setcheckreqprot
+	read_policy
+}
+
+
+#
+# Define the access vector interpretation for system operations.
+#
+
+class system
+{
+	ipc_info
+	syslog_read
+	syslog_mod
+	syslog_console
+	module_request
+	module_load
+}
+
+#
+# Define the access vector interpretation for controling capabilies
+#
+
+class capability
+{
+	# The capabilities are defined in include/linux/capability.h
+	# Capabilities >= 32 are defined in the capability2 class.
+	# Care should be taken to ensure that these are consistent with
+	# those definitions. (Order matters)
+
+	chown
+	dac_override
+	dac_read_search
+	fowner
+	fsetid
+	kill
+	setgid
+	setuid
+	setpcap
+	linux_immutable
+	net_bind_service
+	net_broadcast
+	net_admin
+	net_raw
+	ipc_lock
+	ipc_owner
+	sys_module
+	sys_rawio
+	sys_chroot
+	sys_ptrace
+	sys_pacct
+	sys_admin
+	sys_boot
+	sys_nice
+	sys_resource
+	sys_time
+	sys_tty_config
+	mknod
+	lease
+	audit_write
+	audit_control
+	setfcap
+}
+
+class capability2
+{
+	mac_override	# unused by SELinux
+	mac_admin	# unused by SELinux
+	syslog
+	wake_alarm
+	block_suspend
+	audit_read
+}
+
+#
+# Extended Netlink classes
+#
+class netlink_route_socket
+inherits socket
+{
+	nlmsg_read
+	nlmsg_write
+}
+
+class netlink_firewall_socket
+inherits socket
+{
+	nlmsg_read
+	nlmsg_write
+}
+
+class netlink_tcpdiag_socket
+inherits socket
+{
+	nlmsg_read
+	nlmsg_write
+}
+
+class netlink_nflog_socket
+inherits socket
+
+class netlink_xfrm_socket
+inherits socket
+{
+	nlmsg_read
+	nlmsg_write
+}
+
+class netlink_selinux_socket
+inherits socket
+
+class netlink_audit_socket
+inherits socket
+{
+	nlmsg_read
+	nlmsg_write
+	nlmsg_relay
+	nlmsg_readpriv
+	nlmsg_tty_audit
+}
+
+class netlink_ip6fw_socket
+inherits socket
+{
+	nlmsg_read
+	nlmsg_write
+}
+
+class netlink_dnrt_socket
+inherits socket
+
+# Define the access vector interpretation for controlling
+# access to IPSec network data by association
+#
+class association
+{
+	sendto
+	recvfrom
+	setcontext
+	polmatch
+}
+
+# Updated Netlink class for KOBJECT_UEVENT family.
+class netlink_kobject_uevent_socket
+inherits socket
+
+class appletalk_socket
+inherits socket
+
+class packet
+{
+	send
+	recv
+	relabelto
+	flow_in		# deprecated
+	flow_out	# deprecated
+	forward_in
+	forward_out
+}
+
+class key
+{
+	view
+	read
+	write
+	search
+	link
+	setattr
+	create
+}
+
+class dccp_socket
+inherits socket
+{
+	node_bind
+	name_connect
+}
+
+class memprotect
+{
+	mmap_zero
+}
+
+# network peer labels
+class peer
+{
+	recv
+}
+
+class kernel_service
+{
+	use_as_override
+	create_files_as
+}
+
+class tun_socket
+inherits socket
+{
+	attach_queue
+}
+
+class binder
+{
+	impersonate
+	call
+	set_context_mgr
+	transfer
+}
+
+class netlink_iscsi_socket
+inherits socket
+
+class netlink_fib_lookup_socket
+inherits socket
+
+class netlink_connector_socket
+inherits socket
+
+class netlink_netfilter_socket
+inherits socket
+
+class netlink_generic_socket
+inherits socket
+
+class netlink_scsitransport_socket
+inherits socket
+
+class netlink_rdma_socket
+inherits socket
+
+class netlink_crypto_socket
+inherits socket
+
+class property_service
+{
+	set
+}
+
+class service_manager
+{
+	add
+	find
+	list
+}
+
+class keystore_key
+{
+	get_state
+	get
+	insert
+	delete
+	exist
+	list
+	reset
+	password
+	lock
+	unlock
+	is_empty
+	sign
+	verify
+	grant
+	duplicate
+	clear_uid
+	add_auth
+	user_changed
+}
+
+class debuggerd
+{
+	dump_tombstone
+	dump_backtrace
+}
+
+class drmservice {
+	consumeRights
+	setPlaybackStatus
+	openDecryptSession
+	closeDecryptSession
+	initializeDecryptUnit
+	decrypt
+	finalizeDecryptUnit
+	pread
+}
diff --git a/sepolicy/adbd.te b/sepolicy/adbd.te
new file mode 100644
index 0000000..217a284
--- /dev/null
+++ b/sepolicy/adbd.te
@@ -0,0 +1,116 @@
+# adbd seclabel is specified in init.rc since
+# it lives in the rootfs and has no unique file type.
+type adbd, domain, mlstrustedsubject;
+
+userdebug_or_eng(`
+  allow adbd self:process setcurrent;
+  allow adbd su:process dyntransition;
+')
+
+domain_auto_trans(adbd, shell_exec, shell)
+
+# Do not sanitize the environment or open fds of the shell. Allow signaling
+# created processes.
+allow adbd shell:process { noatsecure signal };
+
+# Set UID and GID to shell.  Set supplementary groups.
+allow adbd self:capability { setuid setgid };
+
+# Drop capabilities from bounding set on user builds.
+allow adbd self:capability setpcap;
+
+# Create and use network sockets.
+net_domain(adbd)
+
+# Access /dev/android_adb or /dev/usb-ffs/adb/ep0
+allow adbd adb_device:chr_file rw_file_perms;
+allow adbd functionfs:dir search;
+allow adbd functionfs:file rw_file_perms;
+
+# Use a pseudo tty.
+allow adbd devpts:chr_file rw_file_perms;
+
+# adb push/pull /data/local/tmp.
+allow adbd shell_data_file:dir create_dir_perms;
+allow adbd shell_data_file:file create_file_perms;
+
+# adb push/pull sdcard.
+allow adbd tmpfs:dir search;
+allow adbd rootfs:lnk_file r_file_perms;
+allow adbd sdcard_type:dir create_dir_perms;
+allow adbd sdcard_type:file create_file_perms;
+
+# adb pull /data/anr/traces.txt
+allow adbd anr_data_file:dir r_dir_perms;
+allow adbd anr_data_file:file r_file_perms;
+
+# Set service.adb.*, sys.powerctl, and sys.usb.ffs.ready properties.
+set_prop(adbd, shell_prop)
+set_prop(adbd, powerctl_prop)
+set_prop(adbd, ffs_prop)
+
+# Access device logging gating property
+get_prop(adbd, device_logging_prop)
+
+# Run /system/bin/bu
+allow adbd system_file:file rx_file_perms;
+
+# Perform binder IPC to surfaceflinger (screencap)
+# XXX Run screencap in a separate domain?
+binder_use(adbd)
+binder_call(adbd, surfaceflinger)
+# b/13188914
+allow adbd gpu_device:chr_file rw_file_perms;
+allow adbd ion_device:chr_file rw_file_perms;
+r_dir_file(adbd, system_file)
+
+# Read /data/misc/adb/adb_keys.
+allow adbd adb_keys_file:dir search;
+allow adbd adb_keys_file:file r_file_perms;
+
+userdebug_or_eng(`
+  # Write debugging information to /data/adb
+  # when persist.adb.trace_mask is set
+  # https://code.google.com/p/android/issues/detail?id=72895
+  allow adbd adb_data_file:dir rw_dir_perms;
+  allow adbd adb_data_file:file create_file_perms;
+')
+
+# ndk-gdb invokes adb forward to forward the gdbserver socket.
+allow adbd app_data_file:dir search;
+allow adbd app_data_file:sock_file write;
+allow adbd appdomain:unix_stream_socket connectto;
+
+# ndk-gdb invokes adb pull of app_process, linker, and libc.so.
+allow adbd zygote_exec:file r_file_perms;
+allow adbd system_file:file r_file_perms;
+
+# Allow pulling the SELinux policy for CTS purposes
+allow adbd selinuxfs:dir r_dir_perms;
+allow adbd selinuxfs:file r_file_perms;
+allow adbd kernel:security read_policy;
+
+allow adbd surfaceflinger_service:service_manager find;
+allow adbd bootchart_data_file:dir search;
+allow adbd bootchart_data_file:file r_file_perms;
+
+# Allow access to external storage; we have several visible mount points under /storage
+# and symlinks to primary storage at places like /storage/sdcard0 and /mnt/user/0/primary
+allow adbd storage_file:dir r_dir_perms;
+allow adbd storage_file:lnk_file r_file_perms;
+allow adbd mnt_user_file:dir r_dir_perms;
+allow adbd mnt_user_file:lnk_file r_file_perms;
+
+r_dir_file(adbd, apk_data_file)
+
+allow adbd rootfs:dir r_dir_perms;
+
+###
+### Neverallow rules
+###
+
+# No transitions from adbd to non-shell domains. adbd only ever
+# transitions to the shell domain. In particular, we never want
+# to see a transition from adbd to su (aka "adb root")
+neverallow adbd { domain -shell }:process transition;
+neverallow adbd { domain -su }:process dyntransition;
diff --git a/sepolicy/app.te b/sepolicy/app.te
new file mode 100644
index 0000000..34c4bdb
--- /dev/null
+++ b/sepolicy/app.te
@@ -0,0 +1,413 @@
+###
+### Domain for all zygote spawned apps
+###
+### This file is the base policy for all zygote spawned apps.
+### Other policy files, such as isolated_app.te, untrusted_app.te, etc
+### extend from this policy. Only policies which should apply to ALL
+### zygote spawned apps should be added here.
+###
+
+# WebView and other application-specific JIT compilers
+allow appdomain self:process execmem;
+
+allow appdomain ashmem_device:chr_file execute;
+
+# Receive and use open file descriptors inherited from zygote.
+allow appdomain zygote:fd use;
+
+# gdbserver for ndk-gdb reads the zygote.
+# valgrind needs mmap exec for zygote
+allow appdomain zygote_exec:file rx_file_perms;
+
+# Read system properties managed by zygote.
+allow appdomain zygote_tmpfs:file read;
+
+# Notify zygote of death;
+allow appdomain zygote:process sigchld;
+
+# Place process into foreground / background
+allow appdomain cgroup:dir { search write };
+allow appdomain cgroup:file w_file_perms;
+
+# Read /data/dalvik-cache.
+allow appdomain dalvikcache_data_file:dir { search getattr };
+allow appdomain dalvikcache_data_file:file r_file_perms;
+
+# Read the /sdcard symlink
+allow appdomain rootfs:lnk_file r_file_perms;
+
+# Search /storage/emulated tmpfs mount.
+allow appdomain tmpfs:dir r_dir_perms;
+
+userdebug_or_eng(`
+  # Notify zygote of the wrapped process PID when using --invoke-with.
+  allow appdomain zygote:fifo_file write;
+
+  # Allow apps to create and write method traces in /data/misc/trace.
+  allow appdomain method_trace_data_file:dir w_dir_perms;
+  allow appdomain method_trace_data_file:file { create w_file_perms };
+')
+
+# Notify shell and adbd of death when spawned via runas for ndk-gdb.
+allow appdomain shell:process sigchld;
+allow appdomain adbd:process sigchld;
+
+# child shell or gdbserver pty access for runas.
+allow appdomain devpts:chr_file { getattr read write ioctl };
+
+# Use pipes and sockets provided by system_server via binder or local socket.
+allow appdomain system_server:fifo_file rw_file_perms;
+allow appdomain system_server:unix_stream_socket { read write setopt getattr getopt shutdown };
+allow appdomain system_server:tcp_socket { read write getattr getopt shutdown };
+
+# Communication with other apps via fifos
+allow appdomain appdomain:fifo_file rw_file_perms;
+
+# Communicate with surfaceflinger.
+allow appdomain surfaceflinger:unix_stream_socket { read write setopt getattr getopt shutdown };
+
+# App sandbox file accesses.
+allow { appdomain -isolated_app } app_data_file:dir create_dir_perms;
+allow { appdomain -isolated_app } app_data_file:notdevfile_class_set create_file_perms;
+
+# Traverse into expanded storage
+allow appdomain mnt_expand_file:dir r_dir_perms;
+
+# Keychain and user-trusted credentials
+allow appdomain keychain_data_file:dir r_dir_perms;
+allow appdomain keychain_data_file:file r_file_perms;
+allow appdomain misc_user_data_file:dir r_dir_perms;
+allow appdomain misc_user_data_file:file r_file_perms;
+
+# Access to OEM provided data and apps
+allow appdomain oemfs:dir r_dir_perms;
+allow appdomain oemfs:file rx_file_perms;
+
+# Execute the shell or other system executables.
+allow appdomain shell_exec:file rx_file_perms;
+allow appdomain system_file:file rx_file_perms;
+allow appdomain toolbox_exec:file rx_file_perms;
+
+# Renderscript needs the ability to read directories on /system
+r_dir_file(appdomain, system_file)
+
+# Execute dex2oat when apps call dexclassloader
+allow appdomain dex2oat_exec:file rx_file_perms;
+
+# Read/write wallpaper file (opened by system).
+allow appdomain wallpaper_file:file { getattr read write };
+
+# Write to /data/anr/traces.txt.
+allow appdomain anr_data_file:dir search;
+allow appdomain anr_data_file:file { open append };
+
+# Allow apps to send dump information to dumpstate
+allow appdomain dumpstate:fd use;
+allow appdomain dumpstate:unix_stream_socket { read write getopt getattr shutdown };
+allow appdomain shell_data_file:file { write getattr };
+
+# Send heap dumps to system_server via an already open file descriptor
+# % adb shell am set-watch-heap com.android.systemui 1048576
+# % adb shell dumpsys procstats --start-testing
+# debuggable builds only.
+userdebug_or_eng(`
+  allow appdomain heapdump_data_file:file append;
+')
+
+# Write to /proc/net/xt_qtaguid/ctrl file.
+allow appdomain qtaguid_proc:file rw_file_perms;
+# Everybody can read the xt_qtaguid resource tracking misc dev.
+# So allow all apps to read from /dev/xt_qtaguid.
+allow appdomain qtaguid_device:chr_file r_file_perms;
+
+# Grant GPU access to all processes started by Zygote.
+# They need that to render the standard UI.
+allow { appdomain -isolated_app } gpu_device:chr_file rw_file_perms;
+
+# Use the Binder.
+binder_use(appdomain)
+# Perform binder IPC to binder services.
+binder_call(appdomain, binderservicedomain)
+# Perform binder IPC to other apps.
+binder_call(appdomain, appdomain)
+
+# Already connected, unnamed sockets being passed over some other IPC
+# hence no sock_file or connectto permission. This appears to be how
+# Chrome works, may need to be updated as more apps using isolated services
+# are examined.
+allow appdomain appdomain:unix_stream_socket { getopt getattr read write shutdown };
+
+# Backup ability for every app. BMS opens and passes the fd
+# to any app that has backup ability. Hence, no open permissions here.
+allow appdomain backup_data_file:file { read write getattr };
+allow appdomain cache_backup_file:file { read write getattr };
+allow appdomain cache_backup_file:dir getattr;
+# Backup ability using 'adb backup'
+allow appdomain system_data_file:lnk_file getattr;
+
+# Allow read/stat of /data/media files passed by Binder or local socket IPC.
+allow appdomain media_rw_data_file:file { read getattr };
+
+# Read and write /data/data/com.android.providers.telephony files passed over Binder.
+allow appdomain radio_data_file:file { read write getattr };
+
+# Allow access to external storage; we have several visible mount points under /storage
+# and symlinks to primary storage at places like /storage/sdcard0 and /mnt/user/0/primary
+allow appdomain storage_file:dir r_dir_perms;
+allow appdomain storage_file:lnk_file r_file_perms;
+allow appdomain mnt_user_file:dir r_dir_perms;
+allow appdomain mnt_user_file:lnk_file r_file_perms;
+
+# Read/write visible storage
+allow appdomain fuse:dir create_dir_perms;
+allow appdomain fuse:file create_file_perms;
+allow appdomain sdcardfs:dir create_dir_perms;
+allow appdomain sdcardfs:file create_file_perms;
+
+# Access OBBs (vfat images) mounted by vold (b/17633509)
+# File write access allowed for FDs returned through Storage Access Framework
+allow appdomain vfat:dir r_dir_perms;
+allow appdomain vfat:file rw_file_perms;
+
+# Allow apps to use the USB Accessory interface.
+# http://developer.android.com/guide/topics/connectivity/usb/accessory.html
+#
+# USB devices are first opened by the system server (USBDeviceManagerService)
+# and the file descriptor is passed to the right Activity via binder.
+allow appdomain usb_device:chr_file { read write getattr ioctl };
+allow appdomain usbaccessory_device:chr_file { read write getattr };
+
+# For art.
+allow appdomain dalvikcache_data_file:file execute;
+allow appdomain dalvikcache_data_file:lnk_file r_file_perms;
+
+# Allow any app to read shared RELRO files.
+allow appdomain shared_relro_file:dir search;
+allow appdomain shared_relro_file:file r_file_perms;
+
+# Allow apps to read/execute installed binaries
+allow appdomain apk_data_file:dir r_dir_perms;
+allow appdomain apk_data_file:file { rx_file_perms execmod };
+
+# /data/resource-cache
+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 { get_state get insert delete exist list sign verify };
+
+use_keystore({ appdomain -isolated_app })
+
+allow appdomain console_device:chr_file { read write };
+
+allow { appdomain -isolated_app } ion_device:chr_file rw_file_perms;
+
+# TODO: switch to meminfo service
+allow appdomain proc_meminfo:file r_file_perms;
+
+# For app fuse.
+allow appdomain app_fuse_file:file { getattr read append write };
+
+###
+### CTS-specific rules
+###
+
+# For cts/tests/tests/permission/src/android/permission/cts/FileSystemPermissionTest.java.
+# testRunAsHasCorrectCapabilities
+allow appdomain runas_exec:file getattr;
+# Others are either allowed elsewhere or not desired.
+
+# For cts/tests/tests/security/src/android/security/cts/SELinuxTest.java
+# Check SELinux policy and contexts.
+selinux_check_access(appdomain)
+selinux_check_context(appdomain)
+
+# Apps receive an open tun fd from the framework for
+# device traffic. Do not allow untrusted app to directly open tun_device
+allow { appdomain -isolated_app } tun_device:chr_file { read write getattr ioctl append };
+
+# Connect to adbd and use a socket transferred from it.
+# This is used for e.g. adb backup/restore.
+allow appdomain adbd:unix_stream_socket connectto;
+allow appdomain adbd:fd use;
+allow appdomain adbd:unix_stream_socket { getattr getopt ioctl read write shutdown };
+
+allow appdomain cache_file:dir getattr;
+
+###
+### Neverallow rules
+###
+### These are things that Android apps should NEVER be able to do
+###
+
+# Superuser capabilities.
+# bluetooth requires net_admin and wake_alarm.
+neverallow { appdomain -bluetooth -su } self:capability *;
+neverallow { appdomain -bluetooth } self:capability2 *;
+
+# Block device access.
+neverallow appdomain dev_type:blk_file { read write };
+
+# Access to any of the following character devices.
+neverallow appdomain {
+    audio_device
+    camera_device
+    dm_device
+    radio_device
+    rpmsg_device
+    video_device
+}:chr_file { read write };
+
+# Note: Try expanding list of app domains in the future.
+neverallow { untrusted_app isolated_app shell } graphics_device:chr_file { read write };
+
+neverallow { appdomain -nfc } nfc_device:chr_file
+    { read write };
+neverallow { appdomain -bluetooth } hci_attach_dev:chr_file
+    { read write };
+neverallow appdomain tee_device:chr_file { read write };
+
+# Privileged netlink socket interfaces.
+neverallow appdomain
+    domain:{
+        netlink_firewall_socket
+        netlink_tcpdiag_socket
+        netlink_nflog_socket
+        netlink_xfrm_socket
+        netlink_audit_socket
+        netlink_ip6fw_socket
+        netlink_dnrt_socket
+    } *;
+
+# These messages are broadcast messages from the kernel to userspace.
+# Do not allow the writing of netlink messages, which has been a source
+# of rooting vulns in the past.
+neverallow appdomain domain:netlink_kobject_uevent_socket { write append };
+
+# Sockets under /dev/socket that are not specifically typed.
+neverallow appdomain socket_device:sock_file write;
+
+# Unix domain sockets.
+neverallow appdomain adbd_socket:sock_file write;
+neverallow appdomain installd_socket:sock_file write;
+neverallow { appdomain -radio } rild_socket:sock_file write;
+neverallow appdomain vold_socket:sock_file write;
+neverallow appdomain zygote_socket:sock_file write;
+
+# ptrace access to non-app domains.
+neverallow appdomain { domain -appdomain }:process ptrace;
+
+# Write access to /proc/pid entries for any non-app domain.
+neverallow appdomain { domain -appdomain }:file write;
+
+# signal access to non-app domains.
+# sigchld allowed for parent death notification.
+# signull allowed for kill(pid, 0) existence test.
+# All others prohibited.
+neverallow appdomain { domain -appdomain }:process
+    { sigkill sigstop signal };
+
+# Transition to a non-app domain.
+# Exception for the shell domain and the su domain, can transition to runas,
+# etc.
+neverallow { appdomain -shell userdebug_or_eng(`-su') } { domain -appdomain }:process
+    { transition dyntransition };
+
+# Write to rootfs.
+neverallow appdomain rootfs:dir_file_class_set
+    { create write setattr relabelfrom relabelto append unlink link rename };
+
+# Write to /system.
+neverallow appdomain system_file:dir_file_class_set
+    { create write setattr relabelfrom relabelto append unlink link rename };
+
+# Write to entrypoint executables.
+neverallow appdomain exec_type:file
+    { create write setattr relabelfrom relabelto append unlink link rename };
+
+# Write to system-owned parts of /data.
+# This is the default type for anything under /data not otherwise
+# specified in file_contexts.  Define a different type for portions
+# that should be writable by apps.
+neverallow appdomain system_data_file:dir_file_class_set
+    { create write setattr relabelfrom relabelto append unlink link rename };
+
+# Write to various other parts of /data.
+neverallow appdomain drm_data_file:dir_file_class_set
+    { create write setattr relabelfrom relabelto append unlink link rename };
+neverallow { appdomain -platform_app }
+    apk_data_file:dir_file_class_set
+    { create write setattr relabelfrom relabelto append unlink link rename };
+neverallow { appdomain -platform_app }
+    apk_tmp_file:dir_file_class_set
+    { create write setattr relabelfrom relabelto append unlink link rename };
+neverallow { appdomain -platform_app }
+    apk_private_data_file:dir_file_class_set
+    { create write setattr relabelfrom relabelto append unlink link rename };
+neverallow { appdomain -platform_app }
+    apk_private_tmp_file:dir_file_class_set
+    { create write setattr relabelfrom relabelto append unlink link rename };
+neverallow { appdomain -shell -su }
+    shell_data_file:dir_file_class_set
+    { create setattr relabelfrom relabelto append unlink link rename };
+neverallow { appdomain -bluetooth -su }
+    bluetooth_data_file:dir_file_class_set
+    { create write setattr relabelfrom relabelto append unlink link rename };
+neverallow appdomain
+    keystore_data_file:dir_file_class_set
+    { create write setattr relabelfrom relabelto append unlink link rename };
+neverallow appdomain
+    systemkeys_data_file:dir_file_class_set
+    { create write setattr relabelfrom relabelto append unlink link rename };
+neverallow appdomain
+    wifi_data_file:dir_file_class_set
+    { create write setattr relabelfrom relabelto append unlink link rename };
+neverallow appdomain
+    dhcp_data_file:dir_file_class_set
+    { create write setattr relabelfrom relabelto append unlink link rename };
+
+# access tmp apk files
+neverallow { appdomain -platform_app -priv_app }
+    { apk_tmp_file apk_private_tmp_file }:dir_file_class_set *;
+
+# Access to factory files.
+neverallow appdomain efs_file:dir_file_class_set write;
+neverallow { appdomain -shell } efs_file:dir_file_class_set read;
+
+# Write to various pseudo file systems.
+neverallow { appdomain -bluetooth -nfc }
+    sysfs:dir_file_class_set write;
+neverallow appdomain
+    proc:dir_file_class_set write;
+
+# Access to syslog(2) or /proc/kmsg.
+neverallow { appdomain -system_app }
+    kernel:system { syslog_mod syslog_console };
+neverallow { appdomain -system_app -shell -su }
+    kernel:system syslog_read;
+
+# Ability to perform any filesystem operation other than statfs(2).
+# i.e. no mount(2), unmount(2), etc.
+neverallow appdomain fs_type:filesystem ~getattr;
+
+# prevent creation/manipulation of globally readable symlinks
+neverallow appdomain {
+  apk_data_file
+  cache_file
+  cache_recovery_file
+  dev_type
+  rootfs
+  system_file
+  tmpfs
+}:lnk_file no_w_file_perms;
+
+# Applications should use the activity model for receiving events
+neverallow {
+  appdomain
+  -shell # bugreport
+} input_device:chr_file ~getattr;
diff --git a/sepolicy/atrace.te b/sepolicy/atrace.te
new file mode 100644
index 0000000..31cf9e7
--- /dev/null
+++ b/sepolicy/atrace.te
@@ -0,0 +1,24 @@
+# Domain for atrace process spawned by boottrace service.
+type atrace_exec, exec_type, file_type;
+
+userdebug_or_eng(`
+
+  type atrace, domain, domain_deprecated;
+  init_daemon_domain(atrace)
+
+  # boottrace services uses /data/misc/boottrace/categories
+  allow atrace boottrace_data_file:dir search;
+  allow atrace boottrace_data_file:file r_file_perms;
+
+  # atrace reads the files in /sys/kernel/debug/tracing/
+  allow atrace debugfs_tracing:file r_file_perms;
+
+  # atrace sets debug.atrace.* properties
+  set_prop(atrace, debug_prop)
+
+  # atrace pokes all the binder-enabled processes at startup.
+  binder_use(atrace)
+  allow atrace healthd:binder call;
+  allow atrace surfaceflinger:binder call;
+
+')
diff --git a/sepolicy/attributes b/sepolicy/attributes
new file mode 100644
index 0000000..052f0dd
--- /dev/null
+++ b/sepolicy/attributes
@@ -0,0 +1,112 @@
+######################################
+# Attribute declarations
+#
+
+# All types used for devices.
+# On change, update CHECK_FC_ASSERT_ATTRS
+# in tools/checkfc.c
+attribute dev_type;
+
+# All types used for processes.
+attribute domain;
+
+# Temporary attribute used for migrating permissions out of domain.
+# Motivation: Domain is overly permissive. Start removing permissions
+# from domain and assign them to the domain_deprecated attribute.
+# Domain_deprecated and domain can initially be assigned to all
+# domains. The goal is to not assign domain_deprecated to new domains
+# and to start removing domain_deprecated where it's not required or
+# reassigning the appropriate permissions to the inheriting domain
+# when necessary.
+attribute domain_deprecated;
+
+# All types used for filesystems.
+# On change, update CHECK_FC_ASSERT_ATTRS
+# definition in tools/checkfc.c.
+attribute fs_type;
+
+# All types used for context= mounts.
+attribute contextmount_type;
+
+# All types used for files that can exist on a labeled fs.
+# Do not use for pseudo file types.
+# On change, update CHECK_FC_ASSERT_ATTRS
+# definition in tools/checkfc.c.
+attribute file_type;
+
+# All types used for domain entry points.
+attribute exec_type;
+
+# All types used for /data files.
+attribute data_file_type;
+
+# All types use for sysfs files.
+attribute sysfs_type;
+
+# All types use for debugfs files.
+attribute debugfs_type;
+
+# Attribute used for all sdcards
+attribute sdcard_type;
+
+# All types used for nodes/hosts.
+attribute node_type;
+
+# All types used for network interfaces.
+attribute netif_type;
+
+# All types used for network ports.
+attribute port_type;
+
+# All types used for property service
+# On change, update CHECK_PC_ASSERT_ATTRS
+# definition in tools/checkfc.c.
+attribute property_type;
+
+# All properties defined in core SELinux policy. Should not be
+# used by device specific properties
+attribute core_property_type;
+
+# All service_manager types created by system_server
+attribute system_server_service;
+
+# services which should be available to all but isolated apps
+attribute app_api_service;
+
+# services which export only system_api
+attribute system_api_service;
+
+# All types used for services managed by service_manager.
+# On change, update CHECK_SC_ASSERT_ATTRS
+# definition in tools/checkfc.c.
+attribute service_manager_type;
+
+# All domains that can override MLS restrictions.
+# i.e. processes that can read up and write down.
+attribute mlstrustedsubject;
+
+# All types that can override MLS restrictions.
+# i.e. files that can be read by lower and written by higher
+attribute mlstrustedobject;
+
+# All domains used for apps.
+attribute appdomain;
+
+# All domains used for apps with network access.
+attribute netdomain;
+
+# All domains used for apps with bluetooth access.
+attribute bluetoothdomain;
+
+# All domains used for binder service domains.
+attribute binderservicedomain;
+
+# All domains that access the boot_control HAL. The permissions the HAL
+# requires are specific to the implementation provided in each device, but
+# common daemons need to be aware of those when calling into the HAL.
+attribute boot_control_hal;
+
+# update_engine related domains that need to apply an update and run
+# postinstall. This includes the background daemon and the sideload tool from
+# recovery for A/B devices.
+attribute update_engine_common;
diff --git a/sepolicy/binderservicedomain.te b/sepolicy/binderservicedomain.te
new file mode 100644
index 0000000..36993eb
--- /dev/null
+++ b/sepolicy/binderservicedomain.te
@@ -0,0 +1,21 @@
+# Rules common to all binder service domains
+
+# Allow dumpstate to collect information from binder services
+allow binderservicedomain dumpstate:fd use;
+allow binderservicedomain dumpstate:unix_stream_socket { read write getopt getattr };
+allow binderservicedomain shell_data_file:file { getattr write };
+
+# Allow dumpsys to work from adb shell or the serial console
+allow binderservicedomain devpts:chr_file rw_file_perms;
+allow binderservicedomain console_device:chr_file rw_file_perms;
+
+# Receive and write to a pipe received over Binder from an app.
+allow binderservicedomain appdomain:fd use;
+allow binderservicedomain appdomain:fifo_file write;
+
+# allow all services to run permission checks
+allow binderservicedomain permission_service:service_manager find;
+
+allow binderservicedomain keystore:keystore_key { get_state get insert delete exist list sign verify };
+
+use_keystore(binderservicedomain)
diff --git a/sepolicy/blkid.te b/sepolicy/blkid.te
new file mode 100644
index 0000000..43bc944
--- /dev/null
+++ b/sepolicy/blkid.te
@@ -0,0 +1,20 @@
+# blkid called from vold
+type blkid, domain, domain_deprecated;
+type blkid_exec, exec_type, file_type;
+
+# Allowed read-only access to encrypted devices to extract UUID/label
+allow blkid block_device:dir search;
+allow blkid userdata_block_device:blk_file r_file_perms;
+allow blkid dm_device:blk_file r_file_perms;
+
+# Allow stdin/out back to vold
+allow blkid vold:fd use;
+allow blkid vold:fifo_file { read write getattr };
+
+# For blkid launched through popen()
+allow blkid blkid_exec:file rx_file_perms;
+
+# Only allow entry from vold
+neverallow { domain -vold } blkid:process transition;
+neverallow * blkid:process dyntransition;
+neverallow blkid { file_type fs_type -blkid_exec -shell_exec }:file entrypoint;
diff --git a/sepolicy/blkid_untrusted.te b/sepolicy/blkid_untrusted.te
new file mode 100644
index 0000000..da3bdac
--- /dev/null
+++ b/sepolicy/blkid_untrusted.te
@@ -0,0 +1,36 @@
+# blkid for untrusted block devices
+type blkid_untrusted, domain, domain_deprecated;
+
+# Allowed read-only access to vold block devices to extract UUID/label
+allow blkid_untrusted block_device:dir search;
+allow blkid_untrusted vold_device:blk_file r_file_perms;
+
+# Allow stdin/out back to vold
+allow blkid_untrusted vold:fd use;
+allow blkid_untrusted vold:fifo_file { read write getattr };
+
+# For blkid launched through popen()
+allow blkid_untrusted blkid_exec:file rx_file_perms;
+
+###
+### neverallow rules
+###
+
+# Untrusted blkid should never be run on block devices holding sensitive data
+neverallow blkid_untrusted {
+  boot_block_device
+  frp_block_device
+  metadata_block_device
+  recovery_block_device
+  root_block_device
+  swap_block_device
+  system_block_device
+  userdata_block_device
+  cache_block_device
+  dm_device
+}:blk_file no_rw_file_perms;
+
+# Only allow entry from vold via blkid binary
+neverallow { domain -vold } blkid_untrusted:process transition;
+neverallow * blkid_untrusted:process dyntransition;
+neverallow blkid_untrusted { file_type fs_type -blkid_exec -shell_exec }:file entrypoint;
diff --git a/sepolicy/bluetooth.te b/sepolicy/bluetooth.te
new file mode 100644
index 0000000..f249e9b
--- /dev/null
+++ b/sepolicy/bluetooth.te
@@ -0,0 +1,64 @@
+# bluetooth subsystem
+type bluetooth, domain, domain_deprecated;
+app_domain(bluetooth)
+net_domain(bluetooth)
+
+wakelock_use(bluetooth);
+
+# Data file accesses.
+allow bluetooth bluetooth_data_file:dir create_dir_perms;
+allow bluetooth bluetooth_data_file:notdevfile_class_set create_file_perms;
+
+# Socket creation under /data/misc/bluedroid.
+type_transition bluetooth bluetooth_data_file:sock_file bluetooth_socket;
+allow bluetooth bluetooth_socket:sock_file create_file_perms;
+
+# bluetooth factory file accesses.
+r_dir_file(bluetooth, bluetooth_efs_file)
+
+allow bluetooth { uhid_device hci_attach_dev }:chr_file rw_file_perms;
+
+# sysfs access.
+allow bluetooth sysfs_bluetooth_writable:file rw_file_perms;
+allow bluetooth self:capability net_admin;
+allow bluetooth self:capability2 wake_alarm;
+
+# tethering
+allow bluetooth self:tun_socket create_socket_perms;
+allow bluetooth tun_device:chr_file rw_file_perms;
+allow bluetooth efs_file:dir search;
+
+# proc access.
+allow bluetooth proc_bluetooth_writable:file rw_file_perms;
+
+# Allow write access to bluetooth specific properties
+set_prop(bluetooth, bluetooth_prop)
+set_prop(bluetooth, pan_result_prop)
+set_prop(bluetooth, ctl_dhcp_pan_prop)
+
+allow bluetooth bluetooth_service:service_manager find;
+allow bluetooth drmserver_service:service_manager find;
+allow bluetooth mediaserver_service:service_manager find;
+allow bluetooth radio_service:service_manager find;
+allow bluetooth surfaceflinger_service:service_manager find;
+allow bluetooth app_api_service:service_manager find;
+allow bluetooth system_api_service:service_manager find;
+
+# Bluetooth Sim Access Profile Socket to the RIL
+unix_socket_connect(bluetooth, sap_uim, rild)
+
+# already open bugreport file descriptors may be shared with
+# the bluetooth process, from a file in
+# /data/data/com.android.shell/files/bugreports/bugreport-*.
+allow bluetooth shell_data_file:file read;
+
+###
+### Neverallow rules
+###
+### These are things that the bluetooth app should NEVER be able to do
+###
+
+# Superuser capabilities.
+# bluetooth requires net_admin, wake_alarm and block_suspend
+neverallow bluetooth self:capability ~net_admin;
+neverallow bluetooth self:capability2 ~{ wake_alarm block_suspend };
diff --git a/sepolicy/bluetoothdomain.te b/sepolicy/bluetoothdomain.te
new file mode 100644
index 0000000..fe4f0e6
--- /dev/null
+++ b/sepolicy/bluetoothdomain.te
@@ -0,0 +1,2 @@
+# Allow clients to use a socket provided by the bluetooth app.
+allow bluetoothdomain bluetooth:unix_stream_socket { getopt setopt getattr read write ioctl shutdown };
diff --git a/sepolicy/boot_control_hal.te b/sepolicy/boot_control_hal.te
new file mode 100644
index 0000000..2a670b3
--- /dev/null
+++ b/sepolicy/boot_control_hal.te
@@ -0,0 +1,2 @@
+# Allow read/write bootctrl block device, if one is defined.
+allow boot_control_hal bootctrl_block_device:blk_file rw_file_perms;
diff --git a/sepolicy/bootanim.te b/sepolicy/bootanim.te
new file mode 100644
index 0000000..fa0e4dc
--- /dev/null
+++ b/sepolicy/bootanim.te
@@ -0,0 +1,30 @@
+# bootanimation oneshot service
+type bootanim, domain;
+type bootanim_exec, exec_type, file_type;
+
+init_daemon_domain(bootanim)
+
+binder_use(bootanim)
+binder_call(bootanim, surfaceflinger)
+
+allow bootanim gpu_device:chr_file rw_file_perms;
+
+# /oem access
+allow bootanim oemfs:dir search;
+allow bootanim oemfs:file r_file_perms;
+
+allow bootanim audio_device:dir r_dir_perms;
+allow bootanim audio_device:chr_file rw_file_perms;
+
+allow bootanim surfaceflinger_service:service_manager find;
+
+# Allow access to ion memory allocation device
+allow bootanim ion_device:chr_file rw_file_perms;
+
+# Read access to pseudo filesystems.
+r_dir_file(bootanim, proc)
+r_dir_file(bootanim, sysfs)
+r_dir_file(bootanim, cgroup)
+
+# System file accesses.
+allow bootanim system_file:dir r_dir_perms;
diff --git a/sepolicy/bootstat.te b/sepolicy/bootstat.te
new file mode 100644
index 0000000..44a8c91
--- /dev/null
+++ b/sepolicy/bootstat.te
@@ -0,0 +1,12 @@
+# bootstat command
+type bootstat, domain;
+type bootstat_exec, exec_type, file_type;
+
+init_daemon_domain(bootstat)
+
+# Allow persistent storage in /data/misc/bootstat.
+allow bootstat bootstat_data_file:dir rw_dir_perms;
+allow bootstat bootstat_data_file:file create_file_perms;
+
+# Read access to pseudo filesystems (for /proc/uptime).
+r_dir_file(bootstat, proc)
\ No newline at end of file
diff --git a/sepolicy/clatd.te b/sepolicy/clatd.te
new file mode 100644
index 0000000..3cda6a2
--- /dev/null
+++ b/sepolicy/clatd.te
@@ -0,0 +1,31 @@
+# 464xlat daemon
+type clatd, domain, domain_deprecated;
+type clatd_exec, exec_type, file_type;
+
+net_domain(clatd)
+
+# Access objects inherited from netd.
+allow clatd netd:fd use;
+allow clatd netd:fifo_file { read write };
+# TODO: Check whether some or all of these sockets should be close-on-exec.
+allow clatd netd:netlink_kobject_uevent_socket { read write };
+allow clatd netd:netlink_nflog_socket { read write };
+allow clatd netd:netlink_route_socket { read write };
+allow clatd netd:udp_socket { read write };
+allow clatd netd:unix_stream_socket { read write };
+allow clatd netd:unix_dgram_socket { read write };
+
+allow clatd self:capability { net_admin net_raw setuid setgid };
+
+# clatd calls mmap(MAP_LOCKED) with a 1M buffer. MAP_LOCKED first checks
+# capable(CAP_IPC_LOCK), and then checks to see the requested amount is
+# under RLIMIT_MEMLOCK. If the latter check succeeds clatd won't have
+# needed CAP_IPC_LOCK. But this is not guaranteed to succeed on all devices
+# so we permit any requests we see from clatd asking for this capability.
+# See https://android-review.googlesource.com/127940 and
+# https://b.corp.google.com/issues/21736319
+allow clatd self:capability ipc_lock;
+
+allow clatd self:netlink_route_socket nlmsg_write;
+allow clatd self:{ packet_socket rawip_socket tun_socket } create_socket_perms;
+allow clatd tun_device:chr_file rw_file_perms;
diff --git a/sepolicy/debuggerd.te b/sepolicy/debuggerd.te
new file mode 100644
index 0000000..04dcb79
--- /dev/null
+++ b/sepolicy/debuggerd.te
@@ -0,0 +1,38 @@
+# debugger interface
+type debuggerd, domain, domain_deprecated;
+type debuggerd_exec, exec_type, file_type;
+
+init_daemon_domain(debuggerd)
+typeattribute debuggerd mlstrustedsubject;
+allow debuggerd self:capability { dac_override sys_ptrace chown kill fowner setuid setgid };
+allow debuggerd self:capability2 { syslog };
+allow debuggerd domain:dir r_dir_perms;
+allow debuggerd domain:file r_file_perms;
+allow debuggerd domain:lnk_file read;
+allow debuggerd { domain -init -ueventd -watchdogd -healthd -adbd -keystore }:process { ptrace getattr };
+allow debuggerd tombstone_data_file:dir rw_dir_perms;
+allow debuggerd tombstone_data_file:file create_file_perms;
+allow debuggerd shared_relro_file:dir r_dir_perms;
+allow debuggerd shared_relro_file:file r_file_perms;
+allow debuggerd domain:process { sigstop sigkill signal };
+allow debuggerd exec_type:file r_file_perms;
+# Access app library
+allow debuggerd system_data_file:file open;
+# Allow debuggerd to redirect a dump_backtrace request to itself.
+# This only happens on 64 bit systems, where all requests go to the 64 bit
+# debuggerd and get redirected to the 32 bit debuggerd if the process is 32 bit.
+allow debuggerd { drmserver mediaserver sdcardd surfaceflinger inputflinger }:debuggerd dump_backtrace;
+
+# Connect to system_server via /data/system/ndebugsocket.
+unix_socket_connect(debuggerd, system_ndebug, system_server)
+
+userdebug_or_eng(`
+  allow debuggerd input_device:dir r_dir_perms;
+  allow debuggerd input_device:chr_file rw_file_perms;
+')
+
+# logd access
+read_logd(debuggerd)
+
+# Check SELinux permissions.
+selinux_check_access(debuggerd)
diff --git a/sepolicy/device.te b/sepolicy/device.te
new file mode 100644
index 0000000..e4a792e
--- /dev/null
+++ b/sepolicy/device.te
@@ -0,0 +1,101 @@
+# Device types
+type device, dev_type, fs_type;
+type alarm_device, dev_type, mlstrustedobject;
+type adb_device, dev_type;
+type ashmem_device, dev_type, mlstrustedobject;
+type audio_device, dev_type;
+type binder_device, dev_type, mlstrustedobject;
+type block_device, dev_type;
+type camera_device, dev_type;
+type dm_device, dev_type;
+type loop_device, dev_type;
+type pmsg_device, dev_type, mlstrustedobject;
+type radio_device, dev_type;
+type ram_device, dev_type;
+type rtc_device, dev_type;
+type vold_device, dev_type;
+type console_device, dev_type;
+type cpuctl_device, dev_type;
+type fscklogs, dev_type;
+type full_device, dev_type;
+# GPU (used by most UI apps)
+type gpu_device, dev_type, mlstrustedobject;
+type graphics_device, dev_type;
+type hw_random_device, dev_type;
+type input_device, dev_type;
+type kmem_device, dev_type;
+type log_device, dev_type, mlstrustedobject;
+type mtd_device, dev_type;
+type mtp_device, dev_type, mlstrustedobject;
+type nfc_device, dev_type;
+type ptmx_device, dev_type, mlstrustedobject;
+type kmsg_device, dev_type;
+type null_device, dev_type, mlstrustedobject;
+type random_device, dev_type, mlstrustedobject;
+type sensors_device, dev_type;
+type serial_device, dev_type;
+type socket_device, dev_type;
+type owntty_device, dev_type, mlstrustedobject;
+type tty_device, dev_type;
+type urandom_device, dev_type, mlstrustedobject;
+type video_device, dev_type;
+type vcs_device, dev_type;
+type zero_device, dev_type, mlstrustedobject;
+type fuse_device, dev_type, mlstrustedobject;
+type iio_device, dev_type;
+type ion_device, dev_type, mlstrustedobject;
+type qtaguid_device, dev_type;
+type watchdog_device, dev_type;
+type uhid_device, dev_type;
+type uio_device, dev_type;
+type tun_device, dev_type, mlstrustedobject;
+type usbaccessory_device, dev_type, mlstrustedobject;
+type usb_device, dev_type, mlstrustedobject;
+type properties_device, dev_type;
+type properties_serial, dev_type;
+type i2c_device, dev_type;
+
+# All devices have a uart for the hci
+# attach service. The uart dev node
+# varies per device. This type
+# is used in per device policy
+type hci_attach_dev, dev_type;
+
+# All devices have a rpmsg device for
+# achieving remoteproc and rpmsg modules
+type rpmsg_device, dev_type;
+
+# Partition layout block device
+type root_block_device, dev_type;
+
+# factory reset protection block device
+type frp_block_device, dev_type;
+
+# System block device mounted on /system.
+type system_block_device, dev_type;
+
+# Recovery block device.
+type recovery_block_device, dev_type;
+
+# boot block device.
+type boot_block_device, dev_type;
+
+# Userdata block device mounted on /data.
+type userdata_block_device, dev_type;
+
+# Cache block device mounted on /cache.
+type cache_block_device, dev_type;
+
+# Block device for any swap partition.
+type swap_block_device, dev_type;
+
+# Metadata block device used for encryption metadata.
+# Assign this type to the partition specified by the encryptable=
+# mount option in your fstab file in the entry for userdata.
+type metadata_block_device, dev_type;
+
+# The 'misc' partition used by recovery and A/B.
+type misc_block_device, dev_type;
+
+# Bootctrl block device used by A/B update (update_engine, update_verifier).
+type bootctrl_block_device, dev_type;
diff --git a/sepolicy/dex2oat.te b/sepolicy/dex2oat.te
new file mode 100644
index 0000000..83a7c8a
--- /dev/null
+++ b/sepolicy/dex2oat.te
@@ -0,0 +1,16 @@
+# dex2oat
+type dex2oat, domain, domain_deprecated;
+type dex2oat_exec, exec_type, file_type;
+
+allow dex2oat dalvikcache_data_file:file write;
+# Read symlinks in /data/dalvik-cache
+allow dex2oat dalvikcache_data_file:lnk_file read;
+allow dex2oat installd:fd use;
+
+# Read already open asec_apk_file file descriptors passed by installd.
+# Also allow reading unlabeled files, to allow for upgrading forward
+# locked APKs.
+allow dex2oat asec_apk_file:file read;
+allow dex2oat unlabeled:file read;
+allow dex2oat oemfs:file read;
+allow dex2oat apk_tmp_file:file read;
diff --git a/sepolicy/dhcp.te b/sepolicy/dhcp.te
new file mode 100644
index 0000000..a858e08
--- /dev/null
+++ b/sepolicy/dhcp.te
@@ -0,0 +1,32 @@
+type dhcp, domain, domain_deprecated;
+type dhcp_exec, exec_type, file_type;
+type dhcp_data_file, file_type, data_file_type;
+
+init_daemon_domain(dhcp)
+net_domain(dhcp)
+
+allow dhcp cgroup:dir { create write add_name };
+allow dhcp self:capability { setgid setuid net_admin net_raw net_bind_service };
+allow dhcp self:packet_socket create_socket_perms;
+allow dhcp self:netlink_route_socket nlmsg_write;
+allow dhcp shell_exec:file rx_file_perms;
+allow dhcp system_file:file rx_file_perms;
+
+# dhcpcd runs dhcpcd-hooks/*, which runs getprop / setprop (toolbox_exec)
+allow dhcp toolbox_exec:file rx_file_perms;
+
+# For /proc/sys/net/ipv4/conf/*/promote_secondaries
+allow dhcp proc_net:file write;
+
+set_prop(dhcp, dhcp_prop)
+set_prop(dhcp, pan_result_prop)
+
+type_transition dhcp system_data_file:{ dir file } dhcp_data_file;
+allow dhcp dhcp_data_file:dir create_dir_perms;
+allow dhcp dhcp_data_file:file create_file_perms;
+
+# PAN connections
+allow dhcp netd:fd use;
+allow dhcp netd:fifo_file rw_file_perms;
+allow dhcp netd:{ dgram_socket_class_set unix_stream_socket } { read write };
+allow dhcp netd:{ netlink_kobject_uevent_socket netlink_route_socket netlink_nflog_socket } { read write };
diff --git a/sepolicy/dnsmasq.te b/sepolicy/dnsmasq.te
new file mode 100644
index 0000000..e5e4198
--- /dev/null
+++ b/sepolicy/dnsmasq.te
@@ -0,0 +1,24 @@
+# DNS, DHCP services
+type dnsmasq, domain, domain_deprecated;
+type dnsmasq_exec, exec_type, file_type;
+
+net_domain(dnsmasq)
+
+# TODO:  Run with dhcp group to avoid need for dac_override.
+allow dnsmasq self:capability dac_override;
+
+allow dnsmasq self:capability { net_admin net_raw net_bind_service setgid setuid };
+
+allow dnsmasq dhcp_data_file:dir w_dir_perms;
+allow dnsmasq dhcp_data_file:file create_file_perms;
+
+# Inherit and use open files from netd.
+allow dnsmasq netd:fd use;
+allow dnsmasq netd:fifo_file { read write };
+# TODO: Investigate whether these inherited sockets should be closed on exec.
+allow dnsmasq netd:netlink_kobject_uevent_socket { read write };
+allow dnsmasq netd:netlink_nflog_socket { read write };
+allow dnsmasq netd:netlink_route_socket { read write };
+allow dnsmasq netd:unix_stream_socket { read write };
+allow dnsmasq netd:unix_dgram_socket { read write };
+allow dnsmasq netd:udp_socket { read write };
diff --git a/sepolicy/domain.te b/sepolicy/domain.te
new file mode 100644
index 0000000..3917f8b
--- /dev/null
+++ b/sepolicy/domain.te
@@ -0,0 +1,593 @@
+# Rules for all domains.
+
+# Allow reaping by init.
+allow domain init:process sigchld;
+
+# Intra-domain accesses.
+allow domain self:process {
+    fork
+    sigchld
+    sigkill
+    sigstop
+    signull
+    signal
+    getsched
+    setsched
+    getsession
+    getpgid
+    setpgid
+    getcap
+    setcap
+    getattr
+    setrlimit
+};
+allow domain self:fd use;
+allow domain proc:dir r_dir_perms;
+allow domain proc_net:dir search;
+r_dir_file(domain, self)
+allow domain self:{ fifo_file file } rw_file_perms;
+allow domain self:unix_dgram_socket { create_socket_perms sendto };
+allow domain self:unix_stream_socket { create_stream_socket_perms connectto };
+
+# Inherit or receive open files from others.
+allow domain init:fd use;
+
+userdebug_or_eng(`
+  # Same as adbd rules above, except allow su to do the same thing
+  allow domain su:unix_stream_socket connectto;
+  allow domain su:fd use;
+  allow domain su:unix_stream_socket { getattr getopt read write shutdown };
+
+  binder_call({ domain -init }, su)
+
+  # Running something like "pm dump com.android.bluetooth" requires
+  # fifo writes
+  allow domain su:fifo_file { write getattr };
+
+  # allow "gdbserver --attach" to work for su.
+  allow domain su:process sigchld;
+
+  # Allow writing coredumps to /cores/*
+  allow domain coredump_file:file create_file_perms;
+  allow domain coredump_file:dir ra_dir_perms;
+')
+
+###
+### Talk to debuggerd.
+###
+allow domain debuggerd:process sigchld;
+allow domain debuggerd:unix_stream_socket connectto;
+
+# Root fs.
+allow domain rootfs:dir search;
+allow domain rootfs:lnk_file read;
+
+# Device accesses.
+allow domain device:dir search;
+allow domain dev_type:lnk_file r_file_perms;
+allow domain devpts:dir search;
+allow domain socket_device:dir r_dir_perms;
+allow domain owntty_device:chr_file rw_file_perms;
+allow domain null_device:chr_file rw_file_perms;
+allow domain zero_device:chr_file rw_file_perms;
+allow domain ashmem_device:chr_file rw_file_perms;
+allow domain binder_device:chr_file rw_file_perms;
+allow domain ptmx_device:chr_file rw_file_perms;
+allow domain alarm_device:chr_file r_file_perms;
+allow domain urandom_device:chr_file rw_file_perms;
+allow domain random_device:chr_file rw_file_perms;
+allow domain properties_device:dir r_dir_perms;
+allow domain properties_serial:file r_file_perms;
+
+# For now, everyone can access core property files
+# Device specific properties are not granted by default
+get_prop(domain, core_property_type)
+dontaudit domain property_type:file audit_access;
+allow domain property_contexts:file r_file_perms;
+
+allow domain init:key search;
+allow domain vold:key search;
+
+# logd access
+write_logd(domain)
+
+# System file accesses.
+allow domain system_file:dir { search getattr };
+allow domain system_file:file { execute read open getattr };
+allow domain system_file:lnk_file read;
+
+# read any sysfs symlinks
+allow domain sysfs:lnk_file read;
+
+# libc references /data/misc/zoneinfo for timezone related information
+r_dir_file(domain, zoneinfo_data_file)
+
+# Lots of processes access current CPU information
+r_dir_file(domain, sysfs_devices_system_cpu)
+
+# files under /data.
+allow domain system_data_file:dir { search getattr };
+allow domain system_data_file:lnk_file read;
+
+# required by the dynamic linker
+allow domain proc:lnk_file { getattr read };
+
+# /proc/cpuinfo
+allow domain proc_cpuinfo:file r_file_perms;
+
+# jemalloc needs to read /proc/sys/vm/overcommit_memory
+allow domain proc_overcommit_memory:file r_file_perms;
+
+# toybox loads libselinux which stats /sys/fs/selinux/
+allow domain selinuxfs:dir search;
+allow domain selinuxfs:file getattr;
+allow domain sysfs:dir search;
+allow domain selinuxfs:filesystem getattr;
+
+# For /acct/uid/*/tasks.
+allow domain cgroup:dir { search write };
+allow domain cgroup:file w_file_perms;
+
+# Almost all processes log tracing information to
+# /sys/kernel/debug/tracing/trace_marker
+# The reason behind this is documented in b/6513400
+allow domain debugfs:dir search;
+allow domain debugfs_tracing:dir search;
+allow domain debugfs_trace_marker:file w_file_perms;
+
+# Filesystem access.
+allow domain fs_type:filesystem getattr;
+allow domain fs_type:dir getattr;
+
+###
+### neverallow rules
+###
+
+# Do not allow any domain other than init or recovery to create unlabeled files.
+neverallow { domain -init -recovery } unlabeled:dir_file_class_set create;
+
+# Limit ability to ptrace or read sensitive /proc/pid files of processes
+# with other UIDs to these whitelisted domains.
+neverallow {
+  domain
+  -debuggerd
+  -vold
+  -dumpstate
+  -system_server
+  userdebug_or_eng(`-perfprofd')
+} self:capability sys_ptrace;
+
+# Limit device node creation to these whitelisted domains.
+neverallow {
+  domain
+  -kernel
+  -init
+  -ueventd
+  -vold
+  -recovery
+} self:capability mknod;
+
+# Limit raw I/O to these whitelisted domains.
+neverallow { domain -kernel -init -recovery -ueventd -watchdogd -healthd -uncrypt -tee } self:capability sys_rawio;
+
+# No process can map low memory (< CONFIG_LSM_MMAP_MIN_ADDR).
+neverallow * self:memprotect mmap_zero;
+
+# No domain needs mac_override as it is unused by SELinux.
+neverallow * self:capability2 mac_override;
+
+# Only recovery needs mac_admin to set contexts not defined in current policy.
+neverallow { domain -recovery } self:capability2 mac_admin;
+
+# Once the policy has been loaded there shall be none to modify the policy.
+# It is sealed.
+neverallow * kernel:security load_policy;
+
+# Only init and the system_server shall use the property_service.
+neverallow { domain -init -system_server } security_prop:property_service set;
+
+# Only init prior to switching context should be able to set enforcing mode.
+# init starts in kernel domain and switches to init domain via setcon in
+# the init.rc, so the setenforce occurs while still in kernel. After
+# switching domains, there is never any need to setenforce again by init.
+neverallow * kernel:security setenforce;
+neverallow { domain -kernel } kernel:security setcheckreqprot;
+
+# No booleans in AOSP policy, so no need to ever set them.
+neverallow * kernel:security setbool;
+
+# Adjusting the AVC cache threshold.
+# Not presently allowed to anything in policy, but possibly something
+# that could be set from init.rc.
+neverallow { domain -init } kernel:security setsecparam;
+
+# Only init, ueventd, shell and system_server should be able to access HW RNG
+neverallow {
+  domain
+  -init
+  -shell # For CTS and is restricted to getattr in shell.te
+  -system_server
+  -ueventd
+} hw_random_device:chr_file *;
+
+# Ensure that all entrypoint executables are in exec_type or postinstall_file.
+neverallow * { file_type -exec_type -postinstall_file }:file entrypoint;
+
+# Ensure that nothing in userspace can access /dev/mem or /dev/kmem
+neverallow {
+  domain
+  -init
+  -kernel
+  -shell # For CTS and is restricted to getattr in shell.te
+  -ueventd # Further restricted in ueventd.te
+} kmem_device:chr_file *;
+neverallow * kmem_device:chr_file ~{ create relabelto unlink setattr getattr };
+
+# Only init should be able to configure kernel usermodehelpers or
+# security-sensitive proc settings.
+neverallow { domain -init } usermodehelper:file { append write };
+neverallow { domain -init } proc_security:file { append write };
+
+# No domain should be allowed to ptrace init.
+neverallow * init:process ptrace;
+
+# Init can't do anything with binder calls. If this neverallow rule is being
+# triggered, it's probably due to a service with no SELinux domain.
+neverallow * init:binder *;
+
+# Don't allow raw read/write/open access to block_device
+# Rather force a relabel to a more specific type
+neverallow { domain -kernel -init -recovery } block_device:blk_file { open read write };
+
+# Don't allow raw read/write/open access to generic devices.
+# Rather force a relabel to a more specific type.
+# init is exempt from this as there are character devices that only it uses.
+# ueventd is exempt from this, as it is managing these devices.
+neverallow { domain -init -ueventd } device:chr_file { open read write };
+
+# Limit what domains can mount filesystems or change their mount flags.
+# sdcard_type / vfat is exempt as a larger set of domains need
+# this capability, including device-specific domains.
+neverallow { domain -kernel -init -recovery -vold -zygote -update_engine } { fs_type -sdcard_type }:filesystem { mount remount relabelfrom relabelto };
+
+#
+# Assert that, to the extent possible, we're not loading executable content from
+# outside the rootfs or /system partition except for a few whitelisted domains.
+#
+neverallow {
+    domain
+    -appdomain
+    -dumpstate
+    -shell
+    -su
+    -system_server
+    -zygote
+} { file_type -system_file -exec_type -postinstall_file }:file execute;
+neverallow {
+    domain
+    -appdomain # for oemfs
+    -recovery # for /tmp/update_binary in tmpfs
+} { fs_type -rootfs }:file execute;
+# Files from cache should never be executed
+neverallow domain { cache_file cache_backup_file cache_recovery_file }:file execute;
+
+# Protect most domains from executing arbitrary content from /data.
+neverallow {
+  domain
+  -untrusted_app
+  -priv_app
+  -shell
+} {
+  data_file_type
+  -dalvikcache_data_file
+  -system_data_file # shared libs in apks
+  -apk_data_file
+}:file no_x_file_perms;
+
+neverallow { domain userdebug_or_eng(`-shell') } nativetest_data_file:file no_x_file_perms;
+
+# Only the init property service should write to /data/property and /dev/__properties__
+neverallow { domain -init } property_data_file:dir no_w_dir_perms;
+neverallow { domain -init } property_data_file:file { no_w_file_perms no_x_file_perms };
+neverallow { domain -init -su } property_type:file { no_w_file_perms no_x_file_perms };
+neverallow { domain -init } properties_device:file { no_w_file_perms no_x_file_perms };
+neverallow { domain -init } properties_serial:file { no_w_file_perms no_x_file_perms };
+
+# Only recovery should be doing writes to /system
+neverallow { domain -recovery } { system_file exec_type }:dir_file_class_set
+    { create write setattr relabelfrom append unlink link rename };
+neverallow { domain -recovery -kernel } { system_file exec_type }:dir_file_class_set relabelto;
+
+# Don't allow mounting on top of /system files or directories
+neverallow * exec_type:dir_file_class_set mounton;
+neverallow { domain -init } system_file:dir_file_class_set mounton;
+
+# Nothing should be writing to files in the rootfs.
+neverallow * rootfs:file { create write setattr relabelto append unlink link rename };
+
+# Restrict context mounts to specific types marked with
+# the contextmount_type attribute.
+neverallow * {fs_type -contextmount_type}:filesystem relabelto;
+
+# Ensure that context mount types are not writable, to ensure that
+# the write to /system restriction above is not bypassed via context=
+# mount to another type.
+neverallow { domain -recovery } contextmount_type:dir_file_class_set
+    { create write setattr relabelfrom relabelto append unlink link rename };
+
+# Do not allow service_manager add for default_android_service.
+# Instead domains should use a more specific type such as
+# system_app_service rather than the generic type.
+# New service_types are defined in service.te and new mappings
+# from service name to service_type are defined in service_contexts.
+neverallow * default_android_service:service_manager add;
+
+# Require that domains explicitly label unknown properties, and do not allow
+# anyone but init to modify unknown properties.
+neverallow { domain -init } default_prop:property_service set;
+neverallow { domain -init } mmc_prop:property_service set;
+
+neverallow {
+  domain
+  -init
+  -recovery
+  -system_server
+  -shell # Shell is further restricted in shell.te
+  -ueventd # Further restricted in ueventd.te
+} frp_block_device:blk_file rw_file_perms;
+
+# No domain other than recovery and update_engine can write to system partition(s).
+neverallow { domain -recovery -update_engine } system_block_device:blk_file write;
+
+# No domains other than install_recovery or recovery can write to recovery.
+neverallow { domain -install_recovery -recovery } recovery_block_device:blk_file write;
+
+# No domains other than a select few can access the misc_block_device. This
+# block device is reserved for OTA use.
+# Do not assert this rule on userdebug/eng builds, due to some devices using
+# this partition for testing purposes.
+neverallow {
+  domain
+  userdebug_or_eng(`-domain') # exclude debuggable builds
+  -init
+  -uncrypt
+  -update_engine
+  -vold
+  -recovery
+  -ueventd
+} misc_block_device:blk_file { append link relabelfrom rename write open read ioctl lock };
+
+# Only servicemanager should be able to register with binder as the context manager
+neverallow { domain -servicemanager } *:binder set_context_mgr;
+
+# Only authorized processes should be writing to files in /data/dalvik-cache
+neverallow {
+  domain
+  -init # TODO: limit init to relabelfrom for files
+  -zygote
+  -installd
+  -dex2oat
+} dalvikcache_data_file:file no_w_file_perms;
+
+neverallow {
+  domain
+  -init
+  -installd
+  -dex2oat
+  -zygote
+} dalvikcache_data_file:dir no_w_dir_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
+# kernel resource leakage.
+#
+# For example, there is no way to automatically release a SysV semaphore
+# allocated in the kernel when:
+#
+# - a buggy or malicious process exits
+# - a non-buggy and non-malicious process crashes or is explicitly killed.
+#
+# Killing processes automatically to make room for new ones is an
+# important part of Android's application lifecycle implementation. This means
+# that, even assuming only non-buggy and non-malicious code, it is very likely
+# that over time, the kernel global tables used to implement SysV IPCs will fill
+# up.
+neverallow * *:{ shm sem msg msgq } *;
+
+# Do not mount on top of symlinks, fifos, or sockets.
+# Feature parity with Chromium LSM.
+neverallow * { 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;
+
+# Do not allow the introduction of new execmod rules. Text relocations
+# and modification of executable pages are unsafe.
+# The only exceptions are for NDK text relocations associated with
+# https://code.google.com/p/android/issues/detail?id=23203
+# which, long term, need to go away.
+neverallow * {
+  file_type
+  -apk_data_file
+  -app_data_file
+  -asec_public_file
+}:file execmod;
+
+# Do not allow making the stack or heap executable.
+# We would also like to minimize execmem but it seems to be
+# required by some device-specific service domains.
+neverallow * self:process { execstack execheap };
+
+# prohibit non-zygote spawned processes from using shared libraries
+# with text relocations. b/20013628 .
+neverallow { domain -appdomain } file_type:file execmod;
+
+neverallow { domain -init } proc:{ file dir } mounton;
+
+# Ensure that all types assigned to processes are included
+# in the domain attribute, so that all allow and neverallow rules
+# written on domain are applied to all processes.
+# This is achieved by ensuring that it is impossible to transition
+# from a domain to a non-domain type and vice versa.
+neverallow domain ~domain:process { transition dyntransition };
+neverallow ~domain domain:process { transition dyntransition };
+
+#
+# Only system_app and system_server should be creating or writing
+# their files. The proper way to share files is to setup
+# type transitions to a more specific type or assigning a type
+# to its parent directory via a file_contexts entry.
+# Example type transition:
+#  mydomain.te:file_type_auto_trans(mydomain, system_data_file, new_file_type)
+#
+neverallow {
+  domain
+  -system_server
+  -system_app
+  -init
+  -installd # for relabelfrom and unlink, check for this in explicit neverallow
+} system_data_file:file no_w_file_perms;
+# do not grant anything greater than r_file_perms and relabelfrom unlink
+# to installd
+neverallow installd system_data_file:file ~{ r_file_perms relabelfrom unlink };
+
+# respect system_app sandboxes
+neverallow {
+  domain
+  -system_app # its own sandbox
+  -system_server #populate com.android.providers.settings/databases/settings.db.
+  -installd # creation of app sandbox
+} system_app_data_file:dir_file_class_set { create unlink open };
+
+# Services should respect app sandboxes
+neverallow {
+  domain
+  -appdomain
+  -installd # creation of sandbox
+} app_data_file:dir_file_class_set { create unlink };
+
+#
+# Only these domains should transition to shell domain. This domain is
+# permissible for the "shell user". If you need a process to exec a shell
+# script with differing privilege, define a domain and set up a transition.
+#
+neverallow {
+  domain
+  -adbd
+  -init
+  -runas
+  -zygote
+} shell:process { transition dyntransition };
+
+# Minimize read access to shell- or app-writable symlinks.
+# This is to prevent malicious symlink attacks.
+neverallow {
+  domain
+  -appdomain
+  -installd
+  -uncrypt  # TODO: see if we can remove
+} app_data_file:lnk_file read;
+
+neverallow {
+  domain
+  -shell
+  userdebug_or_eng(`-uncrypt')
+  -installd
+} shell_data_file:lnk_file read;
+
+# In addition to the symlink reading restrictions above, restrict
+# write access to shell owned directories. The /data/local/tmp
+# directory is untrustworthy, and non-whitelisted domains should
+# not be trusting any content in those directories.
+neverallow {
+  domain
+  -adbd
+  -dumpstate
+  -installd
+  -init
+  -shell
+  -vold
+  -su
+} shell_data_file:dir no_w_dir_perms;
+
+neverallow {
+  domain
+  -adbd
+  -appdomain
+  -dumpstate
+  -init
+  -installd
+  -system_server # why?
+  userdebug_or_eng(`-uncrypt')
+} shell_data_file:dir { open search };
+
+# Same as above for /data/local/tmp files. We allow shell files
+# to be passed around by file descriptor, but not directly opened.
+neverallow {
+  domain
+  -adbd
+  -appdomain
+  -dumpstate
+  -installd
+  userdebug_or_eng(`-uncrypt')
+} shell_data_file:file open;
+
+# servicemanager is the only process which handles list request
+neverallow * ~servicemanager:service_manager list;
+
+# only service_manager_types can be added to service_manager
+neverallow * ~service_manager_type:service_manager { add find };
+
+# Prevent assigning non property types to properties
+neverallow * ~property_type:property_service set;
+
+# Domain types should never be assigned to any files other
+# than the /proc/pid files associated with a process. The
+# executable file used to enter a domain should be labeled
+# with its own _exec type, not with the domain type.
+# Conventionally, this looks something like:
+# $ cat mydaemon.te
+# type mydaemon, domain;
+# type mydaemon_exec, exec_type, file_type;
+# init_daemon_domain(mydaemon)
+# $ grep mydaemon file_contexts
+# /system/bin/mydaemon -- u:object_r:mydaemon_exec:s0
+neverallow * domain:file { execute execute_no_trans entrypoint };
+
+# Do not allow access to the generic debugfs label. This is too broad.
+# Instead, if access to part of debugfs is desired, it should have a
+# more specific label.
+# TODO: fix system_server and dumpstate
+neverallow { domain -init -system_server -dumpstate } debugfs:file no_rw_file_perms;
+
+neverallow {
+  domain
+  -init
+  -recovery
+  -sdcardd
+  -vold
+} fuse_device:chr_file open;
+neverallow {
+  domain
+  -dumpstate
+  -init
+  -priv_app
+  -recovery
+  -sdcardd
+  -shell # Restricted by shell.te to only getattr
+  -system_server
+  -ueventd
+  -vold
+} fuse_device:chr_file *;
+
+# Enforce restrictions on kernel module origin.
+# Do not allow kernel module loading except from system,
+# vendor, and boot partitions.
+neverallow * ~{ system_file rootfs }:system module_load;
diff --git a/sepolicy/domain_deprecated.te b/sepolicy/domain_deprecated.te
new file mode 100644
index 0000000..2a35bcf
--- /dev/null
+++ b/sepolicy/domain_deprecated.te
@@ -0,0 +1,68 @@
+# rules removed from the domain attribute
+
+# Read access to properties mapping.
+allow domain_deprecated kernel:fd use;
+allow domain_deprecated tmpfs:file { read getattr };
+allow domain_deprecated tmpfs:lnk_file { read getattr };
+
+# Search /storage/emulated tmpfs mount.
+allow domain_deprecated tmpfs:dir r_dir_perms;
+
+# Inherit or receive open files from others.
+allow domain_deprecated system_server:fd use;
+
+# Connect to adbd and use a socket transferred from it.
+# This is used for e.g. adb backup/restore.
+allow domain_deprecated adbd:unix_stream_socket connectto;
+allow domain_deprecated adbd:fd use;
+allow domain_deprecated adbd:unix_stream_socket { getattr getopt ioctl read write shutdown };
+
+# Root fs.
+allow domain_deprecated rootfs:dir r_dir_perms;
+allow domain_deprecated rootfs:file r_file_perms;
+allow domain_deprecated rootfs:lnk_file r_file_perms;
+
+# Device accesses.
+allow domain_deprecated device:file read;
+
+# System file accesses.
+allow domain_deprecated system_file:dir r_dir_perms;
+allow domain_deprecated system_file:file r_file_perms;
+allow domain_deprecated system_file:lnk_file r_file_perms;
+
+# Read files already opened under /data.
+allow domain_deprecated system_data_file:file { getattr read };
+allow domain_deprecated system_data_file:lnk_file r_file_perms;
+
+# Read apk files under /data/app.
+allow domain_deprecated apk_data_file:dir { getattr search };
+allow domain_deprecated apk_data_file:file r_file_perms;
+allow domain_deprecated apk_data_file:lnk_file r_file_perms;
+
+# Read /data/dalvik-cache.
+allow domain_deprecated dalvikcache_data_file:dir { search getattr };
+allow domain_deprecated dalvikcache_data_file:file r_file_perms;
+
+# Read already opened /cache files.
+allow domain_deprecated cache_file:dir r_dir_perms;
+allow domain_deprecated cache_file:file { getattr read };
+allow domain_deprecated cache_file:lnk_file r_file_perms;
+
+#Allow access to ion memory allocation device
+allow domain_deprecated ion_device:chr_file rw_file_perms;
+
+# Read access to pseudo filesystems.
+r_dir_file(domain_deprecated, proc)
+r_dir_file(domain_deprecated, sysfs)
+r_dir_file(domain_deprecated, inotify)
+r_dir_file(domain_deprecated, cgroup)
+r_dir_file(domain_deprecated, proc_meminfo)
+r_dir_file(domain_deprecated, proc_net)
+
+# Get SELinux enforcing status.
+allow domain_deprecated selinuxfs:dir r_dir_perms;
+allow domain_deprecated selinuxfs:file r_file_perms;
+
+# World readable asec image contents
+allow domain_deprecated asec_public_file:file r_file_perms;
+allow domain_deprecated { asec_public_file asec_apk_file }:dir r_dir_perms;
diff --git a/sepolicy/drmserver.te b/sepolicy/drmserver.te
new file mode 100644
index 0000000..3b654cc
--- /dev/null
+++ b/sepolicy/drmserver.te
@@ -0,0 +1,55 @@
+# drmserver - DRM service
+type drmserver, domain, domain_deprecated;
+type drmserver_exec, exec_type, file_type;
+
+init_daemon_domain(drmserver)
+typeattribute drmserver mlstrustedsubject;
+
+net_domain(drmserver)
+
+# Perform Binder IPC to system server.
+binder_use(drmserver)
+binder_call(drmserver, system_server)
+binder_call(drmserver, appdomain)
+binder_service(drmserver)
+
+# Perform Binder IPC to mediaserver
+binder_call(drmserver, mediaserver)
+
+allow drmserver sdcard_type:dir search;
+allow drmserver drm_data_file:dir create_dir_perms;
+allow drmserver drm_data_file:file create_file_perms;
+allow drmserver tee_device:chr_file rw_file_perms;
+allow drmserver app_data_file:file { read write getattr };
+allow drmserver sdcard_type:file { read write getattr };
+r_dir_file(drmserver, efs_file)
+
+type drmserver_socket, file_type;
+
+# /data/app/tlcd_sock socket file.
+# Clearly, /data/app is the most logical place to create a socket.  Not.
+allow drmserver apk_data_file:dir rw_dir_perms;
+type_transition drmserver apk_data_file:sock_file drmserver_socket;
+allow drmserver drmserver_socket:sock_file create_file_perms;
+allow drmserver tee:unix_stream_socket connectto;
+# Delete old socket file if present.
+allow drmserver apk_data_file:sock_file unlink;
+
+# After taking a video, drmserver looks at the video file.
+r_dir_file(drmserver, media_rw_data_file)
+
+# Read resources from open apk files passed over Binder.
+allow drmserver apk_data_file:file { read getattr };
+allow drmserver asec_apk_file:file { read getattr };
+
+# Read /data/data/com.android.providers.telephony files passed over Binder.
+allow drmserver radio_data_file:file { read getattr };
+
+# /oem access
+allow drmserver oemfs:dir search;
+allow drmserver oemfs:file r_file_perms;
+
+allow drmserver drmserver_service:service_manager { add find };
+allow drmserver permission_service:service_manager find;
+
+selinux_check_access(drmserver)
diff --git a/sepolicy/dumpstate.te b/sepolicy/dumpstate.te
new file mode 100644
index 0000000..4bb12c3
--- /dev/null
+++ b/sepolicy/dumpstate.te
@@ -0,0 +1,147 @@
+# dumpstate
+type dumpstate, domain, domain_deprecated, mlstrustedsubject;
+type dumpstate_exec, exec_type, file_type;
+
+init_daemon_domain(dumpstate)
+net_domain(dumpstate)
+binder_use(dumpstate)
+
+# Allow setting process priority, protect from OOM killer, and dropping
+# privileges by switching UID / GID
+allow dumpstate self:capability { setuid setgid sys_resource };
+
+# Allow dumpstate to scan through /proc/pid for all processes
+r_dir_file(dumpstate, domain)
+
+allow dumpstate self:capability {
+    # Send signals to processes
+    kill
+    # Run iptables
+    net_raw
+    net_admin
+};
+
+# Allow executing files on system, such as:
+#   /system/bin/toolbox
+#   /system/bin/logcat
+#   /system/bin/dumpsys
+allow dumpstate system_file:file execute_no_trans;
+allow dumpstate toolbox_exec:file rx_file_perms;
+
+# Create and write into /data/anr/
+allow dumpstate self:capability { dac_override chown fowner fsetid };
+allow dumpstate anr_data_file:dir rw_dir_perms;
+allow dumpstate anr_data_file:file create_file_perms;
+
+# Allow reading /data/system/uiderrors.txt
+# TODO: scope this down.
+allow dumpstate system_data_file:file r_file_perms;
+
+# Read dmesg
+allow dumpstate self:capability2 syslog;
+allow dumpstate kernel:system syslog_read;
+
+# Read /sys/fs/pstore/console-ramoops
+allow dumpstate pstorefs:dir r_dir_perms;
+allow dumpstate pstorefs:file r_file_perms;
+
+# Get process attributes
+allow dumpstate domain:process getattr;
+
+# Signal java processes to dump their stack
+allow dumpstate { appdomain system_server }:process signal;
+
+# Signal native processes to dump their stack.
+# This list comes from native_processes_to_dump in dumpstate/utils.c
+allow dumpstate { drmserver mediaserver sdcardd surfaceflinger }:process signal;
+# Ask debuggerd for the backtraces of these processes.
+allow dumpstate { drmserver mediaserver sdcardd surfaceflinger }:debuggerd dump_backtrace;
+
+# Execute and transition to the vdc domain
+domain_auto_trans(dumpstate, vdc_exec, vdc)
+
+# Vibrate the device after we're done collecting the bugreport
+# /sys/class/timed_output/vibrator/enable
+# TODO: create a new file class, instead of allowing write access to all of /sys
+allow dumpstate sysfs:file w_file_perms;
+
+# Other random bits of data we want to collect
+allow dumpstate qtaguid_proc:file r_file_perms;
+allow dumpstate debugfs:file r_file_perms;
+# df for /storage/emulated needs search
+allow dumpstate { storage_file block_device }:dir { search getattr };
+allow dumpstate fuse_device:chr_file getattr;
+allow dumpstate { dm_device cache_block_device }:blk_file getattr;
+
+# Allow dumpstate to make binder calls to any binder service
+binder_call(dumpstate, binderservicedomain)
+binder_call(dumpstate, appdomain)
+
+# Reading /proc/PID/maps of other processes
+allow dumpstate self:capability sys_ptrace;
+
+# Allow the bugreport service to create a file in
+# /data/data/com.android.shell/files/bugreports/bugreport
+allow dumpstate shell_data_file:dir create_dir_perms;
+allow dumpstate shell_data_file:file create_file_perms;
+
+# Run a shell.
+allow dumpstate shell_exec:file rx_file_perms;
+
+# For running am and similar framework commands.
+# Run /system/bin/app_process.
+allow dumpstate zygote_exec:file rx_file_perms;
+# Dalvik Compiler JIT.
+allow dumpstate ashmem_device:chr_file execute;
+allow dumpstate dumpstate_tmpfs:file execute;
+allow dumpstate self:process execmem;
+# For art.
+allow dumpstate dalvikcache_data_file:file execute;
+allow dumpstate dalvikcache_data_file:lnk_file r_file_perms;
+
+# Dumpstate calls screencap, which grabs a screenshot. Needs gpu access
+allow dumpstate gpu_device:chr_file rw_file_perms;
+
+# logd access
+read_logd(dumpstate)
+control_logd(dumpstate)
+
+# Read network state info files.
+allow dumpstate net_data_file:dir search;
+allow dumpstate net_data_file:file r_file_perms;
+
+# Access /data/tombstones.
+allow dumpstate tombstone_data_file:dir r_dir_perms;
+allow dumpstate tombstone_data_file:file r_file_perms;
+
+# Access /cache/recovery
+allow dumpstate cache_recovery_file:dir r_dir_perms;
+allow dumpstate cache_recovery_file:file r_file_perms;
+
+# Access /data/misc/recovery
+allow dumpstate recovery_data_file:dir r_dir_perms;
+allow dumpstate recovery_data_file:file r_file_perms;
+
+# Access /data/misc/logd
+userdebug_or_eng(`
+  allow dumpstate misc_logd_file:dir r_dir_perms;
+  allow dumpstate misc_logd_file:file r_file_perms;
+')
+
+allow dumpstate { service_manager_type -gatekeeper_service }:service_manager find;
+allow dumpstate servicemanager:service_manager list;
+
+allow dumpstate devpts:chr_file rw_file_perms;
+
+# Set properties.
+# dumpstate_prop is used to share state with the Shell app.
+set_prop(dumpstate, dumpstate_prop)
+
+# systrace support - allow atrace to run
+allow dumpstate debugfs_tracing:dir r_dir_perms;
+allow dumpstate debugfs_tracing:file rw_file_perms;
+allow dumpstate debugfs_trace_marker:file getattr;
+allow dumpstate atrace_exec:file rx_file_perms;
+
+allow dumpstate proc_interrupts:file r_file_perms;
+allow dumpstate proc_zoneinfo:file r_file_perms;
diff --git a/sepolicy/file.te b/sepolicy/file.te
new file mode 100644
index 0000000..02112ef
--- /dev/null
+++ b/sepolicy/file.te
@@ -0,0 +1,239 @@
+# Filesystem types
+type labeledfs, fs_type;
+type pipefs, fs_type;
+type sockfs, fs_type;
+type rootfs, fs_type;
+type proc, fs_type;
+# Security-sensitive proc nodes that should not be writable to most.
+type proc_security, fs_type;
+type proc_drop_caches, fs_type;
+type proc_overcommit_memory, fs_type;
+# proc, sysfs, or other nodes that permit configuration of kernel usermodehelpers.
+type usermodehelper, fs_type, sysfs_type;
+type qtaguid_proc, fs_type, mlstrustedobject;
+type proc_bluetooth_writable, fs_type;
+type proc_cpuinfo, fs_type;
+type proc_interrupts, fs_type;
+type proc_iomem, fs_type;
+type proc_meminfo, fs_type;
+type proc_net, fs_type;
+type proc_stat, fs_type;
+type proc_sysrq, fs_type;
+type proc_timer, fs_type;
+type proc_uid_cputime_showstat, fs_type;
+type proc_uid_cputime_removeuid, fs_type;
+type proc_zoneinfo, fs_type;
+type selinuxfs, fs_type, mlstrustedobject;
+type cgroup, fs_type, mlstrustedobject;
+type sysfs, fs_type, sysfs_type, mlstrustedobject;
+type sysfs_uio, sysfs_type, fs_type;
+type sysfs_batteryinfo, fs_type, sysfs_type;
+type sysfs_bluetooth_writable, fs_type, sysfs_type, mlstrustedobject;
+type sysfs_hwrandom, fs_type, sysfs_type;
+type sysfs_nfc_power_writable, fs_type, sysfs_type, mlstrustedobject;
+type sysfs_wake_lock, fs_type, sysfs_type;
+type sysfs_mac_address, fs_type, sysfs_type;
+type configfs, fs_type;
+# /sys/devices/system/cpu
+type sysfs_devices_system_cpu, fs_type, sysfs_type;
+# /sys/module/lowmemorykiller
+type sysfs_lowmemorykiller, fs_type, sysfs_type;
+
+type sysfs_thermal, sysfs_type, fs_type;
+
+type sysfs_zram, fs_type, sysfs_type;
+type sysfs_zram_uevent, fs_type, sysfs_type;
+type inotify, fs_type, mlstrustedobject;
+type devpts, fs_type, mlstrustedobject;
+type tmpfs, fs_type;
+type shm, fs_type;
+type mqueue, fs_type;
+type fuse, sdcard_type, fs_type, mlstrustedobject;
+type sdcardfs, sdcard_type, fs_type, mlstrustedobject;
+type vfat, sdcard_type, fs_type, mlstrustedobject;
+typealias fuse alias sdcard_internal;
+typealias vfat alias sdcard_external;
+type debugfs, fs_type;
+type debugfs_trace_marker, fs_type, debugfs_type, mlstrustedobject;
+type debugfs_tracing, fs_type, debugfs_type;
+type pstorefs, fs_type;
+type functionfs, fs_type;
+type oemfs, fs_type, contextmount_type;
+type usbfs, fs_type;
+type binfmt_miscfs, fs_type;
+type app_fusefs, fs_type, contextmount_type;
+
+# File types
+type unlabeled, file_type;
+# Default type for anything under /system.
+type system_file, file_type;
+# Type for /system/bin/logcat.
+type logcat_exec, exec_type, file_type;
+# /cores for coredumps on userdebug / eng builds
+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;
+# /data/drm - DRM plugin data
+type drm_data_file, file_type, data_file_type;
+# /data/adb - adb debugging files
+type adb_data_file, file_type, data_file_type;
+# /data/anr - ANR traces
+type anr_data_file, file_type, data_file_type, mlstrustedobject;
+# /data/tombstones - core dumps
+type tombstone_data_file, file_type, data_file_type;
+# /data/app - user-installed apps
+type apk_data_file, file_type, data_file_type;
+type apk_tmp_file, file_type, data_file_type, mlstrustedobject;
+# /data/app-private - forward-locked apps
+type apk_private_data_file, file_type, data_file_type;
+type apk_private_tmp_file, file_type, data_file_type, mlstrustedobject;
+# /data/dalvik-cache
+type dalvikcache_data_file, file_type, data_file_type;
+# /data/resource-cache
+type resourcecache_data_file, file_type, data_file_type;
+# /data/local - writable by shell
+type shell_data_file, file_type, data_file_type, mlstrustedobject;
+# /data/property
+type property_data_file, file_type, data_file_type;
+# /data/bootchart
+type bootchart_data_file, file_type, data_file_type;
+# /data/system/heapdump
+type heapdump_data_file, file_type, data_file_type, mlstrustedobject;
+# /data/nativetest
+type nativetest_data_file, file_type, data_file_type;
+
+# Mount locations managed by vold
+type mnt_media_rw_file, file_type;
+type mnt_user_file, file_type;
+type mnt_expand_file, file_type;
+type storage_file, file_type;
+
+# Label for storage dirs which are just mount stubs
+type mnt_media_rw_stub_file, file_type;
+type storage_stub_file, file_type;
+
+# /postinstall: Mount point used by update_engine to run postinstall.
+type postinstall_mnt_dir, file_type;
+# Files inside the /postinstall mountpoint are all labeled as postinstall_file.
+type postinstall_file, file_type;
+
+# /data/misc subdirectories
+type adb_keys_file, file_type, data_file_type;
+type audio_data_file, file_type, data_file_type;
+type bluetooth_data_file, file_type, data_file_type;
+type bootstat_data_file, file_type, data_file_type;
+type boottrace_data_file, file_type, data_file_type;
+type camera_data_file, file_type, data_file_type;
+type gatekeeper_data_file, file_type, data_file_type;
+type keychain_data_file, file_type, data_file_type;
+type keystore_data_file, file_type, data_file_type;
+type media_data_file, file_type, data_file_type;
+type media_rw_data_file, file_type, data_file_type, mlstrustedobject;
+type misc_user_data_file, file_type, data_file_type;
+type net_data_file, file_type, data_file_type;
+type nfc_data_file, file_type, data_file_type;
+type radio_data_file, file_type, data_file_type, mlstrustedobject;
+type recovery_data_file, file_type, data_file_type;
+type shared_relro_file, file_type, data_file_type;
+type systemkeys_data_file, file_type, data_file_type;
+type vpn_data_file, file_type, data_file_type;
+type wifi_data_file, file_type, data_file_type;
+type zoneinfo_data_file, file_type, data_file_type;
+type vold_data_file, file_type, data_file_type;
+type perfprofd_data_file, file_type, data_file_type, mlstrustedobject;
+# /data/misc/trace for method traces on userdebug / eng builds
+type method_trace_data_file, file_type, data_file_type, mlstrustedobject;
+
+# Compatibility with type names used in vanilla Android 4.3 and 4.4.
+typealias audio_data_file alias audio_firmware_file;
+# /data/data subdirectories - app sandboxes
+type app_data_file, file_type, data_file_type;
+# /data/data subdirectory for system UID apps.
+type system_app_data_file, file_type, data_file_type, mlstrustedobject;
+# Compatibility with type name used in Android 4.3 and 4.4.
+typealias app_data_file alias platform_app_data_file;
+typealias app_data_file alias download_file;
+# Default type for anything under /cache
+type cache_file, file_type, mlstrustedobject;
+# Type for /cache/.*\.{data|restore} and default
+# type for anything under /cache/backup
+type cache_backup_file, file_type, mlstrustedobject;
+# Type for anything under /cache/recovery
+type cache_recovery_file, file_type, mlstrustedobject;
+# Default type for anything under /efs
+type efs_file, file_type;
+# Type for wallpaper file.
+type wallpaper_file, file_type, mlstrustedobject;
+# /mnt/asec
+type asec_apk_file, file_type, data_file_type, mlstrustedobject;
+# Elements of asec files (/mnt/asec) that are world readable
+type asec_public_file, file_type, data_file_type;
+# /data/app-asec
+type asec_image_file, file_type, data_file_type;
+# /data/backup and /data/secure/backup
+type backup_data_file, file_type, data_file_type, mlstrustedobject;
+# All devices have bluetooth efs files. But they
+# vary per device, so this type is used in per
+# device policy
+type bluetooth_efs_file, file_type;
+# Type for fingerprint template file.
+type fingerprintd_data_file, file_type, data_file_type;
+# Type for appfuse file.
+type app_fuse_file, file_type, data_file_type, mlstrustedobject;
+
+# Socket types
+type adbd_socket, file_type;
+type bluetooth_socket, file_type;
+type dnsproxyd_socket, file_type, mlstrustedobject;
+type dumpstate_socket, file_type;
+type fwmarkd_socket, file_type, mlstrustedobject;
+type installd_socket, file_type;
+type lmkd_socket, file_type;
+type logd_socket, file_type, mlstrustedobject;
+type logdr_socket, file_type, mlstrustedobject;
+type logdw_socket, file_type, mlstrustedobject;
+type mdns_socket, file_type;
+type mdnsd_socket, file_type, mlstrustedobject;
+type misc_logd_file, file_type;
+type mtpd_socket, file_type;
+type netd_socket, file_type;
+type property_socket, file_type, mlstrustedobject;
+type racoon_socket, file_type;
+type rild_socket, file_type;
+type rild_debug_socket, file_type;
+type system_wpa_socket, file_type;
+type system_ndebug_socket, file_type;
+type vold_socket, file_type;
+type wpa_socket, file_type;
+type zygote_socket, file_type;
+type sap_uim_socket, file_type;
+# UART (for GPS) control proc file
+type gps_control, file_type;
+
+# property_contexts file
+type property_contexts, file_type;
+
+# Allow files to be created in their appropriate filesystems.
+allow fs_type self:filesystem associate;
+allow sysfs_type sysfs:filesystem associate;
+allow debugfs_type { debugfs debugfs_tracing }:filesystem associate;
+allow file_type labeledfs:filesystem associate;
+allow file_type tmpfs:filesystem associate;
+allow file_type rootfs:filesystem associate;
+allow dev_type tmpfs:filesystem associate;
+allow app_fuse_file app_fusefs:filesystem associate;
+allow postinstall_file self:filesystem associate;
+
+# It's a bug to assign the file_type attribute and fs_type attribute
+# to any type. Do not allow it.
+#
+# For example, the following is a bug:
+#   type apk_data_file, file_type, data_file_type, fs_type;
+# Should be:
+#   type apk_data_file, file_type, data_file_type;
+neverallow fs_type file_type:filesystem associate;
diff --git a/sepolicy/file_contexts b/sepolicy/file_contexts
new file mode 100644
index 0000000..39c006d
--- /dev/null
+++ b/sepolicy/file_contexts
@@ -0,0 +1,350 @@
+###########################################
+# Root
+/                   u:object_r:rootfs:s0
+
+# Data files
+/adb_keys           u:object_r:adb_keys_file:s0
+/build\.prop        u:object_r:rootfs:s0
+/default\.prop      u:object_r:rootfs:s0
+/fstab\..*          u:object_r:rootfs:s0
+/init\..*           u:object_r:rootfs:s0
+/res(/.*)?          u:object_r:rootfs:s0
+/selinux_version    u:object_r:rootfs:s0
+/ueventd\..*        u:object_r:rootfs:s0
+/verity_key         u:object_r:rootfs:s0
+
+# Executables
+/charger            u:object_r:rootfs:s0
+/init               u:object_r:init_exec:s0
+/sbin(/.*)?         u:object_r:rootfs:s0
+
+# Empty directories
+/lost\+found        u:object_r:rootfs:s0
+/acct               u:object_r:cgroup:s0
+/config             u:object_r:rootfs:s0
+/mnt                u:object_r:tmpfs:s0
+/postinstall        u:object_r:postinstall_mnt_dir:s0
+/proc               u:object_r:rootfs:s0
+/root               u:object_r:rootfs:s0
+/sys                u:object_r:sysfs:s0
+
+# Symlinks
+/d                  u:object_r:rootfs:s0
+/etc                u:object_r:rootfs:s0
+/sdcard             u:object_r:rootfs:s0
+
+# SELinux policy files
+/file_contexts\.bin u:object_r:rootfs:s0
+/property_contexts  u:object_r:property_contexts:s0
+/seapp_contexts     u:object_r:rootfs:s0
+/sepolicy           u:object_r:rootfs:s0
+/service_contexts   u:object_r:rootfs:s0
+
+##########################
+# Devices
+#
+/dev(/.*)?		u:object_r:device:s0
+/dev/akm8973.*		u:object_r:sensors_device:s0
+/dev/accelerometer	u:object_r:sensors_device:s0
+/dev/adf[0-9]*		u:object_r:graphics_device:s0
+/dev/adf-interface[0-9]*\.[0-9]*	u:object_r:graphics_device:s0
+/dev/adf-overlay-engine[0-9]*\.[0-9]*	u:object_r:graphics_device:s0
+/dev/alarm		u:object_r:alarm_device:s0
+/dev/android_adb.*	u:object_r:adb_device:s0
+/dev/ashmem		u:object_r:ashmem_device:s0
+/dev/audio.*		u:object_r:audio_device:s0
+/dev/binder		u:object_r:binder_device:s0
+/dev/block(/.*)?	u:object_r:block_device:s0
+/dev/block/dm-[0-9]+	u:object_r:dm_device:s0
+/dev/block/loop[0-9]*	u:object_r:loop_device:s0
+/dev/block/vold/.+	u:object_r:vold_device:s0
+/dev/block/ram[0-9]*	u:object_r:ram_device:s0
+/dev/block/zram[0-9]*	u:object_r:ram_device:s0
+/dev/bus/usb(.*)?       u:object_r:usb_device:s0
+/dev/cam		u:object_r:video_device:s0
+/dev/console		u:object_r:console_device:s0
+/dev/cpuctl(/.*)?	u:object_r:cpuctl_device:s0
+/dev/device-mapper	u:object_r:dm_device:s0
+/dev/eac		u:object_r:audio_device:s0
+/dev/fscklogs(/.*)?	u:object_r:fscklogs:s0
+/dev/full		u:object_r:full_device:s0
+/dev/fuse		u:object_r:fuse_device:s0
+/dev/graphics(/.*)?	u:object_r:graphics_device:s0
+/dev/hw_random		u:object_r:hw_random_device:s0
+/dev/i2c-[0-9]+		u:object_r:i2c_device:s0
+/dev/input(/.*)		u:object_r:input_device:s0
+/dev/iio:device[0-9]+   u:object_r:iio_device:s0
+/dev/ion		u:object_r:ion_device:s0
+/dev/kmem		u:object_r:kmem_device:s0
+/dev/log(/.*)?		u:object_r:log_device:s0
+/dev/mem		u:object_r:kmem_device:s0
+/dev/modem.*		u:object_r:radio_device:s0
+/dev/mtd(/.*)?		u:object_r:mtd_device:s0
+/dev/mtp_usb		u:object_r:mtp_device:s0
+/dev/pmsg0		u:object_r:pmsg_device:s0
+/dev/pn544		u:object_r:nfc_device:s0
+/dev/ppp		u:object_r:ppp_device:s0
+/dev/ptmx		u:object_r:ptmx_device:s0
+/dev/pvrsrvkm		u:object_r:gpu_device:s0
+/dev/kmsg		u:object_r:kmsg_device:s0
+/dev/null		u:object_r:null_device:s0
+/dev/nvhdcp1		u:object_r:video_device:s0
+/dev/random		u:object_r:random_device:s0
+/dev/rpmsg-omx[0-9]	u:object_r:rpmsg_device:s0
+/dev/rproc_user	u:object_r:rpmsg_device:s0
+/dev/rtc[0-9]      u:object_r:rtc_device:s0
+/dev/snd(/.*)?		u:object_r:audio_device:s0
+/dev/socket(/.*)?	u:object_r:socket_device:s0
+/dev/socket/adbd	u:object_r:adbd_socket:s0
+/dev/socket/sap_uim_socket[0-9]        u:object_r:sap_uim_socket:s0
+/dev/socket/cryptd	u:object_r:vold_socket:s0
+/dev/socket/dnsproxyd	u:object_r:dnsproxyd_socket:s0
+/dev/socket/dumpstate	u:object_r:dumpstate_socket:s0
+/dev/socket/fwmarkd	u:object_r:fwmarkd_socket:s0
+/dev/socket/installd	u:object_r:installd_socket:s0
+/dev/socket/lmkd        u:object_r:lmkd_socket: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
+/dev/socket/mdns	u:object_r:mdns_socket:s0
+/dev/socket/mdnsd	u:object_r:mdnsd_socket:s0
+/dev/socket/mtpd	u:object_r:mtpd_socket:s0
+/dev/socket/netd	u:object_r:netd_socket:s0
+/dev/socket/property_service	u:object_r:property_socket:s0
+/dev/socket/racoon	u:object_r:racoon_socket:s0
+/dev/socket/rild	u:object_r:rild_socket:s0
+/dev/socket/rild-debug	u:object_r:rild_debug_socket:s0
+/dev/socket/vold	u:object_r:vold_socket:s0
+/dev/socket/wpa_eth[0-9] u:object_r:wpa_socket:s0
+/dev/socket/wpa_wlan[0-9] u:object_r:wpa_socket:s0
+/dev/socket/zygote	u:object_r:zygote_socket:s0
+/dev/socket/zygote_secondary	u:object_r:zygote_socket:s0
+/dev/spdif_out.*	u:object_r:audio_device:s0
+/dev/tegra.*		u:object_r:video_device:s0
+/dev/tf_driver		u:object_r:tee_device:s0
+/dev/tty		u:object_r:owntty_device:s0
+/dev/tty[0-9]*		u:object_r:tty_device:s0
+/dev/ttyS[0-9]*		u:object_r:serial_device:s0
+/dev/tun		u:object_r:tun_device:s0
+/dev/uhid		u:object_r:uhid_device:s0
+/dev/uinput		u:object_r:uhid_device:s0
+/dev/uio[0-9]*		u:object_r:uio_device:s0
+/dev/urandom		u:object_r:urandom_device:s0
+/dev/usb_accessory	u:object_r:usbaccessory_device:s0
+/dev/vcs[0-9a-z]*	u:object_r:vcs_device:s0
+/dev/video[0-9]*	u:object_r:video_device:s0
+/dev/watchdog		u:object_r:watchdog_device:s0
+/dev/xt_qtaguid	u:object_r:qtaguid_device:s0
+/dev/zero		u:object_r:zero_device:s0
+/dev/__properties__ u:object_r:properties_device:s0
+#############################
+# System files
+#
+/system(/.*)?		u:object_r:system_file:s0
+/system/bin/atrace	u:object_r:atrace_exec:s0
+/system/bin/e2fsck	--	u:object_r:fsck_exec:s0
+/system/bin/fsck\.f2fs	--	u:object_r:fsck_exec:s0
+/system/bin/fsck_msdos	--	u:object_r:fsck_exec:s0
+/system/bin/toolbox	--	u:object_r:toolbox_exec:s0
+/system/bin/toybox	--	u:object_r:toolbox_exec:s0
+/system/bin/logcat	--	u:object_r:logcat_exec:s0
+/system/bin/sh		--	u:object_r:shell_exec:s0
+/system/bin/run-as	--	u:object_r:runas_exec:s0
+/system/bin/bootanimation u:object_r:bootanim_exec:s0
+/system/bin/bootstat		u:object_r:bootstat_exec:s0
+/system/bin/app_process32	u:object_r:zygote_exec:s0
+/system/bin/app_process64	u:object_r:zygote_exec:s0
+/system/bin/servicemanager	u:object_r:servicemanager_exec:s0
+/system/bin/surfaceflinger	u:object_r:surfaceflinger_exec:s0
+/system/bin/drmserver	u:object_r:drmserver_exec:s0
+/system/bin/dumpstate   u:object_r:dumpstate_exec:s0
+/system/bin/vold	u:object_r:vold_exec:s0
+/system/bin/netd	u:object_r:netd_exec:s0
+/system/bin/rild	u:object_r:rild_exec:s0
+/system/bin/mediaserver	u:object_r:mediaserver_exec:s0
+/system/bin/mdnsd	u:object_r:mdnsd_exec:s0
+/system/bin/installd	u:object_r:installd_exec:s0
+/system/bin/keystore	u:object_r:keystore_exec:s0
+/system/bin/fingerprintd u:object_r:fingerprintd_exec:s0
+/system/bin/gatekeeperd u:object_r:gatekeeperd_exec:s0
+/system/bin/debuggerd	u:object_r:debuggerd_exec:s0
+/system/bin/debuggerd64	u:object_r:debuggerd_exec:s0
+/system/bin/wpa_supplicant	u:object_r:wpa_exec:s0
+/system/bin/recovery-persist     u:object_r:recovery_persist_exec:s0
+/system/bin/recovery-refresh     u:object_r:recovery_refresh_exec:s0
+/system/bin/sdcard      u:object_r:sdcardd_exec:s0
+/system/bin/dhcpcd      u:object_r:dhcp_exec:s0
+/system/bin/dhcpcd-6.8.2	u:object_r:dhcp_exec:s0
+/system/bin/mtpd	u:object_r:mtp_exec:s0
+/system/bin/pppd	u:object_r:ppp_exec:s0
+/system/bin/tf_daemon	u:object_r:tee_exec:s0
+/system/bin/racoon	u:object_r:racoon_exec:s0
+/system/xbin/su		u:object_r:su_exec:s0
+/system/xbin/perfprofd  u:object_r:perfprofd_exec:s0
+/system/bin/dnsmasq     u:object_r:dnsmasq_exec:s0
+/system/bin/hostapd     u:object_r:hostapd_exec:s0
+/system/bin/clatd	u:object_r:clatd_exec:s0
+/system/bin/lmkd        u:object_r:lmkd_exec:s0
+/system/bin/inputflinger u:object_r:inputflinger_exec:s0
+/system/bin/logd        u:object_r:logd_exec:s0
+/system/bin/uncrypt     u:object_r:uncrypt_exec:s0
+/system/bin/update_verifier u:object_r:update_verifier_exec:s0
+/system/bin/logwrapper  u:object_r:system_file:s0
+/system/bin/vdc         u:object_r:vdc_exec:s0
+/system/bin/install-recovery.sh u:object_r:install_recovery_exec:s0
+/system/bin/dex2oat     u:object_r:dex2oat_exec:s0
+# patchoat executable has (essentially) the same requirements as dex2oat.
+/system/bin/patchoat    u:object_r:dex2oat_exec:s0
+/system/bin/sgdisk      u:object_r:sgdisk_exec:s0
+/system/bin/blkid       u:object_r:blkid_exec:s0
+/system/bin/tzdatacheck u:object_r:tzdatacheck_exec:s0
+/system/bin/idmap u:object_r:idmap_exec:s0
+/system/bin/update_engine        u:object_r:update_engine_exec:s0
+/system/bin/bspatch              u:object_r:update_engine_exec:s0
+
+#############################
+# Vendor files
+#
+/vendor(/.*)?		u:object_r:system_file:s0
+
+#############################
+# OEM and ODM files
+#
+/odm(/.*)?              u:object_r:system_file:s0
+/oem(/.*)?              u:object_r:oemfs:s0
+
+
+#############################
+# Data files
+#
+# NOTE: When modifying existing label rules, changes may also need to
+# propagate to the "Expanded data files" section.
+#
+/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/system/ndebugsocket	u:object_r:system_ndebug_socket:s0
+/data/drm(/.*)?		u:object_r:drm_data_file:s0
+/data/resource-cache(/.*)? u:object_r:resourcecache_data_file:s0
+/data/dalvik-cache(/.*)? u:object_r:dalvikcache_data_file:s0
+/data/adb(/.*)?		u:object_r:adb_data_file:s0
+/data/anr(/.*)?		u:object_r:anr_data_file:s0
+/data/app(/.*)?                       u:object_r:apk_data_file:s0
+/data/app/[^/]+/oat(/.*)?                u:object_r:dalvikcache_data_file:s0
+/data/app/vmdl[^/]+\.tmp(/.*)?           u:object_r:apk_tmp_file:s0
+/data/app/vmdl[^/]+\.tmp/oat(/.*)?           u:object_r:dalvikcache_data_file:s0
+/data/app-private(/.*)?               u:object_r:apk_private_data_file:s0
+/data/app-private/vmdl.*\.tmp(/.*)?   u:object_r:apk_private_tmp_file:s0
+/data/tombstones(/.*)?	u:object_r:tombstone_data_file:s0
+/data/local/tmp(/.*)?	u:object_r:shell_data_file:s0
+/data/media(/.*)?	u:object_r:media_rw_data_file:s0
+/data/mediadrm(/.*)?	u:object_r:media_data_file:s0
+/data/nativetest(/.*)?	u:object_r:nativetest_data_file:s0
+/data/property(/.*)?	u:object_r:property_data_file:s0
+
+# Misc data
+/data/misc/adb(/.*)?            u:object_r:adb_keys_file:s0
+/data/misc/audio(/.*)?          u:object_r:audio_data_file:s0
+/data/misc/bootstat(/.*)?       u:object_r:bootstat_data_file:s0
+/data/misc/boottrace(/.*)?      u:object_r:boottrace_data_file:s0
+/data/misc/bluetooth(/.*)?      u:object_r:bluetooth_data_file:s0
+/data/misc/bluedroid(/.*)?      u:object_r:bluetooth_data_file:s0
+/data/misc/bluedroid/\.a2dp_ctrl u:object_r:bluetooth_socket:s0
+/data/misc/bluedroid/\.a2dp_data u:object_r:bluetooth_socket:s0
+/data/misc/camera(/.*)?         u:object_r:camera_data_file:s0
+/data/misc/dhcp(/.*)?           u:object_r:dhcp_data_file:s0
+/data/misc/dhcp-6.8.2(/.*)?     u:object_r:dhcp_data_file:s0
+/data/misc/gatekeeper(/.*)?     u:object_r:gatekeeper_data_file:s0
+/data/misc/keychain(/.*)?       u:object_r:keychain_data_file:s0
+/data/misc/keystore(/.*)?       u:object_r:keystore_data_file:s0
+/data/misc/logd(/.*)?           u:object_r:misc_logd_file:s0
+/data/misc/media(/.*)?          u:object_r:media_data_file:s0
+/data/misc/net(/.*)?            u:object_r:net_data_file:s0
+/data/misc/recovery(/.*)?       u:object_r:recovery_data_file:s0
+/data/misc/shared_relro(/.*)?   u:object_r:shared_relro_file:s0
+/data/misc/sms(/.*)?            u:object_r:radio_data_file:s0
+/data/misc/systemkeys(/.*)?     u:object_r:systemkeys_data_file:s0
+/data/misc/user(/.*)?           u:object_r:misc_user_data_file:s0
+/data/misc/vpn(/.*)?            u:object_r:vpn_data_file:s0
+/data/misc/wifi(/.*)?           u:object_r:wifi_data_file:s0
+/data/misc/wifi/sockets(/.*)?   u:object_r:wpa_socket:s0
+/data/misc/wifi/sockets/wpa_ctrl.*   u:object_r:system_wpa_socket:s0
+/data/misc/wifi/hostapd(/.*)?   u:object_r:wpa_socket:s0
+/data/misc/zoneinfo(/.*)?       u:object_r:zoneinfo_data_file:s0
+/data/misc/vold(/.*)?           u:object_r:vold_data_file:s0
+/data/misc/perfprofd(/.*)?      u:object_r:perfprofd_data_file:s0
+/data/misc/update_engine(/.*)?  u:object_r:update_engine_data_file:s0
+/data/system/heapdump(/.*)?     u:object_r:heapdump_data_file:s0
+/data/misc/trace(/.*)?          u:object_r:method_trace_data_file:s0
+
+# Fingerprint data
+/data/system/users/[0-9]+/fpdata(/.*)? u:object_r:fingerprintd_data_file:s0
+
+# Bootchart data
+/data/bootchart(/.*)?		u:object_r:bootchart_data_file:s0
+
+#############################
+# Expanded data files
+#
+/mnt/expand(/.*)?                                   u:object_r:mnt_expand_file:s0
+/mnt/expand/[^/]+(/.*)?                             u:object_r:system_data_file:s0
+/mnt/expand/[^/]+/app(/.*)?                         u:object_r:apk_data_file:s0
+/mnt/expand/[^/]+/app/[^/]+/oat(/.*)?               u:object_r:dalvikcache_data_file:s0
+/mnt/expand/[^/]+/app/vmdl[^/]+\.tmp(/.*)?          u:object_r:apk_tmp_file:s0
+/mnt/expand/[^/]+/app/vmdl[^/]+\.tmp/oat(/.*)?      u:object_r:dalvikcache_data_file:s0
+/mnt/expand/[^/]+/local/tmp(/.*)?                   u:object_r:shell_data_file:s0
+/mnt/expand/[^/]+/media(/.*)?                       u:object_r:media_rw_data_file:s0
+/mnt/expand/[^/]+/misc/vold(/.*)?                   u:object_r:vold_data_file:s0
+
+# coredump directory for userdebug/eng devices
+/cores(/.*)?                    u:object_r:coredump_file:s0
+
+# Wallpaper file for other users
+/data/system/users/[0-9]+/wallpaper		u:object_r:wallpaper_file:s0
+#############################
+# efs files
+#
+/efs(/.*)?		u:object_r:efs_file:s0
+#############################
+# Cache files
+#
+/cache(/.*)?		u:object_r:cache_file:s0
+/cache/.*\.data	u:object_r:cache_backup_file:s0
+/cache/.*\.restore	u:object_r:cache_backup_file:s0
+# LocalTransport (backup) uses this directory
+/cache/backup(/.*)?	u:object_r:cache_backup_file:s0
+/cache/recovery(/.*)?	u:object_r:cache_recovery_file:s0
+#############################
+# sysfs files
+#
+/sys/devices/platform/nfc-power/nfc_power -- u:object_r:sysfs_nfc_power_writable:s0
+/sys/devices/system/cpu(/.*)?    u:object_r:sysfs_devices_system_cpu:s0
+/sys/devices/virtual/block/zram\d+(/.*)?     u:object_r:sysfs_zram:s0
+/sys/devices/virtual/block/zram\d+/uevent    u:object_r:sysfs_zram_uevent:s0
+/sys/devices/virtual/misc/hw_random(/.*)?    u:object_r:sysfs_hwrandom:s0
+/sys/power/wake_lock -- u:object_r:sysfs_wake_lock:s0
+/sys/power/wake_unlock -- u:object_r:sysfs_wake_lock:s0
+/sys/kernel/uevent_helper --	u:object_r:usermodehelper:s0
+/sys/module/lowmemorykiller(/.*)? -- u:object_r:sysfs_lowmemorykiller:s0
+
+#############################
+# debugfs files
+#
+/sys/kernel/debug/tracing(/.*)?          u:object_r:debugfs_tracing:s0
+/sys/kernel/debug/tracing/trace_marker   u:object_r:debugfs_trace_marker:s0
+
+#############################
+# asec containers
+/mnt/asec(/.*)?             u:object_r:asec_apk_file:s0
+/mnt/asec/[^/]+/[^/]+\.zip  u:object_r:asec_public_file:s0
+/mnt/asec/[^/]+/lib(/.*)?   u:object_r:asec_public_file:s0
+/data/app-asec(/.*)?        u:object_r:asec_image_file:s0
+
+#############################
+# external storage
+/mnt/media_rw(/.*)?         u:object_r:mnt_media_rw_file:s0
+/mnt/user(/.*)?             u:object_r:mnt_user_file:s0
+/mnt/runtime(/.*)?          u:object_r:storage_file:s0
+/storage(/.*)?              u:object_r:storage_file:s0
diff --git a/sepolicy/file_contexts_asan b/sepolicy/file_contexts_asan
new file mode 100644
index 0000000..5813d32
--- /dev/null
+++ b/sepolicy/file_contexts_asan
@@ -0,0 +1,4 @@
+/data/lib(/.*)?                u:object_r:system_file:s0
+/data/lib64(/.*)?              u:object_r:system_file:s0
+/data/vendor/lib(/.*)?         u:object_r:system_file:s0
+/data/vendor/lib64(/.*)?       u:object_r:system_file:s0
diff --git a/sepolicy/fingerprintd.te b/sepolicy/fingerprintd.te
new file mode 100644
index 0000000..1c0ab1c
--- /dev/null
+++ b/sepolicy/fingerprintd.te
@@ -0,0 +1,23 @@
+type fingerprintd, domain, domain_deprecated;
+type fingerprintd_exec, exec_type, file_type;
+
+# fingerprintd
+init_daemon_domain(fingerprintd)
+binder_use(fingerprintd)
+
+# need to find KeyStore and add self
+allow fingerprintd fingerprintd_service:service_manager { add find };
+
+# allow HAL module to read dir contents
+allow fingerprintd fingerprintd_data_file:file { create_file_perms };
+
+# allow HAL module to read/write/unlink contents of this dir
+allow fingerprintd fingerprintd_data_file:dir rw_dir_perms;
+
+# Need to add auth tokens to KeyStore
+use_keystore(fingerprintd)
+allow fingerprintd keystore:keystore_key { add_auth };
+
+# For permissions checking
+binder_call(fingerprintd, system_server);
+allow fingerprintd permission_service:service_manager find;
diff --git a/sepolicy/fs_use b/sepolicy/fs_use
new file mode 100644
index 0000000..4bd1112
--- /dev/null
+++ b/sepolicy/fs_use
@@ -0,0 +1,23 @@
+# Label inodes via getxattr.
+fs_use_xattr yaffs2 u:object_r:labeledfs:s0;
+fs_use_xattr jffs2 u:object_r:labeledfs:s0;
+fs_use_xattr ext2 u:object_r:labeledfs:s0;
+fs_use_xattr ext3 u:object_r:labeledfs:s0;
+fs_use_xattr ext4 u:object_r:labeledfs:s0;
+fs_use_xattr xfs u:object_r:labeledfs:s0;
+fs_use_xattr btrfs u:object_r:labeledfs:s0;
+fs_use_xattr f2fs u:object_r:labeledfs:s0;
+fs_use_xattr squashfs u:object_r:labeledfs:s0;
+
+# Label inodes from task label.
+fs_use_task pipefs u:object_r:pipefs:s0;
+fs_use_task sockfs u:object_r:sockfs:s0;
+
+# Label inodes from combination of task label and fs label.
+# Define type_transition rules if you want per-domain types.
+fs_use_trans devpts u:object_r:devpts:s0;
+fs_use_trans tmpfs u:object_r:tmpfs:s0;
+fs_use_trans devtmpfs u:object_r:device:s0;
+fs_use_trans shm u:object_r:shm:s0;
+fs_use_trans mqueue u:object_r:mqueue:s0;
+
diff --git a/sepolicy/fsck.te b/sepolicy/fsck.te
new file mode 100644
index 0000000..d5a6db1
--- /dev/null
+++ b/sepolicy/fsck.te
@@ -0,0 +1,47 @@
+# Any fsck program run by init
+type fsck, domain, domain_deprecated;
+type fsck_exec, exec_type, file_type;
+
+init_daemon_domain(fsck)
+
+# /dev/__null__ created by init prior to policy load,
+# open fd inherited by fsck.
+allow fsck tmpfs:chr_file { read write ioctl };
+
+# Inherit and use pty created by android_fork_execvp_ext().
+allow fsck devpts:chr_file { read write ioctl getattr };
+
+# Allow stdin/out back to vold
+allow fsck vold:fd use;
+allow fsck vold:fifo_file { read write getattr };
+
+# Run fsck on certain block devices
+allow fsck block_device:dir search;
+allow fsck userdata_block_device:blk_file rw_file_perms;
+allow fsck cache_block_device:blk_file rw_file_perms;
+allow fsck dm_device:blk_file rw_file_perms;
+
+# fsck performs a stat() on swap to verify that it is a valid
+# swap device before setting the EXT2_MF_SWAP mount flag.
+allow fsck swap_block_device:blk_file getattr;
+
+###
+### neverallow rules
+###
+
+# fsck should never be run on these block devices
+neverallow fsck {
+  boot_block_device
+  frp_block_device
+  metadata_block_device
+  recovery_block_device
+  root_block_device
+  swap_block_device
+  system_block_device
+  vold_device
+}:blk_file no_rw_file_perms;
+
+# Only allow entry from init or vold via fsck binaries
+neverallow { domain -init -vold } fsck:process transition;
+neverallow * fsck:process dyntransition;
+neverallow fsck { file_type fs_type -fsck_exec }:file entrypoint;
diff --git a/sepolicy/fsck_untrusted.te b/sepolicy/fsck_untrusted.te
new file mode 100644
index 0000000..00faa20
--- /dev/null
+++ b/sepolicy/fsck_untrusted.te
@@ -0,0 +1,36 @@
+# Any fsck program run on untrusted block devices
+type fsck_untrusted, domain, domain_deprecated;
+
+# Inherit and use pty created by android_fork_execvp_ext().
+allow fsck_untrusted devpts:chr_file { read write ioctl getattr };
+
+# Allow stdin/out back to vold
+allow fsck_untrusted vold:fd use;
+allow fsck_untrusted vold:fifo_file { read write getattr };
+
+# Run fsck on vold block devices
+allow fsck_untrusted block_device:dir search;
+allow fsck_untrusted vold_device:blk_file rw_file_perms;
+
+###
+### neverallow rules
+###
+
+# Untrusted fsck should never be run on block devices holding sensitive data
+neverallow fsck_untrusted {
+  boot_block_device
+  frp_block_device
+  metadata_block_device
+  recovery_block_device
+  root_block_device
+  swap_block_device
+  system_block_device
+  userdata_block_device
+  cache_block_device
+  dm_device
+}:blk_file no_rw_file_perms;
+
+# Only allow entry from vold via fsck binaries
+neverallow { domain -vold } fsck_untrusted:process transition;
+neverallow * fsck_untrusted:process dyntransition;
+neverallow fsck_untrusted { file_type fs_type -fsck_exec }:file entrypoint;
diff --git a/sepolicy/gatekeeperd.te b/sepolicy/gatekeeperd.te
new file mode 100644
index 0000000..81d7fdf
--- /dev/null
+++ b/sepolicy/gatekeeperd.te
@@ -0,0 +1,27 @@
+type gatekeeperd, domain, domain_deprecated;
+type gatekeeperd_exec, exec_type, file_type;
+
+# gatekeeperd
+init_daemon_domain(gatekeeperd)
+binder_service(gatekeeperd)
+binder_use(gatekeeperd)
+allow gatekeeperd tee_device:chr_file rw_file_perms;
+
+# need to find KeyStore and add self
+allow gatekeeperd gatekeeper_service:service_manager { add find };
+
+# Need to add auth tokens to KeyStore
+use_keystore(gatekeeperd)
+allow gatekeeperd keystore:keystore_key { add_auth };
+
+# For permissions checking
+allow gatekeeperd system_server:binder call;
+allow gatekeeperd permission_service:service_manager find;
+# For parent user ID lookup
+allow gatekeeperd user_service:service_manager find;
+
+# for SID file access
+allow gatekeeperd gatekeeper_data_file:dir rw_dir_perms;
+allow gatekeeperd gatekeeper_data_file:file create_file_perms;
+
+neverallow { domain -gatekeeperd } gatekeeper_service:service_manager add;
diff --git a/sepolicy/genfs_contexts b/sepolicy/genfs_contexts
new file mode 100644
index 0000000..bb2fea9
--- /dev/null
+++ b/sepolicy/genfs_contexts
@@ -0,0 +1,51 @@
+# Label inodes with the fs label.
+genfscon rootfs / u:object_r:rootfs:s0
+# proc labeling can be further refined (longest matching prefix).
+genfscon proc / u:object_r:proc:s0
+genfscon proc /interrupts u:object_r:proc_interrupts:s0
+genfscon proc /iomem u:object_r:proc_iomem:s0
+genfscon proc /meminfo u:object_r:proc_meminfo:s0
+genfscon proc /net u:object_r:proc_net:s0
+genfscon proc /net/xt_qtaguid/ctrl u:object_r:qtaguid_proc:s0
+genfscon proc /cpuinfo u:object_r:proc_cpuinfo:s0
+genfscon proc /softirqs u:object_r:proc_timer:s0
+genfscon proc /stat u:object_r:proc_stat:s0
+genfscon proc /sysrq-trigger u:object_r:proc_sysrq:s0
+genfscon proc /sys/fs/protected_hardlinks u:object_r:proc_security:s0
+genfscon proc /sys/fs/protected_symlinks u:object_r:proc_security:s0
+genfscon proc /sys/fs/suid_dumpable u:object_r:proc_security:s0
+genfscon proc /sys/kernel/core_pattern u:object_r:usermodehelper:s0
+genfscon proc /sys/kernel/dmesg_restrict u:object_r:proc_security:s0
+genfscon proc /sys/kernel/hotplug u:object_r:usermodehelper:s0
+genfscon proc /sys/kernel/kptr_restrict u:object_r:proc_security:s0
+genfscon proc /sys/kernel/modprobe u:object_r:usermodehelper:s0
+genfscon proc /sys/kernel/modules_disabled u:object_r:proc_security:s0
+genfscon proc /sys/kernel/poweroff_cmd u:object_r:usermodehelper:s0
+genfscon proc /sys/kernel/randomize_va_space u:object_r:proc_security:s0
+genfscon proc /sys/kernel/usermodehelper u:object_r:usermodehelper:s0
+genfscon proc /sys/net u:object_r:proc_net:s0
+genfscon proc /sys/vm/mmap_min_addr u:object_r:proc_security:s0
+genfscon proc /sys/vm/drop_caches u:object_r:proc_drop_caches:s0
+genfscon proc /sys/vm/overcommit_memory u:object_r:proc_overcommit_memory:s0
+genfscon proc /timer_list u:object_r:proc_timer:s0
+genfscon proc /timer_stats u:object_r:proc_timer:s0
+genfscon proc /uid_cputime/show_uid_stat u:object_r:proc_uid_cputime_showstat:s0
+genfscon proc /uid_cputime/remove_uid_range u:object_r:proc_uid_cputime_removeuid:s0
+genfscon proc /zoneinfo u:object_r:proc_zoneinfo:s0
+
+# selinuxfs booleans can be individually labeled.
+genfscon selinuxfs / u:object_r:selinuxfs:s0
+genfscon cgroup / u:object_r:cgroup:s0
+# sysfs labels can be set by userspace.
+genfscon sysfs / u:object_r:sysfs:s0
+genfscon inotifyfs / u:object_r:inotify:s0
+genfscon vfat / u:object_r:vfat:s0
+genfscon debugfs / u:object_r:debugfs:s0
+genfscon tracefs / u:object_r:debugfs_tracing:s0
+genfscon fuse / u:object_r:fuse:s0
+genfscon configfs / u:object_r:configfs:s0
+genfscon sdcardfs / u:object_r:sdcardfs:s0
+genfscon pstore / u:object_r:pstorefs:s0
+genfscon functionfs / u:object_r:functionfs:s0
+genfscon usbfs / u:object_r:usbfs:s0
+genfscon binfmt_misc / u:object_r:binfmt_miscfs:s0
diff --git a/sepolicy/global_macros b/sepolicy/global_macros
new file mode 100644
index 0000000..0534e46
--- /dev/null
+++ b/sepolicy/global_macros
@@ -0,0 +1,46 @@
+#####################################
+# Common groupings of object classes.
+#
+define(`capability_class_set', `{ capability capability2 }')
+
+define(`devfile_class_set', `{ chr_file blk_file }')
+define(`notdevfile_class_set', `{ file lnk_file sock_file fifo_file }')
+define(`file_class_set', `{ devfile_class_set notdevfile_class_set }')
+define(`dir_file_class_set', `{ dir file_class_set }')
+
+define(`socket_class_set', `{ socket tcp_socket udp_socket rawip_socket netlink_socket packet_socket key_socket unix_stream_socket unix_dgram_socket appletalk_socket netlink_route_socket netlink_firewall_socket netlink_tcpdiag_socket netlink_nflog_socket netlink_xfrm_socket netlink_selinux_socket netlink_audit_socket netlink_ip6fw_socket netlink_dnrt_socket netlink_kobject_uevent_socket tun_socket netlink_iscsi_socket netlink_fib_lookup_socket netlink_connector_socket netlink_netfilter_socket netlink_generic_socket netlink_scsitransport_socket netlink_rdma_socket netlink_crypto_socket }')
+define(`dgram_socket_class_set', `{ udp_socket unix_dgram_socket }')
+define(`stream_socket_class_set', `{ tcp_socket unix_stream_socket }')
+define(`unpriv_socket_class_set', `{ tcp_socket udp_socket unix_stream_socket unix_dgram_socket }')
+
+define(`ipc_class_set', `{ sem msgq shm ipc }')
+
+#####################################
+# Common groupings of permissions.
+#
+define(`x_file_perms', `{ getattr execute execute_no_trans }')
+define(`r_file_perms', `{ getattr open read ioctl lock }')
+define(`w_file_perms', `{ open append write lock }')
+define(`rx_file_perms', `{ r_file_perms x_file_perms }')
+define(`ra_file_perms', `{ r_file_perms append }')
+define(`rw_file_perms', `{ r_file_perms w_file_perms }')
+define(`rwx_file_perms', `{ rw_file_perms x_file_perms }')
+define(`create_file_perms', `{ create rename setattr unlink rw_file_perms }')
+
+define(`r_dir_perms', `{ open getattr read search ioctl lock }')
+define(`w_dir_perms', `{ open search write add_name remove_name lock }')
+define(`ra_dir_perms', `{ r_dir_perms add_name write }')
+define(`rw_dir_perms', `{ r_dir_perms w_dir_perms }')
+define(`create_dir_perms', `{ create reparent rename rmdir setattr rw_dir_perms }')
+
+define(`r_ipc_perms', `{ getattr read associate unix_read }')
+define(`w_ipc_perms', `{ write unix_write }')
+define(`rw_ipc_perms', `{ r_ipc_perms w_ipc_perms }')
+define(`create_ipc_perms', `{ create setattr destroy rw_ipc_perms }')
+
+#####################################
+# Common socket permission sets.
+define(`rw_socket_perms', `{ ioctl read getattr write setattr lock append bind connect getopt setopt shutdown }')
+define(`create_socket_perms', `{ create rw_socket_perms }')
+define(`rw_stream_socket_perms', `{ rw_socket_perms listen accept }')
+define(`create_stream_socket_perms', `{ create rw_stream_socket_perms }')
diff --git a/sepolicy/hci_attach.te b/sepolicy/hci_attach.te
new file mode 100644
index 0000000..543cae1
--- /dev/null
+++ b/sepolicy/hci_attach.te
@@ -0,0 +1,9 @@
+type hci_attach, domain, domain_deprecated;
+type hci_attach_exec, exec_type, file_type;
+
+init_daemon_domain(hci_attach)
+
+allow hci_attach kernel:system module_request;
+allow hci_attach hci_attach_dev:chr_file rw_file_perms;
+allow hci_attach bluetooth_efs_file:dir r_dir_perms;
+allow hci_attach bluetooth_efs_file:file r_file_perms;
diff --git a/sepolicy/healthd.te b/sepolicy/healthd.te
new file mode 100644
index 0000000..f54d716
--- /dev/null
+++ b/sepolicy/healthd.te
@@ -0,0 +1,48 @@
+# healthd seclabel is specified in init.rc since
+# it lives in the rootfs and has no unique file type.
+type healthd, domain, domain_deprecated;
+
+# Write to /dev/kmsg
+allow healthd kmsg_device:chr_file rw_file_perms;
+
+# Read access to pseudo filesystems.
+r_dir_file(healthd, sysfs)
+
+allow healthd self:capability { net_admin sys_tty_config };
+wakelock_use(healthd)
+allow healthd self:netlink_kobject_uevent_socket create_socket_perms;
+binder_use(healthd)
+binder_service(healthd)
+binder_call(healthd, system_server)
+
+# Write to state file.
+# TODO:  Split into a separate type?
+allow healthd sysfs:file write;
+
+allow healthd sysfs_batteryinfo:file r_file_perms;
+
+###
+### healthd: charger mode
+###
+
+# Read /sys/fs/pstore/console-ramoops
+# Don't worry about overly broad permissions for now, as there's
+# only one file in /sys/fs/pstore
+allow healthd pstorefs:dir r_dir_perms;
+allow healthd pstorefs:file r_file_perms;
+
+allow healthd graphics_device:dir r_dir_perms;
+allow healthd graphics_device:chr_file rw_file_perms;
+allow healthd input_device:dir r_dir_perms;
+allow healthd input_device:chr_file r_file_perms;
+allow healthd tty_device:chr_file rw_file_perms;
+allow healthd ashmem_device:chr_file execute;
+allow healthd self:process execmem;
+allow healthd proc_sysrq:file rw_file_perms;
+allow healthd self:capability sys_boot;
+
+allow healthd batteryproperties_service:service_manager { add find };
+
+# Healthd needs to tell init to continue the boot
+# process when running in charger mode.
+set_prop(healthd, system_prop)
diff --git a/sepolicy/hostapd.te b/sepolicy/hostapd.te
new file mode 100644
index 0000000..204a0d9
--- /dev/null
+++ b/sepolicy/hostapd.te
@@ -0,0 +1,27 @@
+# userspace wifi access points
+type hostapd, domain, domain_deprecated;
+type hostapd_exec, exec_type, file_type;
+
+net_domain(hostapd)
+
+allow hostapd self:capability { net_admin net_raw setuid setgid };
+allow hostapd self:netlink_socket create_socket_perms;
+allow hostapd self:netlink_generic_socket create_socket_perms;
+allow hostapd self:packet_socket create_socket_perms;
+allow hostapd self:netlink_route_socket nlmsg_write;
+
+allow hostapd wifi_data_file:file rw_file_perms;
+allow hostapd wifi_data_file:dir create_dir_perms;
+type_transition hostapd wifi_data_file:dir wpa_socket "sockets";
+type_transition hostapd wifi_data_file:dir wpa_socket "hostapd";
+allow hostapd wpa_socket:dir create_dir_perms;
+allow hostapd wpa_socket:sock_file create_file_perms;
+allow hostapd netd:fd use;
+allow hostapd netd:udp_socket { read write };
+allow hostapd netd:fifo_file { read write };
+# TODO: Investigate whether these inherited sockets should be closed on exec.
+allow hostapd netd:netlink_kobject_uevent_socket { read write };
+allow hostapd netd:netlink_nflog_socket { read write };
+allow hostapd netd:netlink_route_socket { read write };
+allow hostapd netd:unix_stream_socket { read write };
+allow hostapd netd:unix_dgram_socket { read write };
diff --git a/sepolicy/idmap.te b/sepolicy/idmap.te
new file mode 100644
index 0000000..c1b4d0f
--- /dev/null
+++ b/sepolicy/idmap.te
@@ -0,0 +1,10 @@
+# idmap, when executed by installd
+type idmap, domain, domain_deprecated;
+type idmap_exec, exec_type, file_type;
+
+# Use open file to /data/resource-cache file inherited from installd.
+allow idmap installd:fd use;
+allow idmap resourcecache_data_file:file { getattr read write };
+
+# Open and read from target and overlay apk files passed by argument.
+allow idmap apk_data_file:file r_file_perms;
diff --git a/sepolicy/init.te b/sepolicy/init.te
new file mode 100644
index 0000000..2b64953
--- /dev/null
+++ b/sepolicy/init.te
@@ -0,0 +1,369 @@
+# init is its own domain.
+type init, domain, domain_deprecated, mlstrustedsubject;
+tmpfs_domain(init)
+
+# The init domain is entered by execing init.
+type init_exec, exec_type, file_type;
+
+# /dev/__null__ node created by init.
+allow init tmpfs:chr_file create_file_perms;
+
+#
+# init direct restorecon calls.
+#
+# /dev/kmsg
+allow init tmpfs:chr_file relabelfrom;
+allow init kmsg_device:chr_file { write relabelto };
+# /dev/__properties__
+allow init properties_device:dir relabelto;
+allow init properties_serial:file { write relabelto };
+allow init property_type:file { create_file_perms relabelto };
+# /dev/socket
+allow init { device socket_device }:dir relabelto;
+# /dev/device-mapper, /dev/block(/.*)?
+allow init tmpfs:{ chr_file blk_file } relabelfrom;
+allow init tmpfs:blk_file getattr;
+allow init block_device:{ dir blk_file } relabelto;
+allow init dm_device:{ chr_file blk_file } relabelto;
+
+# setrlimit
+allow init self:capability sys_resource;
+
+# Remove /dev/.booting, created before initial policy load or restorecon /dev.
+allow init tmpfs:file unlink;
+
+# Access pty created for fsck.
+allow init devpts:chr_file { read write open };
+
+# Create /dev/fscklogs files.
+allow init fscklogs:file create_file_perms;
+
+# Access /dev/__null__ node created prior to initial policy load.
+allow init tmpfs:chr_file write;
+
+# Access /dev/console.
+allow init console_device:chr_file rw_file_perms;
+
+# Access /dev/tty0.
+allow init tty_device:chr_file rw_file_perms;
+
+# Call mount(2).
+allow init self:capability sys_admin;
+
+# Create and mount on directories in /.
+allow init rootfs:dir create_dir_perms;
+allow init { rootfs cache_file cgroup storage_file system_data_file system_file }:dir mounton;
+
+# Mount on /dev/usb-ffs/adb.
+allow init device:dir mounton;
+
+# Create and remove symlinks in /.
+allow init rootfs:lnk_file { create unlink };
+
+# Mount debugfs on /sys/kernel/debug.
+allow init sysfs:dir mounton;
+
+# Create cgroups mount points in tmpfs and mount cgroups on them.
+allow init tmpfs:dir create_dir_perms;
+allow init tmpfs:dir mounton;
+allow init cgroup:dir create_dir_perms;
+allow init cpuctl_device:dir { create mounton };
+
+# /config
+allow init configfs:dir mounton;
+allow init configfs:dir create_dir_perms;
+
+# Use tmpfs as /data, used for booting when /data is encrypted
+allow init tmpfs:dir relabelfrom;
+
+# Create directories under /dev/cpuctl after chowning it to system.
+allow init self:capability dac_override;
+
+# Set system clock.
+allow init self:capability sys_time;
+
+allow init self:capability { sys_rawio mknod };
+
+# Mounting filesystems from block devices.
+allow init dev_type:blk_file r_file_perms;
+
+# Mounting filesystems.
+# Only allow relabelto for types used in context= mount options,
+# which should all be assigned the contextmount_type attribute.
+# This can be done in device-specific policy via type or typeattribute
+# declarations.
+allow init fs_type:filesystem ~relabelto;
+allow init unlabeled:filesystem ~relabelto;
+allow init contextmount_type:filesystem relabelto;
+
+# Allow read-only access to context= mounted filesystems.
+allow init contextmount_type:dir r_dir_perms;
+allow init contextmount_type:notdevfile_class_set r_file_perms;
+
+# restorecon /adb_keys or any other rootfs files and directories to a more
+# specific type.
+allow init rootfs:{ dir file } relabelfrom;
+
+# mkdir, symlink, write, rm/rmdir, chown/chmod, restorecon/restorecon_recursive from init.rc files.
+# chown/chmod require open+read+setattr required for open()+fchown/fchmod().
+# system/core/init.rc requires at least cache_file and data_file_type.
+# init.<board>.rc files often include device-specific types, so
+# we just allow all file types except /system files here.
+allow init self:capability { chown fowner fsetid };
+
+allow init {
+  file_type
+  -system_file
+  -exec_type
+  -app_data_file
+  -system_app_data_file
+}:dir { create search getattr open read setattr ioctl };
+
+allow init {
+  file_type
+  -system_file
+  -exec_type
+  -keystore_data_file
+  -app_data_file
+  -system_app_data_file
+  -shell_data_file
+  -vold_data_file
+  -misc_logd_file
+}:dir { write add_name remove_name rmdir relabelfrom };
+
+allow init {
+  file_type
+  -system_file
+  -exec_type
+  -keystore_data_file
+  -app_data_file
+  -system_app_data_file
+  -shell_data_file
+  -vold_data_file
+  -misc_logd_file
+}:file { create getattr open read write setattr relabelfrom unlink };
+
+allow init {
+  file_type
+  -system_file
+  -exec_type
+  -keystore_data_file
+  -app_data_file
+  -system_app_data_file
+  -shell_data_file
+  -vold_data_file
+  -misc_logd_file
+}:{ sock_file fifo_file } { create getattr open read setattr relabelfrom unlink };
+
+allow init {
+  file_type
+  -system_file
+  -exec_type
+  -keystore_data_file
+  -app_data_file
+  -system_app_data_file
+  -shell_data_file
+  -vold_data_file
+  -misc_logd_file
+}:lnk_file { create getattr setattr relabelfrom unlink };
+
+allow init {file_type -system_file -exec_type}:dir_file_class_set relabelto;
+allow init { sysfs debugfs debugfs_tracing }:{ dir file lnk_file } { getattr relabelfrom };
+allow init { sysfs_type debugfs_type }:{ dir file lnk_file } relabelto;
+allow init dev_type:dir create_dir_perms;
+allow init dev_type:lnk_file create;
+
+# Disable tracing by writing to /sys/kernel/debug/tracing/tracing_on
+allow init debugfs_tracing:file w_file_perms;
+
+# chown/chmod on pseudo files.
+allow init { fs_type -contextmount_type -sdcard_type -rootfs }:file { open read setattr };
+allow init { fs_type -contextmount_type -sdcard_type -rootfs }:dir  { open read setattr search };
+
+# chown/chmod on devices.
+allow init { dev_type -kmem_device }:chr_file { read open setattr };
+
+# Unlabeled file access for upgrades from 4.2.
+allow init unlabeled:dir { create_dir_perms relabelfrom };
+allow init unlabeled:notdevfile_class_set { create_file_perms relabelfrom };
+
+# Any operation that can modify the kernel ring buffer, e.g. clear
+# or a read that consumes the messages that were read.
+allow init kernel:system syslog_mod;
+allow init self:capability2 syslog;
+
+# Set usermodehelpers and /proc security settings.
+allow init usermodehelper:file rw_file_perms;
+allow init proc_security:file rw_file_perms;
+
+# Write to /proc/sys/kernel/panic_on_oops.
+allow init proc:file w_file_perms;
+
+# Write to /proc/sys/net/ping_group_range and other /proc/sys/net files.
+allow init proc_net:file w_file_perms;
+allow init self:capability net_admin;
+
+# Write to /proc/sysrq-trigger.
+allow init proc_sysrq:file w_file_perms;
+
+# Read /proc/stat for bootchart.
+allow init proc_stat:file r_file_perms;
+
+# Reboot.
+allow init self:capability sys_boot;
+
+# Write to sysfs nodes.
+allow init sysfs_type:dir r_dir_perms;
+allow init sysfs_type:lnk_file read;
+allow init sysfs_type:file w_file_perms;
+
+# disksize
+allow init sysfs_zram:file getattr;
+
+# Transitions to seclabel processes in init.rc
+domain_trans(init, rootfs, adbd)
+domain_trans(init, rootfs, healthd)
+domain_trans(init, rootfs, slideshow)
+recovery_only(`
+  domain_trans(init, rootfs, recovery)
+')
+domain_trans(init, shell_exec, shell)
+domain_trans(init, init_exec, ueventd)
+domain_trans(init, init_exec, watchdogd)
+# case where logpersistd is actually logcat -f in logd context (nee: logcatd)
+userdebug_or_eng(`
+  domain_auto_trans(init, logcat_exec, logd)
+')
+
+# Init will create /data/misc/logd when the property persist.logd.logpersistd is "logcatd".
+# Init will also walk through the directory as part of a recursive restorecon.
+allow init misc_logd_file:dir { open create read getattr setattr search };
+allow init misc_logd_file:file { getattr };
+
+# Support "adb shell stop"
+allow init self:capability kill;
+allow init domain:process { sigkill signal };
+
+# Init creates keystore's directory on boot, and walks through
+# the directory as part of a recursive restorecon.
+allow init keystore_data_file:dir { open create read getattr setattr search };
+allow init keystore_data_file:file { getattr };
+
+# Init creates vold's directory on boot, and walks through
+# the directory as part of a recursive restorecon.
+allow init vold_data_file:dir { open create read getattr setattr search };
+allow init vold_data_file:file { getattr };
+
+# Init creates /data/local/tmp at boot
+allow init shell_data_file:dir { open create read getattr setattr search };
+allow init shell_data_file:file { getattr };
+
+# Set UID and GID for services.
+allow init self:capability { setuid setgid };
+
+# For bootchart to read the /proc/$pid/cmdline file of each process,
+# we need to have following line to allow init to have access
+# to different domains.
+r_dir_file(init, domain)
+
+# Use setexeccon(), setfscreatecon(), and setsockcreatecon().
+# setexec is for services with seclabel options.
+# setfscreate is for labeling directories and socket files.
+# setsockcreate is for labeling local/unix domain sockets.
+allow init self:process { setexec setfscreate setsockcreate };
+
+# Perform SELinux access checks on setting properties.
+selinux_check_access(init)
+
+# Ask the kernel for the new context on services to label their sockets.
+allow init kernel:security compute_create;
+
+# Create sockets for the services.
+allow init domain:unix_stream_socket { create bind };
+allow init domain:unix_dgram_socket { create bind };
+
+# Create /data/property and files within it.
+allow init property_data_file:dir create_dir_perms;
+allow init property_data_file:file create_file_perms;
+
+# Set any property.
+allow init property_type:property_service set;
+
+# Run "ifup lo" to bring up the localhost interface
+allow init self:udp_socket { create ioctl };
+allow init self:capability net_raw;
+
+# This line seems suspect, as it should not really need to
+# set scheduling parameters for a kernel domain task.
+allow init kernel:process setsched;
+
+# swapon() needs write access to swap device
+# system/core/fs_mgr/fs_mgr.c - fs_mgr_swapon_all
+allow init swap_block_device:blk_file rw_file_perms;
+
+# Read from /dev/hw_random if present.
+# system/core/init/init.c - mix_hwrng_into_linux_rng_action
+allow init hw_random_device:chr_file r_file_perms;
+
+# Create and access /dev files without a specific type,
+# e.g. /dev/.coldboot_done, /dev/.booting
+# TODO:  Move these files into their own type unless they are
+# only ever accessed by init.
+allow init device:file create_file_perms;
+
+# Access character devices without a specific type,
+# e.g. /dev/keychord.
+# TODO: Move these devices into their own type unless they
+# are only ever accessed by init.
+allow init device:chr_file { rw_file_perms setattr };
+
+# keychord configuration
+allow init self:capability sys_tty_config;
+
+# Access device mapper for setting up dm-verity
+allow init dm_device:chr_file rw_file_perms;
+allow init dm_device:blk_file rw_file_perms;
+
+# Access metadata block device for storing dm-verity state
+allow init metadata_block_device:blk_file rw_file_perms;
+
+# Read /sys/fs/pstore/console-ramoops to detect restarts caused
+# by dm-verity detecting corrupted blocks
+allow init pstorefs:dir search;
+allow init pstorefs:file r_file_perms;
+allow init kernel:system syslog_read;
+
+# linux keyring configuration
+allow init init:key { write search setattr };
+
+# Allow init to create /data/unencrypted
+allow init unencrypted_data_file:dir create_dir_perms;
+
+# Allow init to write to /proc/sys/vm/overcommit_memory
+allow init proc_overcommit_memory:file { write };
+
+unix_socket_connect(init, vold, vold)
+
+###
+### neverallow rules
+###
+
+# The init domain is only entered via setcon from the kernel domain,
+# never via an exec-based transition.
+neverallow domain init:process dyntransition;
+neverallow { domain -kernel} init:process transition;
+neverallow init { file_type fs_type -init_exec }:file entrypoint;
+
+# Never read/follow symlinks created by shell or untrusted apps.
+neverallow init shell_data_file:lnk_file read;
+neverallow init app_data_file:lnk_file read;
+
+# init should never execute a program without changing to another domain.
+neverallow init { file_type fs_type }:file execute_no_trans;
+
+# Init never adds or uses services via service_manager.
+neverallow init service_manager_type:service_manager { add find };
+neverallow init servicemanager:service_manager list;
+
+# Init should not be creating subdirectories in /data/local/tmp
+neverallow init shell_data_file:dir { write add_name remove_name };
diff --git a/sepolicy/initial_sid_contexts b/sepolicy/initial_sid_contexts
new file mode 100644
index 0000000..9819051
--- /dev/null
+++ b/sepolicy/initial_sid_contexts
@@ -0,0 +1,27 @@
+sid kernel u:r:kernel:s0
+sid security u:object_r:kernel:s0
+sid unlabeled u:object_r:unlabeled:s0
+sid fs u:object_r:labeledfs:s0
+sid file u:object_r:unlabeled:s0
+sid file_labels u:object_r:unlabeled:s0
+sid init u:object_r:unlabeled:s0
+sid any_socket u:object_r:unlabeled:s0
+sid port u:object_r:port:s0
+sid netif u:object_r:netif:s0
+sid netmsg u:object_r:unlabeled:s0
+sid node u:object_r:node:s0
+sid igmp_packet u:object_r:unlabeled:s0
+sid icmp_socket u:object_r:unlabeled:s0
+sid tcp_socket u:object_r:unlabeled:s0
+sid sysctl_modprobe u:object_r:unlabeled:s0
+sid sysctl u:object_r:proc:s0
+sid sysctl_fs u:object_r:unlabeled:s0
+sid sysctl_kernel u:object_r:unlabeled:s0
+sid sysctl_net u:object_r:unlabeled:s0
+sid sysctl_net_unix u:object_r:unlabeled:s0
+sid sysctl_vm u:object_r:unlabeled:s0
+sid sysctl_dev u:object_r:unlabeled:s0
+sid kmod u:object_r:unlabeled:s0
+sid policy u:object_r:unlabeled:s0
+sid scmp_packet u:object_r:unlabeled:s0
+sid devnull u:object_r:null_device:s0
diff --git a/sepolicy/initial_sids b/sepolicy/initial_sids
new file mode 100644
index 0000000..91ac816
--- /dev/null
+++ b/sepolicy/initial_sids
@@ -0,0 +1,35 @@
+# FLASK
+
+#
+# Define initial security identifiers
+#
+
+sid kernel
+sid security
+sid unlabeled
+sid fs
+sid file
+sid file_labels
+sid init
+sid any_socket
+sid port
+sid netif
+sid netmsg
+sid node
+sid igmp_packet
+sid icmp_socket
+sid tcp_socket
+sid sysctl_modprobe
+sid sysctl
+sid sysctl_fs
+sid sysctl_kernel
+sid sysctl_net
+sid sysctl_net_unix
+sid sysctl_vm
+sid sysctl_dev
+sid kmod
+sid policy
+sid scmp_packet
+sid devnull
+
+# FLASK
diff --git a/sepolicy/inputflinger.te b/sepolicy/inputflinger.te
new file mode 100644
index 0000000..324f3f6
--- /dev/null
+++ b/sepolicy/inputflinger.te
@@ -0,0 +1,15 @@
+# inputflinger
+type inputflinger, domain, domain_deprecated;
+type inputflinger_exec, exec_type, file_type;
+
+init_daemon_domain(inputflinger)
+binder_use(inputflinger)
+binder_service(inputflinger)
+
+binder_call(inputflinger, system_server)
+
+wakelock_use(inputflinger)
+
+allow inputflinger inputflinger_service:service_manager { add find };
+allow inputflinger input_device:dir r_dir_perms;
+allow inputflinger input_device:chr_file rw_file_perms;
diff --git a/sepolicy/install_recovery.te b/sepolicy/install_recovery.te
new file mode 100644
index 0000000..b11ff74
--- /dev/null
+++ b/sepolicy/install_recovery.te
@@ -0,0 +1,28 @@
+# service flash_recovery in init.rc
+type install_recovery, domain, domain_deprecated;
+type install_recovery_exec, exec_type, file_type;
+
+init_daemon_domain(install_recovery)
+
+allow install_recovery self:capability dac_override;
+
+# /system/bin/install-recovery.sh is a shell script.
+# Needs to execute /system/bin/sh
+allow install_recovery shell_exec:file rx_file_perms;
+
+# Execute /system/bin/applypatch
+allow install_recovery system_file:file rx_file_perms;
+
+allow install_recovery toolbox_exec:file rx_file_perms;
+
+# Update the recovery block device based off a diff of the boot block device
+allow install_recovery block_device:dir search;
+allow install_recovery boot_block_device:blk_file r_file_perms;
+allow install_recovery recovery_block_device:blk_file rw_file_perms;
+
+# Create and delete /cache/saved.file
+allow install_recovery cache_file:dir rw_dir_perms;
+allow install_recovery cache_file:file create_file_perms;
+
+# Write to /proc/sys/vm/drop_caches
+allow install_recovery proc_drop_caches:file w_file_perms;
diff --git a/sepolicy/installd.te b/sepolicy/installd.te
new file mode 100644
index 0000000..1f83501
--- /dev/null
+++ b/sepolicy/installd.te
@@ -0,0 +1,94 @@
+# installer daemon
+type installd, domain, domain_deprecated;
+type installd_exec, exec_type, file_type;
+
+init_daemon_domain(installd)
+typeattribute installd mlstrustedsubject;
+allow installd self:capability { chown dac_override fowner fsetid setgid setuid };
+
+# Allow labeling of files under /data/app/com.example/oat/
+allow installd dalvikcache_data_file:dir relabelto;
+allow installd dalvikcache_data_file:file { relabelto link };
+
+# Allow movement of APK files between volumes
+allow installd apk_data_file:dir { create_dir_perms relabelfrom };
+allow installd apk_data_file:file { create_file_perms relabelfrom link };
+allow installd apk_data_file:lnk_file { create read unlink };
+
+allow installd asec_apk_file:file r_file_perms;
+allow installd apk_tmp_file:file { r_file_perms unlink };
+allow installd apk_tmp_file:dir { relabelfrom create_dir_perms };
+allow installd oemfs:dir r_dir_perms;
+allow installd oemfs:file r_file_perms;
+allow installd cgroup:dir create_dir_perms;
+allow installd mnt_expand_file:dir { search getattr };
+# Check validity of SELinux context before use.
+selinux_check_context(installd)
+
+# Search /data/app-asec and stat files in it.
+allow installd asec_image_file:dir search;
+allow installd asec_image_file:file getattr;
+
+# Create /data/user and /data/user/0 if necessary.
+# Also required to initially create /data/data subdirectories
+# and lib symlinks before the setfilecon call.  May want to
+# move symlink creation after setfilecon in installd.
+allow installd system_data_file:dir create_dir_perms;
+allow installd system_data_file:lnk_file { create setattr unlink };
+
+# Upgrade /data/media for multi-user if necessary.
+allow installd media_rw_data_file:dir create_dir_perms;
+allow installd media_rw_data_file:file { getattr unlink };
+# restorecon new /data/media directory.
+allow installd system_data_file:dir relabelfrom;
+allow installd media_rw_data_file:dir relabelto;
+
+# Upgrade /data/misc/keychain for multi-user if necessary.
+allow installd misc_user_data_file:dir create_dir_perms;
+allow installd misc_user_data_file:file create_file_perms;
+allow installd keychain_data_file:dir create_dir_perms;
+allow installd keychain_data_file:file {r_file_perms unlink};
+
+# Create /data/.layout_version.* file
+type_transition installd system_data_file:file install_data_file;
+allow installd install_data_file:file create_file_perms;
+
+# Create files under /data/dalvik-cache.
+allow installd dalvikcache_data_file:dir create_dir_perms;
+allow installd dalvikcache_data_file:file create_file_perms;
+
+# Create files under /data/resource-cache.
+allow installd resourcecache_data_file:dir rw_dir_perms;
+allow installd resourcecache_data_file:file create_file_perms;
+
+# Run dex2oat in its own sandbox.
+domain_auto_trans(installd, dex2oat_exec, dex2oat)
+
+# Run idmap in its own sandbox.
+domain_auto_trans(installd, idmap_exec, idmap)
+
+# Upgrade from unlabeled userdata.
+# Just need enough to remove and/or relabel it.
+allow installd unlabeled:dir { getattr search relabelfrom rw_dir_perms rmdir };
+allow installd unlabeled:notdevfile_class_set { getattr relabelfrom rename unlink setattr };
+# Read pkg.apk file for input during dexopt.
+allow installd unlabeled:file r_file_perms;
+
+# Upgrade from before system_app_data_file was used for system UID apps.
+# Just need enough to relabel it and to unlink removed package files.
+# Directory access covered by earlier rule above.
+allow installd system_data_file:notdevfile_class_set { getattr relabelfrom unlink };
+
+# Manage /data/data subdirectories, including initially labeling them
+# upon creation via setfilecon or running restorecon_recursive,
+# setting owner/mode, creating symlinks within them, and deleting them
+# upon package uninstall.
+# Types extracted from seapp_contexts type= fields.
+allow installd { system_app_data_file bluetooth_data_file nfc_data_file radio_data_file shell_data_file app_data_file }:dir { create_dir_perms relabelfrom relabelto };
+allow installd { system_app_data_file bluetooth_data_file nfc_data_file radio_data_file shell_data_file app_data_file }:notdevfile_class_set { create_file_perms relabelfrom relabelto };
+
+# Create and use pty created by android_fork_execvp().
+allow installd devpts:chr_file rw_file_perms;
+
+# execute toybox for app relocation
+allow installd toolbox_exec:file rx_file_perms;
diff --git a/sepolicy/ioctl_macros b/sepolicy/ioctl_macros
new file mode 100644
index 0000000..e71e0ce
--- /dev/null
+++ b/sepolicy/ioctl_macros
@@ -0,0 +1,11 @@
+# socket ioctls allowed to unprivileged apps
+define(`unpriv_sock_ioctls', `
+{
+# all socket ioctls except the Mac address SIOCGIFHWADDR 0x8927
+0x8900-0x8926 0x8928-0x89ff
+# all wireless extensions ioctls except get/set essid
+# IOCSIWESSID 0x8B1A SIOCGIWESSID 0x8B1B
+0x8B00-0x8B09 0x8B1C-0x8BFF
+# commonly used TTY ioctls
+0x5411 0x5451
+}')
diff --git a/sepolicy/isolated_app.te b/sepolicy/isolated_app.te
new file mode 100644
index 0000000..124fde9
--- /dev/null
+++ b/sepolicy/isolated_app.te
@@ -0,0 +1,62 @@
+###
+### Services with isolatedProcess=true in their manifest.
+###
+### This file defines the rules for isolated apps. An "isolated
+### app" is an APP with UID between AID_ISOLATED_START (99000)
+### and AID_ISOLATED_END (99999).
+###
+### isolated_app includes all the appdomain rules, plus the
+### additional following rules:
+###
+
+type isolated_app, domain;
+app_domain(isolated_app)
+
+# Access already open app data files received over Binder or local socket IPC.
+allow isolated_app app_data_file:file { read write getattr lock };
+
+allow isolated_app activity_service:service_manager find;
+allow isolated_app display_service:service_manager find;
+
+# Google Breakpad (crash reporter for Chrome) relies on ptrace
+# functionality. Without the ability to ptrace, the crash reporter
+# tool is broken.
+# b/20150694
+# https://code.google.com/p/chromium/issues/detail?id=475270
+allow isolated_app self:process ptrace;
+
+#####
+##### Neverallow
+#####
+
+# Do not allow isolated_app to directly open tun_device
+neverallow isolated_app tun_device:chr_file open;
+
+# Do not allow isolated_app to set system properties.
+neverallow isolated_app property_socket:sock_file write;
+neverallow isolated_app property_type:property_service set;
+
+# Isolated apps should not directly open app data files themselves.
+neverallow isolated_app app_data_file:file open;
+
+# Only allow appending to /data/anr/traces.txt (b/27853304, b/18340553)
+# TODO: are there situations where isolated_apps write to this file?
+# TODO: should we tighten these restrictions further?
+neverallow isolated_app anr_data_file:file ~{ open append };
+neverallow isolated_app anr_data_file:dir ~search;
+
+# b/17487348
+# Isolated apps can only access two services,
+# activity_service and display_service
+neverallow isolated_app {
+    service_manager_type
+    -activity_service
+    -display_service
+}:service_manager find;
+
+# Isolated apps shouldn't be able to access the driver directly.
+neverallow isolated_app gpu_device:chr_file { rw_file_perms execute };
+
+# Do not allow isolated_app access to /cache
+neverallow isolated_app cache_file:dir ~{ r_dir_perms };
+neverallow isolated_app cache_file:file ~{ read getattr };
diff --git a/sepolicy/kernel.te b/sepolicy/kernel.te
new file mode 100644
index 0000000..adab085
--- /dev/null
+++ b/sepolicy/kernel.te
@@ -0,0 +1,92 @@
+# Life begins with the kernel.
+type kernel, domain, domain_deprecated, mlstrustedsubject;
+
+allow kernel self:capability sys_nice;
+
+# Root fs.
+allow kernel rootfs:dir r_dir_perms;
+allow kernel rootfs:file r_file_perms;
+allow kernel rootfs:lnk_file r_file_perms;
+
+# Get SELinux enforcing status.
+allow kernel selinuxfs:dir r_dir_perms;
+allow kernel selinuxfs:file r_file_perms;
+
+# Allow init relabel itself.
+allow kernel rootfs:file relabelfrom;
+allow kernel init_exec:file relabelto;
+# TODO: investigate why we need this.
+allow kernel init:process share;
+
+# cgroup filesystem initialization prior to setting the cgroup root directory label.
+allow kernel unlabeled:dir search;
+
+# Mount usbfs.
+allow kernel usbfs:filesystem mount;
+allow kernel usbfs:dir search;
+
+# Initial setenforce by init prior to switching to init domain.
+# We use dontaudit instead of allow to prevent a kernel spawned userspace
+# process from turning off SELinux once enabled.
+dontaudit kernel self:security setenforce;
+
+# Write to /proc/1/oom_adj prior to switching to init domain.
+allow kernel self:capability sys_resource;
+
+# Init reboot before switching selinux domains under certain error
+# conditions. Allow it.
+# As part of rebooting, init writes "u" to /proc/sysrq-trigger to
+# remount filesystems read-only. /data is not mounted at this point,
+# so we could ignore this. For now, we allow it.
+allow kernel self:capability sys_boot;
+allow kernel proc_sysrq:file w_file_perms;
+
+# Allow writing to /dev/kmsg which was created prior to loading policy.
+allow kernel tmpfs:chr_file write;
+
+# Set checkreqprot by init.rc prior to switching to init domain.
+allow kernel selinuxfs:file write;
+allow kernel self:security setcheckreqprot;
+
+# MTP sync (b/15835289)
+# kernel thread "loop0", used by the loop block device, for ASECs (b/17158723)
+allow kernel priv_app:fd use;
+allow kernel sdcard_type:file { read write };
+
+# Allow the kernel to read OBB files from app directories. (b/17428116)
+# Kernel thread "loop0" reads a vold supplied file descriptor.
+# Fixes CTS tests:
+#  * android.os.storage.cts.StorageManagerTest#testMountAndUnmountObbNormal
+#  * android.os.storage.cts.StorageManagerTest#testMountAndUnmountTwoObbs
+allow kernel vold:fd use;
+allow kernel app_data_file:file read;
+allow kernel asec_image_file:file read;
+
+# Allow reading loop device in update_engine_unittests. (b/28319454)
+userdebug_or_eng(`
+  allow kernel update_engine_data_file:file read;
+  allow kernel nativetest_data_file:file read;
+')
+
+domain_auto_trans(kernel, init_exec, init)
+
+###
+### neverallow rules
+###
+
+# The initial task starts in the kernel domain (assigned via
+# initial_sid_contexts), but nothing ever transitions to it.
+neverallow * kernel:process { transition dyntransition };
+
+# The kernel domain is never entered via an exec, nor should it
+# ever execute a program outside the rootfs without changing to another domain.
+# If you encounter an execute_no_trans denial on the kernel domain, then
+# possible causes include:
+# - The program is a kernel usermodehelper.  In this case, define a domain
+#   for the program and domain_auto_trans() to it.
+# - You failed to setcon u:r:init:s0 in your init.rc and thus your init
+#   program was left in the kernel domain and is now trying to execute
+#   some other program.  Fix your init.rc file.
+# - You are running an exploit which switched to the init task credentials
+#   and is then trying to exec a shell or other program.  You lose!
+neverallow kernel { file_type fs_type -rootfs }:file { entrypoint execute_no_trans };
diff --git a/sepolicy/keys.conf b/sepolicy/keys.conf
new file mode 100644
index 0000000..7a307b5
--- /dev/null
+++ b/sepolicy/keys.conf
@@ -0,0 +1,25 @@
+#
+# Maps an arbitrary tag [TAGNAME] with the string contents found in
+# TARGET_BUILD_VARIANT. Common convention is to start TAGNAME with an @ and
+# name it after the base file name of the pem file.
+#
+# Each tag (section) then allows one to specify any string found in
+# TARGET_BUILD_VARIANT. Typcially this is user, eng, and userdebug. Another
+# option is to use ALL which will match ANY TARGET_BUILD_VARIANT string.
+#
+
+[@PLATFORM]
+ALL : $DEFAULT_SYSTEM_DEV_CERTIFICATE/platform.x509.pem
+
+[@MEDIA]
+ALL : $DEFAULT_SYSTEM_DEV_CERTIFICATE/media.x509.pem
+
+[@SHARED]
+ALL : $DEFAULT_SYSTEM_DEV_CERTIFICATE/shared.x509.pem
+
+# Example of ALL TARGET_BUILD_VARIANTS
+[@RELEASE]
+ENG       : $DEFAULT_SYSTEM_DEV_CERTIFICATE/testkey.x509.pem
+USER      : $DEFAULT_SYSTEM_DEV_CERTIFICATE/testkey.x509.pem
+USERDEBUG : $DEFAULT_SYSTEM_DEV_CERTIFICATE/testkey.x509.pem
+
diff --git a/sepolicy/keystore.te b/sepolicy/keystore.te
new file mode 100644
index 0000000..9dca43c
--- /dev/null
+++ b/sepolicy/keystore.te
@@ -0,0 +1,32 @@
+type keystore, domain, domain_deprecated;
+type keystore_exec, exec_type, file_type;
+
+# keystore daemon
+init_daemon_domain(keystore)
+typeattribute keystore mlstrustedsubject;
+binder_use(keystore)
+binder_service(keystore)
+allow keystore keystore_data_file:dir create_dir_perms;
+allow keystore keystore_data_file:notdevfile_class_set create_file_perms;
+allow keystore keystore_exec:file { getattr };
+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
+###
+### Protect ourself from others
+###
+
+neverallow { domain -keystore } keystore_data_file:dir ~{ open create read getattr setattr search relabelto ioctl };
+neverallow { domain -keystore } keystore_data_file:notdevfile_class_set ~{ relabelto getattr };
+
+neverallow { domain -keystore -init } keystore_data_file:dir *;
+neverallow { domain -keystore -init } keystore_data_file:notdevfile_class_set *;
+
+neverallow * keystore:process ptrace;
diff --git a/sepolicy/lmkd.te b/sepolicy/lmkd.te
new file mode 100644
index 0000000..ee731c5
--- /dev/null
+++ b/sepolicy/lmkd.te
@@ -0,0 +1,40 @@
+# lmkd low memory killer daemon
+type lmkd, domain, domain_deprecated, mlstrustedsubject;
+type lmkd_exec, exec_type, file_type;
+
+init_daemon_domain(lmkd)
+
+allow lmkd self:capability { dac_override sys_resource kill };
+
+# lmkd locks itself in memory, to prevent it from being
+# swapped out and unable to kill other memory hogs.
+# system/core commit b28ff9131363f7b4a698990da5748b2a88c3ed35
+# b/16236289
+allow lmkd self:capability ipc_lock;
+
+## Open and write to /proc/PID/oom_score_adj
+## TODO: maybe scope this down?
+r_dir_file(lmkd, appdomain)
+allow lmkd appdomain:file write;
+r_dir_file(lmkd, system_server)
+allow lmkd system_server:file write;
+
+## Writes to /sys/module/lowmemorykiller/parameters/minfree
+r_dir_file(lmkd, sysfs_type)
+allow lmkd sysfs_lowmemorykiller:file w_file_perms;
+
+# Send kill signals
+allow lmkd appdomain:process sigkill;
+
+# Clean up old cgroups
+allow lmkd cgroup:dir { remove_name rmdir };
+
+# Set self to SCHED_FIFO
+allow lmkd self:capability sys_nice;
+
+allow lmkd proc_zoneinfo:file r_file_perms;
+
+### neverallow rules
+
+# never honor LD_PRELOAD
+neverallow * lmkd:process noatsecure;
diff --git a/sepolicy/logd.te b/sepolicy/logd.te
new file mode 100644
index 0000000..8c68ae7
--- /dev/null
+++ b/sepolicy/logd.te
@@ -0,0 +1,66 @@
+# android user-space log manager
+type logd, domain, domain_deprecated, mlstrustedsubject;
+type logd_exec, exec_type, file_type;
+
+init_daemon_domain(logd)
+
+# Read access to pseudo filesystems.
+r_dir_file(logd, proc)
+r_dir_file(logd, proc_net)
+
+allow logd self:capability { setuid setgid setpcap sys_nice audit_control };
+allow logd self:capability2 syslog;
+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;
+# logpersist is only allowed on userdebug and eng builds
+userdebug_or_eng(`
+  allow logd misc_logd_file:file create_file_perms;
+  allow logd misc_logd_file:dir rw_dir_perms;
+')
+allow logd pstorefs:dir search;
+allow logd pstorefs:file r_file_perms;
+
+# Set persist.sys. and sys.powerctl
+set_prop(logd, safemode_prop)
+set_prop(logd, powerctl_prop)
+
+# Access device logging gating property
+get_prop(logd, device_logging_prop)
+userdebug_or_eng(`get_prop(logd, logpersistd_logging_prop)')
+
+r_dir_file(logd, domain)
+
+allow logd kernel:system syslog_mod;
+
+control_logd(logd)
+
+# case where logpersistd is actually logcat -f in logd context (nee: logcatd)
+userdebug_or_eng(`
+  unix_socket_connect(logd, logdr, logd)
+')
+
+###
+### Neverallow rules
+###
+### logd should NEVER do any of this
+
+# Block device access.
+neverallow logd dev_type:blk_file { read write };
+
+# ptrace any other app
+neverallow logd domain:process ptrace;
+
+# Write to /system.
+neverallow logd system_file:dir_file_class_set write;
+
+# Write to files in /data/data or system files on /data
+neverallow logd { app_data_file system_data_file }:dir_file_class_set write;
+
+# logd is not allowed to write anywhere other than /data/misc/logd
+neverallow logd { file_type -logd_tmpfs -misc_logd_file -coredump_file }:file { create write append };
+
+neverallow { domain -shell -dumpstate -logd -logrotate -su } misc_logd_file:file no_rw_file_perms;
+neverallow { domain -logd -logrotate -su } misc_logd_file:dir { add_name link relabelfrom remove_name rename reparent rmdir write };
+neverallow { domain -init } misc_logd_file:dir create;
diff --git a/sepolicy/mac_permissions.xml b/sepolicy/mac_permissions.xml
new file mode 100644
index 0000000..87efe0e
--- /dev/null
+++ b/sepolicy/mac_permissions.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="utf-8"?>
+<policy>
+
+<!--
+
+    * A signature is a hex encoded X.509 certificate or a tag defined in
+      keys.conf and is required for each signer tag. The signature can
+      either appear as a set of attached cert child tags or as an attribute.
+    * A signer tag must contain a seinfo tag XOR multiple package stanzas.
+    * Each signer/package tag is allowed to contain one seinfo tag. This tag
+      represents additional info that each app can use in setting a SELinux security
+      context on the eventual process as well as the apps data directory.
+    * seinfo assignments are made according to the following rules:
+      - Stanzas with package name refinements will be checked first.
+      - Stanzas w/o package name refinements will be checked second.
+      - The "default" seinfo label is automatically applied.
+
+    * valid stanzas can take one of the following forms:
+
+     // single cert protecting seinfo
+     <signer signature="@PLATFORM" >
+       <seinfo value="platform" />
+     </signer>
+
+     // multiple certs protecting seinfo (all contained certs must match)
+     <signer>
+       <cert signature="@PLATFORM1"/>
+       <cert signature="@PLATFORM2"/>
+       <seinfo value="platform" />
+     </signer>
+
+     // single cert protecting explicitly named app
+     <signer signature="@PLATFORM" >
+       <package name="com.android.foo">
+         <seinfo value="bar" />
+       </package>
+     </signer>
+
+     // multiple certs protecting explicitly named app (all certs must match)
+     <signer>
+       <cert signature="@PLATFORM1"/>
+       <cert signature="@PLATFORM2"/>
+       <package name="com.android.foo">
+         <seinfo value="bar" />
+       </package>
+     </signer>
+-->
+
+    <!-- Platform dev key in AOSP -->
+    <signer signature="@PLATFORM" >
+      <seinfo value="platform" />
+    </signer>
+
+</policy>
diff --git a/sepolicy/mdnsd.te b/sepolicy/mdnsd.te
new file mode 100644
index 0000000..a9dc7c5
--- /dev/null
+++ b/sepolicy/mdnsd.te
@@ -0,0 +1,9 @@
+# mdns daemon
+type mdnsd, domain, mlstrustedsubject;
+type mdnsd_exec, exec_type, file_type;
+
+init_daemon_domain(mdnsd)
+net_domain(mdnsd)
+
+# Read from /proc/net
+r_dir_file(mdnsd, proc_net)
diff --git a/sepolicy/mediaserver.te b/sepolicy/mediaserver.te
new file mode 100644
index 0000000..7e20002
--- /dev/null
+++ b/sepolicy/mediaserver.te
@@ -0,0 +1,124 @@
+# mediaserver - multimedia daemon
+type mediaserver, domain, domain_deprecated;
+type mediaserver_exec, exec_type, file_type;
+
+typeattribute mediaserver mlstrustedsubject;
+
+net_domain(mediaserver)
+init_daemon_domain(mediaserver)
+
+r_dir_file(mediaserver, sdcard_type)
+
+# stat /proc/self
+allow mediaserver proc:lnk_file getattr;
+
+# open /vendor/lib/mediadrm
+allow mediaserver system_file:dir r_dir_perms;
+
+binder_use(mediaserver)
+binder_call(mediaserver, binderservicedomain)
+binder_call(mediaserver, appdomain)
+binder_service(mediaserver)
+
+# Required by Widevine DRM (b/22990512)
+allow mediaserver self:process execmem;
+
+allow mediaserver kernel:system module_request;
+allow mediaserver media_data_file:dir create_dir_perms;
+allow mediaserver media_data_file:file create_file_perms;
+allow mediaserver app_data_file:dir search;
+allow mediaserver app_data_file:file rw_file_perms;
+allow mediaserver sdcard_type:file write;
+allow mediaserver gpu_device:chr_file rw_file_perms;
+allow mediaserver video_device:dir r_dir_perms;
+allow mediaserver video_device:chr_file rw_file_perms;
+allow mediaserver audio_device:dir r_dir_perms;
+allow mediaserver tee_device:chr_file rw_file_perms;
+
+set_prop(mediaserver, audio_prop)
+
+# Access audio devices at all.
+allow mediaserver audio_device:chr_file rw_file_perms;
+
+# XXX Label with a specific type?
+allow mediaserver sysfs:file r_file_perms;
+
+# Read resources from open apk files passed over Binder.
+allow mediaserver apk_data_file:file { read getattr };
+allow mediaserver asec_apk_file:file { read getattr };
+
+# Read /data/data/com.android.providers.telephony files passed over Binder.
+allow mediaserver radio_data_file:file { read getattr };
+
+# Use pipes passed over Binder from app domains.
+allow mediaserver appdomain:fifo_file { getattr read write };
+
+allow mediaserver rpmsg_device:chr_file rw_file_perms;
+
+# Inter System processes communicate over named pipe (FIFO)
+allow mediaserver system_server:fifo_file r_file_perms;
+
+# Camera data
+r_dir_file(mediaserver, camera_data_file)
+r_dir_file(mediaserver, media_rw_data_file)
+
+# Grant access to audio files to mediaserver
+allow mediaserver audio_data_file:dir ra_dir_perms;
+allow mediaserver audio_data_file:file create_file_perms;
+
+# Grant access to read files on appfuse.
+allow mediaserver app_fuse_file:file { read getattr };
+
+# Read/[write] to /proc/net/xt_qtaguid/ctrl and /dev/xt_qtaguid
+allow mediaserver qtaguid_proc:file rw_file_perms;
+allow mediaserver qtaguid_device:chr_file r_file_perms;
+
+# Allow abstract socket connection
+allow mediaserver rild:unix_stream_socket { connectto read write setopt };
+
+# Needed on some devices for playing DRM protected content,
+# but seems expected and appropriate for all devices.
+unix_socket_connect(mediaserver, drmserver, drmserver)
+
+# Needed on some devices for playing audio on paired BT device,
+# but seems appropriate for all devices.
+unix_socket_connect(mediaserver, bluetooth, bluetooth)
+
+# Connect to tee service.
+allow mediaserver tee:unix_stream_socket connectto;
+
+allow mediaserver activity_service:service_manager find;
+allow mediaserver appops_service:service_manager find;
+allow mediaserver cameraproxy_service:service_manager find;
+allow mediaserver batterystats_service:service_manager find;
+allow mediaserver drmserver_service:service_manager find;
+allow mediaserver mediaserver_service:service_manager { add find };
+allow mediaserver permission_service:service_manager find;
+allow mediaserver power_service:service_manager find;
+allow mediaserver processinfo_service:service_manager find;
+allow mediaserver scheduling_policy_service:service_manager find;
+allow mediaserver surfaceflinger_service:service_manager find;
+
+# /oem access
+allow mediaserver oemfs:dir search;
+allow mediaserver oemfs:file r_file_perms;
+
+use_drmservice(mediaserver)
+allow mediaserver drmserver:drmservice {
+    consumeRights
+    setPlaybackStatus
+    openDecryptSession
+    closeDecryptSession
+    initializeDecryptUnit
+    decrypt
+    finalizeDecryptUnit
+    pread
+};
+
+###
+### neverallow rules
+###
+
+# mediaserver should never execute any executable without a
+# domain transition
+neverallow mediaserver { file_type fs_type }:file execute_no_trans;
diff --git a/sepolicy/mls b/sepolicy/mls
new file mode 100644
index 0000000..5589b4b
--- /dev/null
+++ b/sepolicy/mls
@@ -0,0 +1,112 @@
+#########################################
+# MLS declarations
+#
+
+# Generate the desired number of sensitivities and categories.
+gen_sens(mls_num_sens)
+gen_cats(mls_num_cats)
+
+# Generate level definitions for each sensitivity and category.
+gen_levels(mls_num_sens,mls_num_cats)
+
+
+#################################################
+# MLS policy constraints
+#
+
+#
+# Process constraints
+#
+
+# Process transition:  Require equivalence unless the subject is trusted.
+mlsconstrain process { transition dyntransition }
+	     ((h1 eq h2 and l1 eq l2) or t1 == mlstrustedsubject);
+
+# Process read operations: No read up unless trusted.
+mlsconstrain process { getsched getsession getpgid getcap getattr ptrace share }
+	     (l1 dom l2 or t1 == mlstrustedsubject);
+
+# Process write operations:  Require equivalence unless trusted.
+mlsconstrain process { sigkill sigstop signal setsched setpgid setcap setrlimit ptrace share }
+	     (l1 eq l2 or t1 == mlstrustedsubject);
+
+#
+# Socket constraints
+#
+
+# Create/relabel operations:  Subject must be equivalent to object unless
+# the subject is trusted.  Sockets inherit the range of their creator.
+mlsconstrain socket_class_set { create relabelfrom relabelto }
+	     ((h1 eq h2 and l1 eq l2) or t1 == mlstrustedsubject);
+
+# Datagram send: Sender must be equivalent to the receiver unless one of them
+# is trusted.
+mlsconstrain unix_dgram_socket { sendto }
+	     (l1 eq l2 or t1 == mlstrustedsubject or t2 == mlstrustedsubject);
+
+# Stream connect:  Client must be equivalent to server unless one of them
+# is trusted.
+mlsconstrain unix_stream_socket { connectto }
+	     (l1 eq l2 or t1 == mlstrustedsubject or t2 == mlstrustedsubject);
+
+#
+# Directory/file constraints
+#
+
+# Create/relabel operations:  Subject must be equivalent to object unless
+# the subject is trusted. Also, files should always be single-level.
+# Do NOT exempt mlstrustedobject types from this constraint.
+mlsconstrain dir_file_class_set { create relabelfrom relabelto }
+	     (l2 eq h2 and (l1 eq l2 or t1 == mlstrustedsubject));
+
+#
+# Constraints for app data files only.
+#
+
+# Only constrain open, not read/write.
+# Also constrain other forms of manipulation, e.g. chmod/chown, unlink, rename, etc.
+# Subject must be equivalent to object unless the subject is trusted.
+mlsconstrain dir { open search setattr rename add_name remove_name reparent rmdir }
+	     (t2 != app_data_file or l1 eq l2 or t1 == mlstrustedsubject);
+mlsconstrain { file lnk_file sock_file } { open setattr unlink link rename }
+	     (t2 != app_data_file or l1 eq l2 or t1 == mlstrustedsubject);
+
+#
+# Constraints for file types other than app data files.
+#
+
+# Read operations: Subject must dominate object unless the subject
+# or the object is trusted.
+mlsconstrain dir { read getattr search }
+	     (t2 == app_data_file or l1 dom l2 or t1 == mlstrustedsubject or t2 == mlstrustedobject);
+
+mlsconstrain { file lnk_file sock_file chr_file blk_file } { read getattr execute }
+	     (t2 == app_data_file or l1 dom l2 or t1 == mlstrustedsubject or t2 == mlstrustedobject);
+
+# Write operations: Subject must be equivalent to the object unless the
+# subject or the object is trusted.
+mlsconstrain dir { write setattr rename add_name remove_name reparent rmdir }
+	     (t2 == app_data_file or l1 eq l2 or t1 == mlstrustedsubject or t2 == mlstrustedobject);
+
+mlsconstrain { file lnk_file sock_file chr_file blk_file } { write setattr append unlink link rename }
+	     (t2 == app_data_file or l1 eq l2 or t1 == mlstrustedsubject or t2 == mlstrustedobject);
+
+# Special case for FIFOs.
+# These can be unnamed pipes, in which case they will be labeled with the
+# creating process' label. Thus we also have an exemption when the "object"
+# is a domain type, so that processes can communicate via unnamed pipes
+# passed by binder or local socket IPC.
+mlsconstrain fifo_file { read getattr }
+	     (l1 dom l2 or t1 == mlstrustedsubject or t2 == mlstrustedobject or t2 == domain);
+
+mlsconstrain fifo_file { write setattr append unlink link rename }
+	     (l1 eq l2 or t1 == mlstrustedsubject or t2 == mlstrustedobject or t2 == domain);
+
+#
+# Binder IPC constraints
+#
+# Presently commented out, as apps are expected to call one another.
+# This would only make sense if apps were assigned categories
+# based on allowable communications rather than per-app categories.
+#mlsconstrain binder call
+#	(l1 eq l2 or t1 == mlstrustedsubject or t2 == mlstrustedsubject);
diff --git a/sepolicy/mls_macros b/sepolicy/mls_macros
new file mode 100644
index 0000000..83e0542
--- /dev/null
+++ b/sepolicy/mls_macros
@@ -0,0 +1,54 @@
+########################################
+#
+# gen_cats(N)
+#
+# declares categores c0 to c(N-1)
+#
+define(`decl_cats',`dnl
+category c$1;
+ifelse(`$1',`$2',,`decl_cats(incr($1),$2)')dnl
+')
+
+define(`gen_cats',`decl_cats(0,decr($1))')
+
+########################################
+#
+# gen_sens(N)
+#
+# declares sensitivites s0 to s(N-1) with dominance
+# in increasing numeric order with s0 lowest, s(N-1) highest
+#
+define(`decl_sens',`dnl
+sensitivity s$1;
+ifelse(`$1',`$2',,`decl_sens(incr($1),$2)')dnl
+')
+
+define(`gen_dominance',`s$1 ifelse(`$1',`$2',,`gen_dominance(incr($1),$2)')')
+
+define(`gen_sens',`
+# Each sensitivity has a name and zero or more aliases.
+decl_sens(0,decr($1))
+
+# Define the ordering of the sensitivity levels (least to greatest)
+dominance { gen_dominance(0,decr($1)) }
+')
+
+########################################
+#
+# gen_levels(N,M)
+#
+# levels from s0 to (N-1) with categories c0 to (M-1)
+#
+define(`decl_levels',`dnl
+level s$1:c0.c$3;
+ifelse(`$1',`$2',,`decl_levels(incr($1),$2,$3)')dnl
+')
+
+define(`gen_levels',`decl_levels(0,decr($1),decr($2))')
+
+########################################
+#
+# Basic level names for system low and high
+#
+define(`mls_systemlow',`s0')
+define(`mls_systemhigh',`s`'decr(mls_num_sens):c0.c`'decr(mls_num_cats)')
diff --git a/sepolicy/mtp.te b/sepolicy/mtp.te
new file mode 100644
index 0000000..9677abd
--- /dev/null
+++ b/sepolicy/mtp.te
@@ -0,0 +1,12 @@
+# vpn tunneling protocol manager
+type mtp, domain, domain_deprecated;
+type mtp_exec, exec_type, file_type;
+
+init_daemon_domain(mtp)
+net_domain(mtp)
+
+# pptp policy
+allow mtp self:socket create_socket_perms;
+allow mtp self:capability net_raw;
+allow mtp ppp:process signal;
+allow mtp vpn_data_file:dir search;
diff --git a/sepolicy/net.te b/sepolicy/net.te
new file mode 100644
index 0000000..6aa12f2
--- /dev/null
+++ b/sepolicy/net.te
@@ -0,0 +1,25 @@
+# Network types
+type node, node_type;
+type netif, netif_type;
+type port, port_type;
+
+# Use network sockets.
+allow netdomain self:tcp_socket create_stream_socket_perms;
+allow netdomain self:{ udp_socket rawip_socket } create_socket_perms;
+# Connect to ports.
+allow netdomain port_type:tcp_socket name_connect;
+# Bind to ports.
+allow netdomain node_type:{ tcp_socket udp_socket } node_bind;
+allow netdomain port_type:udp_socket name_bind;
+allow netdomain port_type:tcp_socket name_bind;
+# See changes to the routing table.
+allow netdomain self:netlink_route_socket { create_socket_perms nlmsg_read };
+
+# Talks to netd via dnsproxyd socket.
+unix_socket_connect(netdomain, dnsproxyd, netd)
+
+# Talks to netd via fwmarkd socket.
+unix_socket_connect(netdomain, fwmarkd, netd)
+
+# Connect to mdnsd via mdnsd socket.
+unix_socket_connect(netdomain, mdnsd, mdnsd)
diff --git a/sepolicy/netd.te b/sepolicy/netd.te
new file mode 100644
index 0000000..d6c715c
--- /dev/null
+++ b/sepolicy/netd.te
@@ -0,0 +1,88 @@
+# network manager
+type netd, domain, domain_deprecated, mlstrustedsubject;
+type netd_exec, exec_type, file_type;
+
+init_daemon_domain(netd)
+net_domain(netd)
+
+allow netd self:capability { net_admin net_raw kill };
+# Note: fsetid is deliberately not included above. fsetid checks are
+# triggered by chmod on a directory or file owned by a group other
+# than one of the groups assigned to the current process to see if
+# the setgid bit should be cleared, regardless of whether the setgid
+# bit was even set.  We do not appear to truly need this capability
+# for netd to operate.
+dontaudit netd self:capability fsetid;
+
+allow netd self:netlink_kobject_uevent_socket create_socket_perms;
+allow netd self:netlink_route_socket nlmsg_write;
+allow netd self:netlink_nflog_socket create_socket_perms;
+allow netd self:netlink_socket create_socket_perms;
+allow netd self:netlink_tcpdiag_socket { create_socket_perms nlmsg_read nlmsg_write };
+allow netd self:netlink_generic_socket create_socket_perms;
+allow netd self:netlink_netfilter_socket create_socket_perms;
+allow netd shell_exec:file rx_file_perms;
+allow netd system_file:file x_file_perms;
+allow netd devpts:chr_file rw_file_perms;
+
+# For /proc/sys/net/ipv[46]/route/flush.
+allow netd proc_net:file write;
+
+# For /sys/modules/bcmdhd/parameters/firmware_path
+# XXX Split into its own type.
+allow netd sysfs:file write;
+
+# Set dhcp lease for PAN connection
+set_prop(netd, dhcp_prop)
+set_prop(netd, system_prop)
+auditallow netd system_prop:property_service set;
+
+# Connect to PAN
+domain_auto_trans(netd, dhcp_exec, dhcp)
+allow netd dhcp:process signal;
+
+# Needed to update /data/misc/wifi/hostapd.conf
+# TODO: See what we can do to reduce the need for
+# these capabilities
+allow netd self:capability { dac_override chown fowner };
+allow netd wifi_data_file:file create_file_perms;
+allow netd wifi_data_file:dir rw_dir_perms;
+
+# Needed to update /data/misc/net/rt_tables
+allow netd net_data_file:file create_file_perms;
+allow netd net_data_file:dir rw_dir_perms;
+
+# Allow netd to spawn hostapd in it's own domain
+domain_auto_trans(netd, hostapd_exec, hostapd)
+allow netd hostapd:process signal;
+
+# Allow netd to spawn dnsmasq in it's own domain
+domain_auto_trans(netd, dnsmasq_exec, dnsmasq)
+allow netd dnsmasq:process signal;
+
+# Allow netd to start clatd in its own domain
+domain_auto_trans(netd, clatd_exec, clatd)
+allow netd clatd:process signal;
+
+set_prop(netd, ctl_mdnsd_prop)
+
+# Allow netd to operate on sockets that are passed to it.
+allow netd netdomain:{tcp_socket udp_socket rawip_socket dccp_socket tun_socket} {read write getattr setattr getopt setopt};
+allow netd netdomain:fd use;
+
+###
+### Neverallow rules
+###
+### netd should NEVER do any of this
+
+# Block device access.
+neverallow netd dev_type:blk_file { read write };
+
+# ptrace any other app
+neverallow netd { domain }:process ptrace;
+
+# Write to /system.
+neverallow netd system_file:dir_file_class_set write;
+
+# Write to files in /data/data or system files on /data
+neverallow netd { app_data_file system_data_file }:dir_file_class_set write;
diff --git a/sepolicy/neverallow_macros b/sepolicy/neverallow_macros
new file mode 100644
index 0000000..b36cceb
--- /dev/null
+++ b/sepolicy/neverallow_macros
@@ -0,0 +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/sepolicy/nfc.te b/sepolicy/nfc.te
new file mode 100644
index 0000000..85572e2
--- /dev/null
+++ b/sepolicy/nfc.te
@@ -0,0 +1,31 @@
+# nfc subsystem
+type nfc, domain, domain_deprecated;
+app_domain(nfc)
+net_domain(nfc)
+binder_service(nfc)
+
+# Set NFC properties
+set_prop(nfc, nfc_prop)
+
+# NFC device access.
+allow nfc nfc_device:chr_file rw_file_perms;
+
+# Data file accesses.
+allow nfc nfc_data_file:dir create_dir_perms;
+allow nfc nfc_data_file:notdevfile_class_set create_file_perms;
+
+allow nfc sysfs_nfc_power_writable:file rw_file_perms;
+allow nfc sysfs:file write;
+
+allow nfc drmserver_service:service_manager find;
+allow nfc mediaserver_service:service_manager find;
+allow nfc nfc_service:service_manager { add find };
+allow nfc radio_service:service_manager find;
+allow nfc surfaceflinger_service:service_manager find;
+allow nfc app_api_service:service_manager find;
+allow nfc system_api_service:service_manager find;
+
+# already open bugreport file descriptors may be shared with
+# the nfc process, from a file in
+# /data/data/com.android.shell/files/bugreports/bugreport-*.
+allow nfc shell_data_file:file read;
diff --git a/sepolicy/perfprofd.te b/sepolicy/perfprofd.te
new file mode 100644
index 0000000..0122c55
--- /dev/null
+++ b/sepolicy/perfprofd.te
@@ -0,0 +1,59 @@
+# perfprofd - perf profile collection daemon
+type perfprofd_exec, exec_type, file_type;
+
+userdebug_or_eng(`
+
+  type perfprofd, domain, domain_deprecated, mlstrustedsubject;
+
+  init_daemon_domain(perfprofd)
+
+  # perfprofd needs to control CPU hot-plug in order to avoid kernel
+  # perfevents problems in cases where CPU goes on/off during measurement;
+  # this means read access to /sys/devices/system/cpu/possible
+  # and read/write access to /sys/devices/system/cpu/cpu*/online
+  allow perfprofd sysfs_devices_system_cpu:file rw_file_perms;
+
+  # perfprofd checks for the existence of and then invokes simpleperf;
+  # simpleperf retains perfprofd domain after exec
+  allow perfprofd system_file:file rx_file_perms;
+
+  # perfprofd reads a config file from /data/data/com.google.android.gms/files
+  allow perfprofd app_data_file:file r_file_perms;
+  allow perfprofd app_data_file:dir search;
+  allow perfprofd self:capability { dac_override };
+
+  # perfprofd opens a file for writing in /data/misc/perfprofd
+  allow perfprofd perfprofd_data_file:file create_file_perms;
+  allow perfprofd perfprofd_data_file:dir rw_dir_perms;
+
+  # perfprofd uses the system log
+  read_logd(perfprofd);
+  write_logd(perfprofd);
+
+  # perfprofd inspects /sys/power/wake_unlock
+  wakelock_use(perfprofd);
+
+  # simpleperf uses ioctl() to turn on kernel perf events measurements
+  allow perfprofd self:capability sys_admin;
+
+  # simpleperf needs to examine /proc to collect task/thread info
+  r_dir_file(perfprofd, domain)
+
+  # simpleperf needs to access /proc/<pid>/exec
+  allow perfprofd self:capability { sys_resource sys_ptrace };
+  neverallow perfprofd domain:process ptrace;
+
+  # simpleperf needs open/read any file that turns up in a profile
+  # to see whether it has a build ID
+  allow perfprofd exec_type:file r_file_perms;
+
+  # simpleperf examines debugfs on startup to collect tracepoint event types
+  allow perfprofd debugfs_tracing:file r_file_perms;
+
+  # simpleperf is going to execute "sleep"
+  allow perfprofd toolbox_exec:file rx_file_perms;
+
+  # needed for simpleperf on some kernels
+  allow perfprofd self:capability ipc_lock;
+
+')
diff --git a/sepolicy/platform_app.te b/sepolicy/platform_app.te
new file mode 100644
index 0000000..0381288
--- /dev/null
+++ b/sepolicy/platform_app.te
@@ -0,0 +1,47 @@
+###
+### Apps signed with the platform key.
+###
+
+type platform_app, domain, domain_deprecated;
+app_domain(platform_app)
+# Access the network.
+net_domain(platform_app)
+# Access bluetooth.
+bluetooth_domain(platform_app)
+# Read from /data/local/tmp or /data/data/com.android.shell.
+allow platform_app shell_data_file:dir search;
+allow platform_app shell_data_file:file { open getattr read };
+# Populate /data/app/vmdl*.tmp, /data/app-private/vmdl*.tmp files
+# created by system server.
+allow platform_app { apk_tmp_file apk_private_tmp_file }:dir rw_dir_perms;
+allow platform_app { apk_tmp_file apk_private_tmp_file }:file rw_file_perms;
+allow platform_app apk_private_data_file:dir search;
+# ASEC
+allow platform_app asec_apk_file:dir create_dir_perms;
+allow platform_app asec_apk_file:file create_file_perms;
+
+# Access to /data/media.
+allow platform_app media_rw_data_file:dir create_dir_perms;
+allow platform_app media_rw_data_file:file create_file_perms;
+
+# Write to /cache.
+allow platform_app { cache_file cache_recovery_file }:dir create_dir_perms;
+allow platform_app { cache_file cache_recovery_file }:file create_file_perms;
+
+# Likely not needed
+auditallow platform_app cache_recovery_file:dir create_dir_perms;
+auditallow platform_app cache_recovery_file:file create_file_perms;
+
+# Direct access to vold-mounted storage under /mnt/media_rw
+# This is a performance optimization that allows platform apps to bypass the FUSE layer
+allow platform_app mnt_media_rw_file:dir r_dir_perms;
+allow platform_app vfat:dir create_dir_perms;
+allow platform_app vfat:file create_file_perms;
+
+allow platform_app drmserver_service:service_manager find;
+allow platform_app mediaserver_service:service_manager find;
+allow platform_app persistent_data_block_service:service_manager find;
+allow platform_app radio_service:service_manager find;
+allow platform_app surfaceflinger_service:service_manager find;
+allow platform_app app_api_service:service_manager find;
+allow platform_app system_api_service:service_manager find;
diff --git a/sepolicy/policy_capabilities b/sepolicy/policy_capabilities
new file mode 100644
index 0000000..c7b9d9c
--- /dev/null
+++ b/sepolicy/policy_capabilities
@@ -0,0 +1,5 @@
+# Enable new networking controls.
+policycap network_peer_controls;
+
+# Enable open permission check.
+policycap open_perms;
diff --git a/sepolicy/port_contexts b/sepolicy/port_contexts
new file mode 100644
index 0000000..b473c0c
--- /dev/null
+++ b/sepolicy/port_contexts
@@ -0,0 +1,3 @@
+# portcon statements go here, e.g.
+# portcon tcp 80 u:object_r:http_port:s0
+
diff --git a/sepolicy/postinstall.te b/sepolicy/postinstall.te
new file mode 100644
index 0000000..dd89886
--- /dev/null
+++ b/sepolicy/postinstall.te
@@ -0,0 +1,25 @@
+# Domain where the postinstall program runs during the update.
+# Extend the permissions in this domain to allow this program to access other
+# files needed by the specific device on your device's sepolicy directory.
+type postinstall, domain;
+
+# Allow postinstall to write to its stdout/stderr when redirected via pipes to
+# update_engine.
+allow postinstall update_engine_common:fd use;
+allow postinstall update_engine_common:fifo_file rw_file_perms;
+
+# Allow postinstall to read and execute directories and files in the same
+# mounted location.
+allow postinstall postinstall_file:file rx_file_perms;
+allow postinstall postinstall_file:lnk_file r_file_perms;
+allow postinstall postinstall_file:dir r_dir_perms;
+
+# Allow postinstall to execute the shell or other system executables.
+allow postinstall shell_exec:file rx_file_perms;
+allow postinstall system_file:file rx_file_perms;
+allow postinstall toolbox_exec:file rx_file_perms;
+
+# No domain other than update_engine and recovery (via update_engine_sideload)
+# should transition to postinstall, as it is only meant to run during the
+# update.
+neverallow { domain -update_engine -recovery } postinstall:process { transition dyntransition };
diff --git a/sepolicy/ppp.te b/sepolicy/ppp.te
new file mode 100644
index 0000000..d7ed70d
--- /dev/null
+++ b/sepolicy/ppp.te
@@ -0,0 +1,16 @@
+# Point to Point Protocol daemon
+type ppp, domain, domain_deprecated;
+type ppp_device, dev_type;
+type ppp_exec, exec_type, file_type;
+domain_auto_trans(mtp, ppp_exec, ppp)
+
+net_domain(ppp)
+
+allow ppp mtp:socket rw_socket_perms;
+allow ppp mtp:unix_dgram_socket rw_socket_perms;
+allow ppp ppp_device:chr_file rw_file_perms;
+allow ppp self:capability net_admin;
+allow ppp system_file:file rx_file_perms;
+allow ppp vpn_data_file:dir w_dir_perms;
+allow ppp vpn_data_file:file create_file_perms;
+allow ppp mtp:fd use;
diff --git a/sepolicy/priv_app.te b/sepolicy/priv_app.te
new file mode 100644
index 0000000..9146263
--- /dev/null
+++ b/sepolicy/priv_app.te
@@ -0,0 +1,123 @@
+###
+### A domain for further sandboxing privileged apps.
+###
+type priv_app, domain, domain_deprecated;
+app_domain(priv_app)
+# Access the network.
+net_domain(priv_app)
+# Access bluetooth.
+bluetooth_domain(priv_app)
+
+# Some apps ship with shared libraries and binaries that they write out
+# to their sandbox directory and then execute.
+allow priv_app app_data_file:file rx_file_perms;
+
+# android.process.media uses /dev/mtp_usb
+allow priv_app mtp_device:chr_file rw_file_perms;
+
+# Allow the allocation and use of ptys
+# Used by: https://play.privileged.com/store/apps/details?id=jackpal.androidterm
+create_pty(priv_app)
+
+allow priv_app drmserver_service:service_manager find;
+allow priv_app mediaserver_service:service_manager find;
+allow priv_app nfc_service:service_manager find;
+allow priv_app radio_service:service_manager find;
+allow priv_app surfaceflinger_service:service_manager find;
+allow priv_app app_api_service:service_manager find;
+allow priv_app system_api_service:service_manager find;
+allow priv_app persistent_data_block_service:service_manager find;
+allow priv_app recovery_service:service_manager find;
+
+# Traverse into /mnt/media_rw for bypassing FUSE daemon
+# TODO: narrow this to just MediaProvider
+allow priv_app mnt_media_rw_file:dir search;
+
+# Write to /cache.
+allow priv_app { cache_file cache_recovery_file }:dir create_dir_perms;
+allow priv_app { cache_file cache_recovery_file }:file create_file_perms;
+
+# Access to /data/media.
+allow priv_app media_rw_data_file:dir create_dir_perms;
+allow priv_app media_rw_data_file:file create_file_perms;
+
+# Used by Finsky / Android "Verify Apps" functionality when
+# running "adb install foo.apk".
+allow priv_app shell_data_file:file r_file_perms;
+allow priv_app shell_data_file:dir r_dir_perms;
+
+# Allow verifier to access staged apks.
+allow priv_app { apk_tmp_file apk_private_tmp_file }:dir r_dir_perms;
+allow priv_app { apk_tmp_file apk_private_tmp_file }:file r_file_perms;
+
+# b/18504118: Allow reads from /data/anr/traces.txt
+allow priv_app anr_data_file:file r_file_perms;
+
+# Allow GMS core to access perfprofd output, which is stored
+# in /data/misc/perfprofd/. GMS core will need to list all
+# data stored in that directory to process them one by one.
+userdebug_or_eng(`
+  allow priv_app perfprofd_data_file:file r_file_perms;
+  allow priv_app perfprofd_data_file:dir r_dir_perms;
+')
+
+# Allow GMS core to stat files and executables on
+# the system partition
+allow priv_app exec_type:file getattr;
+
+# For AppFuse.
+allow priv_app vold:fd use;
+allow priv_app fuse_device:chr_file { read write };
+allow priv_app app_fuse_file:dir rw_dir_perms;
+allow priv_app app_fuse_file:file rw_file_perms;
+
+# /sys access
+allow priv_app sysfs_zram:dir search;
+allow priv_app sysfs_zram:file r_file_perms;
+
+# Allow GMS core to communicate with update_engine for A/B update.
+binder_call(priv_app, update_engine)
+allow priv_app update_engine_service:service_manager find;
+
+###
+### neverallow rules
+###
+
+# Receive or send uevent messages.
+neverallow priv_app domain:netlink_kobject_uevent_socket *;
+
+# Receive or send generic netlink messages
+neverallow priv_app domain:netlink_socket *;
+
+# Too much leaky information in debugfs. It's a security
+# best practice to ensure these files aren't readable.
+neverallow priv_app debugfs:file read;
+
+# Do not allow privileged apps to register services.
+# Only trusted components of Android should be registering
+# services.
+neverallow priv_app service_manager_type:service_manager add;
+
+# Do not allow privileged apps to connect to the property service
+# or set properties. b/10243159
+neverallow priv_app property_socket:sock_file write;
+neverallow priv_app init:unix_stream_socket connectto;
+neverallow priv_app property_type:property_service set;
+
+# Do not allow priv_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 priv_app is allowed fork permission to itself.
+neverallow priv_app mlstrustedsubject:process fork;
+
+# Do not allow priv_app to hard link to any files.
+# In particular, if priv_app links to other app data
+# files, installd will not be able to guarantee the deletion
+# of the linked to file. Hard links also contribute to security
+# bugs, so we want to ensure priv_app never has this
+# capability.
+neverallow priv_app file_type:file link;
diff --git a/sepolicy/property.te b/sepolicy/property.te
new file mode 100644
index 0000000..6d3ba4f
--- /dev/null
+++ b/sepolicy/property.te
@@ -0,0 +1,39 @@
+type default_prop, property_type, core_property_type;
+type shell_prop, property_type, core_property_type;
+type debug_prop, property_type, core_property_type;
+type dumpstate_prop, property_type, core_property_type;
+type persist_debug_prop, property_type, core_property_type;
+type debuggerd_prop, property_type, core_property_type;
+type dhcp_prop, property_type, core_property_type;
+type fingerprint_prop, property_type, core_property_type;
+type ffs_prop, property_type, core_property_type;
+type radio_prop, property_type, core_property_type;
+type net_radio_prop, property_type, core_property_type;
+type system_radio_prop, property_type, core_property_type;
+type system_prop, property_type, core_property_type;
+type vold_prop, property_type, core_property_type;
+type ctl_bootanim_prop, property_type;
+type ctl_default_prop, property_type;
+type ctl_dhcp_pan_prop, property_type;
+type ctl_dumpstate_prop, property_type;
+type ctl_fuse_prop, property_type;
+type ctl_mdnsd_prop, property_type;
+type ctl_rildaemon_prop, property_type;
+type ctl_bugreport_prop, property_type;
+type ctl_console_prop, property_type;
+type audio_prop, property_type, core_property_type;
+type logd_prop, property_type, core_property_type;
+type logpersistd_logging_prop, property_type;
+type mmc_prop, property_type;
+type restorecon_prop, property_type, core_property_type;
+type security_prop, property_type, core_property_type;
+type bluetooth_prop, property_type, core_property_type;
+type pan_result_prop, property_type, core_property_type;
+type powerctl_prop, property_type, core_property_type;
+type nfc_prop, property_type, core_property_type;
+type dalvik_prop, property_type, core_property_type;
+type config_prop, property_type, core_property_type;
+type device_logging_prop, property_type;
+type safemode_prop, property_type;
+
+allow property_type tmpfs:filesystem associate;
diff --git a/sepolicy/property_contexts b/sepolicy/property_contexts
new file mode 100644
index 0000000..bbfea8a
--- /dev/null
+++ b/sepolicy/property_contexts
@@ -0,0 +1,95 @@
+##########################
+# property service keys
+#
+#
+net.rmnet               u:object_r:net_radio_prop:s0
+net.gprs                u:object_r:net_radio_prop:s0
+net.ppp                 u:object_r:net_radio_prop:s0
+net.qmi                 u:object_r:net_radio_prop:s0
+net.lte                 u:object_r:net_radio_prop:s0
+net.cdma                u:object_r:net_radio_prop:s0
+net.dns                 u:object_r:net_radio_prop:s0
+sys.usb.config          u:object_r:system_radio_prop:s0
+ril.                    u:object_r:radio_prop:s0
+ro.ril.                 u:object_r:radio_prop:s0
+gsm.                    u:object_r:radio_prop:s0
+persist.radio           u:object_r:radio_prop:s0
+
+net.                    u:object_r:system_prop:s0
+dev.                    u:object_r:system_prop:s0
+ro.runtime.             u:object_r:system_prop:s0
+hw.                     u:object_r:system_prop:s0
+ro.hw.                  u:object_r:system_prop:s0
+sys.                    u:object_r:system_prop:s0
+sys.powerctl            u:object_r:powerctl_prop:s0
+sys.usb.ffs.            u:object_r:ffs_prop:s0
+service.                u:object_r:system_prop:s0
+wlan.                   u:object_r:system_prop:s0
+dhcp.                   u:object_r:dhcp_prop:s0
+dhcp.bt-pan.result      u:object_r:pan_result_prop:s0
+bluetooth.              u:object_r:bluetooth_prop:s0
+
+debug.                  u:object_r:debug_prop:s0
+debug.db.               u:object_r:debuggerd_prop:s0
+dumpstate.              u:object_r:dumpstate_prop:s0
+log.                    u:object_r:shell_prop:s0
+security.perf_harden    u:object_r:shell_prop:s0
+service.adb.root        u:object_r:shell_prop:s0
+service.adb.tcp.port    u:object_r:shell_prop:s0
+
+persist.audio.          u:object_r:audio_prop:s0
+persist.bluetooth.      u:object_r:bluetooth_prop:s0
+persist.debug.          u:object_r:persist_debug_prop:s0
+persist.logd.           u:object_r:logd_prop:s0
+persist.logd.security   u:object_r:device_logging_prop:s0
+persist.logd.logpersistd        u:object_r:logpersistd_logging_prop:s0
+logd.logpersistd        u:object_r:logpersistd_logging_prop:s0
+persist.log.tag         u:object_r:logd_prop:s0
+persist.mmc.            u:object_r:mmc_prop:s0
+persist.sys.            u:object_r:system_prop:s0
+persist.sys.safemode    u:object_r:safemode_prop:s0
+persist.sys.audit_safemode      u:object_r:safemode_prop:s0
+persist.service.        u:object_r:system_prop:s0
+persist.service.bdroid. u:object_r:bluetooth_prop:s0
+persist.security.       u:object_r:system_prop:s0
+
+# Boolean property set by system server upon boot indicating
+# if device owner is provisioned.
+ro.device_owner         u:object_r:device_logging_prop:s0
+
+# selinux non-persistent properties
+selinux.restorecon_recursive   u:object_r:restorecon_prop:s0
+selinux.                       u:object_r:security_prop:s0
+
+# default property context
+*                       u:object_r:default_prop:s0
+
+# data partition encryption properties
+vold.                   u:object_r:vold_prop:s0
+ro.crypto.              u:object_r:vold_prop:s0
+
+# ro.build.fingerprint is either set in /system/build.prop, or is
+# set at runtime by system_server.
+ro.build.fingerprint    u:object_r:fingerprint_prop:s0
+
+# ctl properties
+ctl.bootanim            u:object_r:ctl_bootanim_prop:s0
+ctl.dumpstate           u:object_r:ctl_dumpstate_prop:s0
+ctl.fuse_               u:object_r:ctl_fuse_prop:s0
+ctl.mdnsd               u:object_r:ctl_mdnsd_prop:s0
+ctl.ril-daemon          u:object_r:ctl_rildaemon_prop:s0
+ctl.bugreport           u:object_r:ctl_bugreport_prop:s0
+ctl.dhcpcd_bt-pan       u:object_r:ctl_dhcp_pan_prop:s0
+ctl.console             u:object_r:ctl_console_prop:s0
+ctl.                    u:object_r:ctl_default_prop:s0
+
+# NFC properties
+nfc.                    u:object_r:nfc_prop:s0
+
+# These properties are not normally set by processes other than init.
+# They are only distinguished here for setting by qemu-props on the
+# emulator/goldfish.
+config.                 u:object_r:config_prop:s0
+ro.config.              u:object_r:config_prop:s0
+dalvik.                 u:object_r:dalvik_prop:s0
+ro.dalvik.              u:object_r:dalvik_prop:s0
diff --git a/sepolicy/racoon.te b/sepolicy/racoon.te
new file mode 100644
index 0000000..bf272d1
--- /dev/null
+++ b/sepolicy/racoon.te
@@ -0,0 +1,32 @@
+# IKE key management daemon
+type racoon, domain, domain_deprecated;
+type racoon_exec, exec_type, file_type;
+
+init_daemon_domain(racoon)
+typeattribute racoon mlstrustedsubject;
+
+net_domain(racoon)
+
+binder_use(racoon)
+
+allow racoon tun_device:chr_file r_file_perms;
+allow racoon cgroup:dir { add_name create };
+allow racoon kernel:system module_request;
+
+allow racoon self:key_socket create_socket_perms;
+allow racoon self:tun_socket create_socket_perms;
+allow racoon self:capability { net_admin net_bind_service net_raw setuid };
+
+# XXX: should we give ip-up-vpn its own label (currently racoon domain)
+allow racoon system_file:file rx_file_perms;
+allow racoon vpn_data_file:file create_file_perms;
+allow racoon vpn_data_file:dir w_dir_perms;
+
+use_keystore(racoon)
+
+# Racoon (VPN) has a restricted set of permissions from the default.
+allow racoon keystore:keystore_key {
+	get
+	sign
+	verify
+};
diff --git a/sepolicy/radio.te b/sepolicy/radio.te
new file mode 100644
index 0000000..448fdb5
--- /dev/null
+++ b/sepolicy/radio.te
@@ -0,0 +1,35 @@
+# phone subsystem
+type radio, domain, domain_deprecated, mlstrustedsubject;
+app_domain(radio)
+net_domain(radio)
+bluetooth_domain(radio)
+binder_service(radio)
+
+# Talks to rild via the rild socket.
+unix_socket_connect(radio, rild, rild)
+
+# Data file accesses.
+allow radio radio_data_file:dir create_dir_perms;
+allow radio radio_data_file:notdevfile_class_set create_file_perms;
+
+allow radio alarm_device:chr_file rw_file_perms;
+
+allow radio net_data_file:dir search;
+allow radio net_data_file:file r_file_perms;
+
+# Property service
+set_prop(radio, radio_prop)
+set_prop(radio, system_radio_prop)
+set_prop(radio, net_radio_prop)
+auditallow radio net_radio_prop:property_service set;
+auditallow radio system_radio_prop:property_service set;
+
+# ctl interface
+set_prop(radio, ctl_rildaemon_prop)
+
+allow radio drmserver_service:service_manager find;
+allow radio mediaserver_service:service_manager find;
+allow radio radio_service:service_manager { add find };
+allow radio surfaceflinger_service:service_manager find;
+allow radio app_api_service:service_manager find;
+allow radio system_api_service:service_manager find;
diff --git a/sepolicy/recovery.te b/sepolicy/recovery.te
new file mode 100644
index 0000000..209a276
--- /dev/null
+++ b/sepolicy/recovery.te
@@ -0,0 +1,124 @@
+# recovery console (used in recovery init.rc for /sbin/recovery)
+
+# Declare the domain unconditionally so we can always reference it
+# in neverallow rules.
+type recovery, domain, domain_deprecated;
+
+# But the allow rules are only included in the recovery policy.
+# Otherwise recovery is only allowed the domain rules.
+recovery_only(`
+  # Allow recovery to perform an update as update_engine would do.
+  typeattribute recovery update_engine_common, boot_control_hal;
+
+  allow recovery self:capability { chown dac_override fowner fsetid setfcap setuid setgid sys_admin sys_tty_config };
+
+  # Set security contexts on files that are not known to the loaded policy.
+  allow recovery self:capability2 mac_admin;
+
+  # Run helpers from / or /system without changing domain.
+  allow recovery rootfs:file execute_no_trans;
+  allow recovery system_file:file execute_no_trans;
+  allow recovery toolbox_exec:file rx_file_perms;
+
+  # Mount filesystems.
+  allow recovery rootfs:dir mounton;
+  allow recovery fs_type:filesystem ~relabelto;
+  allow recovery unlabeled:filesystem ~relabelto;
+  allow recovery contextmount_type:filesystem relabelto;
+
+  # Create and relabel files and directories under /system.
+  allow recovery exec_type:{ file lnk_file } { create_file_perms relabelfrom relabelto };
+  allow recovery system_file:{ file lnk_file } { create_file_perms relabelfrom relabelto };
+  allow recovery system_file:dir { create_dir_perms relabelfrom relabelto };
+
+  # We may be asked to set an SELinux label for a type not known to the
+  # currently loaded policy. Allow it.
+  allow recovery unlabeled:{ file lnk_file } { create_file_perms relabelfrom relabelto };
+  allow recovery unlabeled:dir { create_dir_perms relabelfrom relabelto };
+
+  # 0eb17d944704b3eb140bb9dded299d3be3aed77e in build/ added SELinux
+  # support to OTAs. However, that code has a bug. When an update occurs,
+  # some directories are inappropriately labeled as exec_type. This is
+  # only transient, and subsequent steps in the OTA script correct this
+  # mistake. New devices are moving to block based OTAs, so this is not
+  # worth fixing. b/15575013
+  allow recovery exec_type:dir { create_dir_perms relabelfrom relabelto };
+
+  # Write to /proc/sys/vm/drop_caches
+  allow recovery proc_drop_caches:file w_file_perms;
+
+  # Write to /sys/class/android_usb/android0/enable.
+  # TODO: create more specific label?
+  allow recovery sysfs:file w_file_perms;
+
+  allow recovery sysfs_batteryinfo:file r_file_perms;
+
+  allow recovery kernel:system syslog_read;
+
+  # Access /dev/android_adb or /dev/usb-ffs/adb/ep0
+  allow recovery adb_device:chr_file rw_file_perms;
+  allow recovery functionfs:dir search;
+  allow recovery functionfs:file rw_file_perms;
+
+  # Required to e.g. wipe userdata/cache.
+  allow recovery device:dir r_dir_perms;
+  allow recovery block_device:dir r_dir_perms;
+  allow recovery dev_type:blk_file rw_file_perms;
+
+  # GUI
+  allow recovery self:process execmem;
+  allow recovery ashmem_device:chr_file execute;
+  allow recovery graphics_device:chr_file rw_file_perms;
+  allow recovery graphics_device:dir r_dir_perms;
+  allow recovery input_device:dir r_dir_perms;
+  allow recovery input_device:chr_file r_file_perms;
+  allow recovery tty_device:chr_file rw_file_perms;
+
+  # Create /tmp/recovery.log and execute /tmp/update_binary.
+  allow recovery tmpfs:file { create_file_perms x_file_perms };
+  allow recovery tmpfs:dir create_dir_perms;
+
+  # Manage files on /cache and /cache/recovery
+  allow recovery { cache_file cache_recovery_file }:dir create_dir_perms;
+  allow recovery { cache_file cache_recovery_file }:file create_file_perms;
+
+  # Read files on /oem.
+  r_dir_file(recovery, oemfs);
+
+  # Reboot the device
+  set_prop(recovery, powerctl_prop)
+
+  # Start/stop adbd via ctl.start adbd
+  set_prop(recovery, ctl_default_prop)
+
+  # Use setfscreatecon() to label files for OTA updates.
+  allow recovery self:process setfscreate;
+
+  # Allow recovery to create a fuse filesystem, and read files from it.
+  allow recovery fuse_device:chr_file rw_file_perms;
+  allow recovery fuse:dir r_dir_perms;
+  allow recovery fuse:file r_file_perms;
+
+  wakelock_use(recovery)
+
+  # This line seems suspect, as it should not really need to
+  # set scheduling parameters for a kernel domain task.
+  allow recovery kernel:process setsched;
+')
+
+###
+### neverallow rules
+###
+
+# Recovery should never touch /data.
+#
+# In particular, if /data is encrypted, it is not accessible
+# to recovery anyway.
+#
+# For now, we only enforce write/execute restrictions, as domain.te
+# contains a number of read-only rules that apply to all
+# domains, including recovery.
+#
+# TODO: tighten this up further.
+neverallow recovery data_file_type:file { no_w_file_perms no_x_file_perms };
+neverallow recovery data_file_type:dir no_w_dir_perms;
diff --git a/sepolicy/recovery_persist.te b/sepolicy/recovery_persist.te
new file mode 100644
index 0000000..162ebb1
--- /dev/null
+++ b/sepolicy/recovery_persist.te
@@ -0,0 +1,31 @@
+# android recovery persistent log manager
+type recovery_persist, domain;
+type recovery_persist_exec, exec_type, file_type;
+
+init_daemon_domain(recovery_persist)
+
+allow recovery_persist pstorefs:dir search;
+allow recovery_persist pstorefs:file r_file_perms;
+
+allow recovery_persist recovery_data_file:file create_file_perms;
+allow recovery_persist recovery_data_file:dir create_dir_perms;
+
+###
+### Neverallow rules
+###
+### recovery_persist should NEVER do any of this
+
+# Block device access.
+neverallow recovery_persist dev_type:blk_file { read write };
+
+# ptrace any other app
+neverallow recovery_persist domain:process ptrace;
+
+# Write to /system.
+neverallow recovery_persist system_file:dir_file_class_set write;
+
+# Write to files in /data/data
+neverallow recovery_persist { app_data_file system_data_file }:dir_file_class_set write;
+
+# recovery_persist is not allowed to write anywhere other than recovery_data_file
+neverallow recovery_persist { file_type -recovery_data_file -recovery_persist_tmpfs -coredump_file }:file write;
diff --git a/sepolicy/recovery_refresh.te b/sepolicy/recovery_refresh.te
new file mode 100644
index 0000000..907086e
--- /dev/null
+++ b/sepolicy/recovery_refresh.te
@@ -0,0 +1,29 @@
+# android recovery refresh log manager
+type recovery_refresh, domain;
+type recovery_refresh_exec, exec_type, file_type;
+
+init_daemon_domain(recovery_refresh)
+
+allow recovery_refresh pstorefs:dir search;
+allow recovery_refresh pstorefs:file r_file_perms;
+# NB: domain inherits write_logd which hands us write to pmsg_device
+
+###
+### Neverallow rules
+###
+### recovery_refresh should NEVER do any of this
+
+# Block device access.
+neverallow recovery_refresh dev_type:blk_file { read write };
+
+# ptrace any other app
+neverallow recovery_refresh domain:process ptrace;
+
+# Write to /system.
+neverallow recovery_refresh system_file:dir_file_class_set write;
+
+# Write to files in /data/data or system files on /data
+neverallow recovery_refresh { app_data_file system_data_file }:dir_file_class_set write;
+
+# recovery_refresh is not allowed to write anywhere
+neverallow recovery_refresh { file_type -recovery_refresh_tmpfs -coredump_file }:file write;
diff --git a/sepolicy/rild.te b/sepolicy/rild.te
new file mode 100644
index 0000000..c63f2e7
--- /dev/null
+++ b/sepolicy/rild.te
@@ -0,0 +1,44 @@
+# rild - radio interface layer daemon
+type rild, domain, domain_deprecated;
+type rild_exec, exec_type, file_type;
+
+init_daemon_domain(rild)
+net_domain(rild)
+allow rild self:netlink_route_socket nlmsg_write;
+allow rild kernel:system module_request;
+allow rild self:capability { setpcap setgid setuid net_admin net_raw };
+allow rild alarm_device:chr_file rw_file_perms;
+allow rild cgroup:dir create_dir_perms;
+allow rild radio_device:chr_file rw_file_perms;
+allow rild radio_device:blk_file r_file_perms;
+allow rild mtd_device:dir search;
+allow rild efs_file:dir create_dir_perms;
+allow rild efs_file:file create_file_perms;
+allow rild shell_exec:file rx_file_perms;
+allow rild bluetooth_efs_file:file r_file_perms;
+allow rild bluetooth_efs_file:dir r_dir_perms;
+allow rild radio_data_file:dir rw_dir_perms;
+allow rild radio_data_file:file create_file_perms;
+allow rild sdcard_type:dir r_dir_perms;
+allow rild system_data_file:dir r_dir_perms;
+allow rild system_data_file:file r_file_perms;
+allow rild system_file:file x_file_perms;
+
+# property service
+set_prop(rild, radio_prop)
+set_prop(rild, net_radio_prop)
+set_prop(rild, system_radio_prop)
+auditallow rild net_radio_prop:property_service set;
+auditallow rild system_radio_prop:property_service set;
+
+allow rild tty_device:chr_file rw_file_perms;
+
+# Allow rild to create and use netlink sockets.
+allow rild self:netlink_socket create_socket_perms;
+allow rild self:netlink_generic_socket create_socket_perms;
+allow rild self:netlink_kobject_uevent_socket create_socket_perms;
+
+# Access to wake locks
+wakelock_use(rild)
+
+allow rild self:socket create_socket_perms;
diff --git a/sepolicy/roles b/sepolicy/roles
new file mode 100644
index 0000000..af5fe8b
--- /dev/null
+++ b/sepolicy/roles
@@ -0,0 +1,2 @@
+role r;
+role r types domain;
diff --git a/sepolicy/runas.te b/sepolicy/runas.te
new file mode 100644
index 0000000..58a1bdc
--- /dev/null
+++ b/sepolicy/runas.te
@@ -0,0 +1,33 @@
+type runas, domain, domain_deprecated, mlstrustedsubject;
+type runas_exec, exec_type, file_type;
+
+# ndk-gdb invokes adb shell run-as.
+domain_auto_trans(shell, runas_exec, runas)
+allow runas adbd:process sigchld;
+allow runas shell:fd use;
+allow runas shell:fifo_file { read write };
+allow runas devpts:chr_file { read write ioctl };
+allow runas shell_data_file:file { read write };
+
+# run-as reads package information.
+allow runas system_data_file:file r_file_perms;
+
+# run-as checks and changes to the app data dir.
+dontaudit runas self:capability dac_override;
+allow runas app_data_file:dir { getattr search };
+
+# run-as switches to the app UID/GID.
+allow runas self:capability { setuid setgid };
+
+# run-as switches to the app security context.
+selinux_check_context(runas) # validate context
+allow runas self:process setcurrent;
+allow runas non_system_app_set:process dyntransition; # setcon
+
+###
+### neverallow rules
+###
+
+# run-as cannot have capabilities other than CAP_SETUID and CAP_SETGID
+neverallow runas self:capability ~{ setuid setgid };
+neverallow runas self:capability2 *;
diff --git a/sepolicy/sdcardd.te b/sepolicy/sdcardd.te
new file mode 100644
index 0000000..846c59b
--- /dev/null
+++ b/sepolicy/sdcardd.te
@@ -0,0 +1,40 @@
+type sdcardd, domain, domain_deprecated;
+type sdcardd_exec, exec_type, file_type;
+
+allow sdcardd cgroup:dir create_dir_perms;
+allow sdcardd fuse_device:chr_file rw_file_perms;
+allow sdcardd rootfs:dir mounton;  # TODO: deprecated in M
+allow sdcardd tmpfs:dir r_dir_perms;
+allow sdcardd mnt_media_rw_file:dir r_dir_perms;
+allow sdcardd storage_file:dir search;
+allow sdcardd storage_stub_file:dir { search mounton };
+allow sdcardd sdcard_type:filesystem { mount unmount };
+allow sdcardd self:capability { setuid setgid dac_override sys_admin sys_resource };
+
+allow sdcardd sdcard_type:dir create_dir_perms;
+allow sdcardd sdcard_type:file create_file_perms;
+
+type_transition sdcardd system_data_file:{ dir file } media_rw_data_file;
+allow sdcardd media_rw_data_file:dir create_dir_perms;
+allow sdcardd media_rw_data_file:file create_file_perms;
+
+# Read /data/system/packages.list.
+allow sdcardd system_data_file:file r_file_perms;
+
+# Read /data/.layout_version
+allow sdcardd install_data_file:file r_file_perms;
+
+# Allow stdin/out back to vold
+allow sdcardd vold:fd use;
+allow sdcardd vold:fifo_file { read write getattr };
+
+# Allow running on top of expanded storage
+allow sdcardd mnt_expand_file:dir search;
+
+###
+### neverallow rules
+###
+
+# The sdcard daemon should no longer be started from init
+neverallow init sdcardd_exec:file execute;
+neverallow init sdcardd:process { transition dyntransition };
diff --git a/sepolicy/seapp_contexts b/sepolicy/seapp_contexts
new file mode 100644
index 0000000..d8d2240
--- /dev/null
+++ b/sepolicy/seapp_contexts
@@ -0,0 +1,92 @@
+# Input selectors:
+#	isSystemServer (boolean)
+#	isOwner (boolean)
+#	user (string)
+#	seinfo (string)
+#	name (string)
+#	path (string)
+#	isPrivApp (boolean)
+# isSystemServer=true can only be used once.
+# An unspecified isSystemServer defaults to false.
+# isOwner=true will only match for the owner/primary user.
+# isOwner=false will only match for secondary users.
+# If unspecified, the entry can match either case.
+# An unspecified string selector will match any value.
+# A user string selector that ends in * will perform a prefix match.
+# user=_app will match any regular app UID.
+# user=_isolated will match any isolated service UID.
+# isPrivApp=true will only match for applications preinstalled in
+#       /system/priv-app.
+# All specified input selectors in an entry must match (i.e. logical AND).
+# Matching is case-insensitive.
+#
+# Precedence rules:
+# 	  (1) isSystemServer=true before isSystemServer=false.
+# 	  (2) Specified isOwner= before unspecified isOwner= boolean.
+#	  (3) Specified user= string before unspecified user= string.
+#	  (4) Fixed user= string before user= prefix (i.e. ending in *).
+#	  (5) Longer user= prefix before shorter user= prefix.
+#	  (6) Specified seinfo= string before unspecified seinfo= string.
+#	      ':' character is reserved and may not be used.
+#	  (7) Specified name= string before unspecified name= string.
+#	  (8) Specified path= string before unspecified path= string.
+# 	  (9) Specified isPrivApp= before unspecified isPrivApp= boolean.
+#
+# Outputs:
+#	domain (string)
+#	type (string)
+#	levelFrom (string; one of none, all, app, or user)
+#	level (string)
+# Only entries that specify domain= will be used for app process labeling.
+# Only entries that specify type= will be used for app directory labeling.
+# levelFrom=user is only supported for _app or _isolated UIDs.
+# levelFrom=app or levelFrom=all is only supported for _app UIDs.
+# level may be used to specify a fixed level for any UID.
+#
+#
+# Neverallow Assertions
+# Additional compile time assertion checks can be added as well. The assertion
+# rules are lines beginning with the keyword neverallow. Full support for PCRE
+# regular expressions exists on all input and output selectors. Neverallow
+# rules are never output to the built seapp_contexts file. Like all keywords,
+# neverallows are case-insensitive. A neverallow is asserted when all key value
+# inputs are matched on a key value rule line.
+#
+
+# only the system server can be in system_server domain
+neverallow isSystemServer=false domain=system_server
+neverallow isSystemServer="" domain=system_server
+
+# system domains should never be assigned outside of system uid
+neverallow user=((?!system).)* domain=system_app
+neverallow user=((?!system).)* type=system_app_data_file
+
+# anything with a non-known uid with a specified name should have a specified seinfo
+neverallow user=_app name=.* seinfo=""
+neverallow user=_app name=.* seinfo=default
+
+# neverallow shared relro to any other domain
+# and neverallow any other uid into shared_relro
+neverallow user=shared_relro domain=((?!shared_relro).)*
+neverallow user=((?!shared_relro).)* domain=shared_relro
+
+# neverallow non-isolated uids into isolated_app domain
+# and vice versa
+neverallow user=_isolated domain=((?!isolated_app).)*
+neverallow user=((?!_isolated).)* domain=isolated_app
+
+# uid shell should always be in shell domain, however non-shell
+# uid's can be in shell domain
+neverallow user=shell domain=((?!shell).)*
+
+isSystemServer=true domain=system_server
+user=system seinfo=platform domain=system_app type=system_app_data_file
+user=bluetooth seinfo=platform domain=bluetooth type=bluetooth_data_file
+user=nfc seinfo=platform domain=nfc type=nfc_data_file
+user=radio seinfo=platform domain=radio type=radio_data_file
+user=shared_relro domain=shared_relro
+user=shell seinfo=platform domain=shell type=shell_data_file
+user=_isolated domain=isolated_app levelFrom=user
+user=_app seinfo=platform domain=platform_app type=app_data_file levelFrom=user
+user=_app isPrivApp=true domain=priv_app type=app_data_file levelFrom=user
+user=_app domain=untrusted_app type=app_data_file levelFrom=user
diff --git a/sepolicy/security_classes b/sepolicy/security_classes
new file mode 100644
index 0000000..680d3dd
--- /dev/null
+++ b/sepolicy/security_classes
@@ -0,0 +1,110 @@
+# FLASK
+
+#
+# Define the security object classes
+#
+
+# Classes marked as userspace are classes
+# for userspace object managers
+
+class security
+class process
+class system
+class capability
+
+# file-related classes
+class filesystem
+class file
+class dir
+class fd
+class lnk_file
+class chr_file
+class blk_file
+class sock_file
+class fifo_file
+
+# network-related classes
+class socket
+class tcp_socket
+class udp_socket
+class rawip_socket
+class node
+class netif
+class netlink_socket
+class packet_socket
+class key_socket
+class unix_stream_socket
+class unix_dgram_socket
+
+# sysv-ipc-related classes
+class sem
+class msg
+class msgq
+class shm
+class ipc
+
+# extended netlink sockets
+class netlink_route_socket
+class netlink_firewall_socket
+class netlink_tcpdiag_socket
+class netlink_nflog_socket
+class netlink_xfrm_socket
+class netlink_selinux_socket
+class netlink_audit_socket
+class netlink_ip6fw_socket
+class netlink_dnrt_socket
+
+# IPSec association
+class association
+
+# Updated Netlink class for KOBJECT_UEVENT family.
+class netlink_kobject_uevent_socket
+
+class appletalk_socket
+
+class packet
+
+# Kernel access key retention
+class key
+
+class dccp_socket
+
+class memprotect
+
+# network peer labels
+class peer
+
+# Capabilities >= 32
+class capability2
+
+# kernel services that need to override task security, e.g. cachefiles
+class kernel_service
+
+class tun_socket
+
+class binder
+
+# Updated netlink classes for more recent netlink protocols.
+class netlink_iscsi_socket
+class netlink_fib_lookup_socket
+class netlink_connector_socket
+class netlink_netfilter_socket
+class netlink_generic_socket
+class netlink_scsitransport_socket
+class netlink_rdma_socket
+class netlink_crypto_socket
+
+# Property service
+class property_service          # userspace
+
+# Service manager
+class service_manager           # userspace
+
+# Keystore Key
+class keystore_key              # userspace
+
+# debuggerd service
+class debuggerd                 # userspace
+
+class drmservice                # userspace
+# FLASK
diff --git a/sepolicy/service.te b/sepolicy/service.te
new file mode 100644
index 0000000..fb5b9f4
--- /dev/null
+++ b/sepolicy/service.te
@@ -0,0 +1,106 @@
+type bluetooth_service,         service_manager_type;
+type default_android_service,   service_manager_type;
+type drmserver_service,         service_manager_type;
+type gatekeeper_service,        app_api_service, service_manager_type;
+type fingerprintd_service,      service_manager_type;
+type batteryproperties_service, app_api_service, service_manager_type;
+type inputflinger_service,      service_manager_type;
+type keystore_service,          service_manager_type;
+type mediaserver_service,       service_manager_type;
+type nfc_service,               service_manager_type;
+type radio_service,             service_manager_type;
+type surfaceflinger_service,    service_manager_type;
+type system_app_service,        service_manager_type;
+type update_engine_service,     service_manager_type;
+
+# system_server_services broken down
+type accessibility_service, app_api_service, system_server_service, service_manager_type;
+type account_service, app_api_service, system_server_service, service_manager_type;
+type activity_service, app_api_service, system_server_service, service_manager_type;
+type alarm_service, app_api_service, system_server_service, service_manager_type;
+type appops_service, app_api_service, system_server_service, service_manager_type;
+type appwidget_service, app_api_service, system_server_service, service_manager_type;
+type assetatlas_service, app_api_service, system_server_service, service_manager_type;
+type audio_service, app_api_service, system_server_service, service_manager_type;
+type backup_service, app_api_service, system_server_service, service_manager_type;
+type batterystats_service, app_api_service, system_server_service, service_manager_type;
+type battery_service, system_server_service, service_manager_type;
+type bluetooth_manager_service, app_api_service, system_server_service, service_manager_type;
+type cameraproxy_service, system_server_service, service_manager_type;
+type clipboard_service, app_api_service, system_server_service, service_manager_type;
+type IProxyService_service, system_api_service, system_server_service, service_manager_type;
+type commontime_management_service, system_server_service, service_manager_type;
+type connectivity_service, app_api_service, system_server_service, service_manager_type;
+type consumer_ir_service, app_api_service, system_server_service, service_manager_type;
+type content_service, app_api_service, system_server_service, service_manager_type;
+type country_detector_service, app_api_service, system_server_service, service_manager_type;
+type cpuinfo_service, system_api_service, system_server_service, service_manager_type;
+type dbinfo_service, system_api_service, system_server_service, service_manager_type;
+type device_policy_service, app_api_service, system_server_service, service_manager_type;
+type deviceidle_service, app_api_service, system_server_service, service_manager_type;
+type devicestoragemonitor_service, system_server_service, service_manager_type;
+type diskstats_service, system_api_service, system_server_service, service_manager_type;
+type display_service, app_api_service, system_server_service, service_manager_type;
+type DockObserver_service, system_server_service, service_manager_type;
+type dreams_service, app_api_service, system_server_service, service_manager_type;
+type dropbox_service, app_api_service, system_server_service, service_manager_type;
+type ethernet_service, app_api_service, system_server_service, service_manager_type;
+type fingerprint_service, app_api_service, system_server_service, service_manager_type;
+type gfxinfo_service, system_api_service, system_server_service, service_manager_type;
+type graphicsstats_service, app_api_service, system_server_service, service_manager_type;
+type hardware_service, system_server_service, service_manager_type;
+type hdmi_control_service, system_api_service, system_server_service, service_manager_type;
+type input_method_service, app_api_service, system_server_service, service_manager_type;
+type input_service, app_api_service, system_server_service, service_manager_type;
+type imms_service, app_api_service, system_server_service, service_manager_type;
+type jobscheduler_service, app_api_service, system_server_service, service_manager_type;
+type launcherapps_service, app_api_service, system_server_service, service_manager_type;
+type location_service, app_api_service, system_server_service, service_manager_type;
+type lock_settings_service, system_api_service, system_server_service, service_manager_type;
+type media_projection_service, app_api_service, system_server_service, service_manager_type;
+type media_router_service, app_api_service, system_server_service, service_manager_type;
+type media_session_service, app_api_service, system_server_service, service_manager_type;
+type meminfo_service, system_api_service, system_server_service, service_manager_type;
+type midi_service, app_api_service, system_server_service, service_manager_type;
+type mount_service, app_api_service, system_server_service, service_manager_type;
+type netpolicy_service, app_api_service, system_server_service, service_manager_type;
+type netstats_service, app_api_service, system_server_service, service_manager_type;
+type network_management_service, app_api_service, system_server_service, service_manager_type;
+type network_score_service, system_api_service, system_server_service, service_manager_type;
+type notification_service, app_api_service, system_server_service, service_manager_type;
+type package_service, app_api_service, system_server_service, service_manager_type;
+type permission_service, app_api_service, system_server_service, service_manager_type;
+type persistent_data_block_service, system_api_service, system_server_service, service_manager_type;
+type power_service, app_api_service, system_server_service, service_manager_type;
+type print_service, app_api_service, system_server_service, service_manager_type;
+type processinfo_service, system_server_service, service_manager_type;
+type procstats_service, app_api_service, system_server_service, service_manager_type;
+type recovery_service, system_server_service, service_manager_type;
+type registry_service, app_api_service, system_server_service, service_manager_type;
+type restrictions_service, app_api_service, system_server_service, service_manager_type;
+type rttmanager_service, app_api_service, system_server_service, service_manager_type;
+type samplingprofiler_service, system_server_service, service_manager_type;
+type scheduling_policy_service, system_server_service, service_manager_type;
+type search_service, app_api_service, system_server_service, service_manager_type;
+type sensorservice_service, app_api_service, system_server_service, service_manager_type;
+type serial_service, system_api_service, system_server_service, service_manager_type;
+type servicediscovery_service, app_api_service, system_server_service, service_manager_type;
+type statusbar_service, app_api_service, system_server_service, service_manager_type;
+type task_service, system_server_service, service_manager_type;
+type textservices_service, app_api_service, system_server_service, service_manager_type;
+type telecom_service, app_api_service, system_server_service, service_manager_type;
+type trust_service, app_api_service, system_server_service, service_manager_type;
+type tv_input_service, app_api_service, system_server_service, service_manager_type;
+type uimode_service, app_api_service, system_server_service, service_manager_type;
+type updatelock_service, system_api_service, system_server_service, service_manager_type;
+type usagestats_service, app_api_service, system_server_service, service_manager_type;
+type usb_service, app_api_service, system_server_service, service_manager_type;
+type user_service, app_api_service, system_server_service, service_manager_type;
+type vibrator_service, app_api_service, system_server_service, service_manager_type;
+type voiceinteraction_service, app_api_service, system_server_service, service_manager_type;
+type wallpaper_service, app_api_service, system_server_service, service_manager_type;
+type webviewupdate_service, app_api_service, system_server_service, service_manager_type;
+type wifip2p_service, app_api_service, system_server_service, service_manager_type;
+type wifiscanner_service, system_api_service, system_server_service, service_manager_type;
+type wifi_service, app_api_service, system_server_service, service_manager_type;
+type window_service, system_api_service, system_server_service, service_manager_type;
diff --git a/sepolicy/service_contexts b/sepolicy/service_contexts
new file mode 100644
index 0000000..0e77818
--- /dev/null
+++ b/sepolicy/service_contexts
@@ -0,0 +1,132 @@
+accessibility                             u:object_r:accessibility_service:s0
+account                                   u:object_r:account_service:s0
+activity                                  u:object_r:activity_service:s0
+alarm                                     u:object_r:alarm_service:s0
+android.os.UpdateEngineService            u:object_r:update_engine_service:s0
+android.security.keystore                 u:object_r:keystore_service:s0
+android.service.gatekeeper.IGateKeeperService    u:object_r:gatekeeper_service:s0
+appops                                    u:object_r:appops_service:s0
+appwidget                                 u:object_r:appwidget_service:s0
+assetatlas                                u:object_r:assetatlas_service:s0
+audio                                     u:object_r:audio_service:s0
+backup                                    u:object_r:backup_service:s0
+batteryproperties                         u:object_r:batteryproperties_service:s0
+batterystats                              u:object_r:batterystats_service:s0
+battery                                   u:object_r:battery_service:s0
+bluetooth_manager                         u:object_r:bluetooth_manager_service:s0
+bluetooth                                 u:object_r:bluetooth_service:s0
+carrier_config                            u:object_r:radio_service:s0
+clipboard                                 u:object_r:clipboard_service:s0
+com.android.net.IProxyService             u:object_r:IProxyService_service:s0
+commontime_management                     u:object_r:commontime_management_service:s0
+common_time.clock                        u:object_r:mediaserver_service:s0
+common_time.config                       u:object_r:mediaserver_service:s0
+connectivity                              u:object_r:connectivity_service:s0
+consumer_ir                               u:object_r:consumer_ir_service:s0
+content                                   u:object_r:content_service:s0
+country_detector                          u:object_r:country_detector_service:s0
+cpuinfo                                   u:object_r:cpuinfo_service:s0
+dbinfo                                    u:object_r:dbinfo_service:s0
+device_policy                             u:object_r:device_policy_service:s0
+deviceidle                                u:object_r:deviceidle_service:s0
+devicestoragemonitor                      u:object_r:devicestoragemonitor_service:s0
+diskstats                                 u:object_r:diskstats_service:s0
+display.qservice                          u:object_r:surfaceflinger_service:s0
+display                                   u:object_r:display_service:s0
+DockObserver                              u:object_r:DockObserver_service:s0
+dreams                                    u:object_r:dreams_service:s0
+drm.drmManager                            u:object_r:drmserver_service:s0
+dropbox                                   u:object_r:dropbox_service:s0
+ethernet                                  u:object_r:ethernet_service:s0
+fingerprint                               u:object_r:fingerprint_service:s0
+android.hardware.fingerprint.IFingerprintDaemon u:object_r:fingerprintd_service:s0
+gfxinfo                                   u:object_r:gfxinfo_service:s0
+graphicsstats                             u:object_r:graphicsstats_service:s0
+hardware                                  u:object_r:hardware_service:s0
+hdmi_control                              u:object_r:hdmi_control_service:s0
+inputflinger                              u:object_r:inputflinger_service:s0
+input_method                              u:object_r:input_method_service:s0
+input                                     u:object_r:input_service:s0
+iphonesubinfo_msim                        u:object_r:radio_service:s0
+iphonesubinfo2                            u:object_r:radio_service:s0
+iphonesubinfo                             u:object_r:radio_service:s0
+ims                                       u:object_r:radio_service:s0
+imms                                      u:object_r:imms_service:s0
+isms_msim                                 u:object_r:radio_service:s0
+isms2                                     u:object_r:radio_service:s0
+isms                                      u:object_r:radio_service:s0
+isub                                      u:object_r:radio_service:s0
+jobscheduler                              u:object_r:jobscheduler_service:s0
+launcherapps                              u:object_r:launcherapps_service:s0
+location                                  u:object_r:location_service:s0
+lock_settings                             u:object_r:lock_settings_service:s0
+media.audio_flinger                       u:object_r:mediaserver_service:s0
+media.audio_policy                        u:object_r:mediaserver_service:s0
+media.camera                              u:object_r:mediaserver_service:s0
+media.camera.proxy                        u:object_r:cameraproxy_service:s0
+media.log                                 u:object_r:mediaserver_service:s0
+media.player                              u:object_r:mediaserver_service:s0
+media.resource_manager                    u:object_r:mediaserver_service:s0
+media.radio                               u:object_r:mediaserver_service:s0
+media.sound_trigger_hw                    u:object_r:mediaserver_service:s0
+media_projection                          u:object_r:media_projection_service:s0
+media_router                              u:object_r:media_router_service:s0
+media_session                             u:object_r:media_session_service:s0
+meminfo                                   u:object_r:meminfo_service:s0
+midi                                      u:object_r:midi_service:s0
+mount                                     u:object_r:mount_service:s0
+netpolicy                                 u:object_r:netpolicy_service:s0
+netstats                                  u:object_r:netstats_service:s0
+network_management                        u:object_r:network_management_service:s0
+network_score                             u:object_r:network_score_service:s0
+nfc                                       u:object_r:nfc_service:s0
+notification                              u:object_r:notification_service:s0
+package                                   u:object_r:package_service:s0
+permission                                u:object_r:permission_service:s0
+persistent_data_block                     u:object_r:persistent_data_block_service:s0
+phone_msim                                u:object_r:radio_service:s0
+phone1                                    u:object_r:radio_service:s0
+phone2                                    u:object_r:radio_service:s0
+phone                                     u:object_r:radio_service:s0
+power                                     u:object_r:power_service:s0
+print                                     u:object_r:print_service:s0
+processinfo                               u:object_r:processinfo_service:s0
+procstats                                 u:object_r:procstats_service:s0
+radio.phonesubinfo                        u:object_r:radio_service:s0
+radio.phone                               u:object_r:radio_service:s0
+radio.sms                                 u:object_r:radio_service:s0
+recovery                                  u:object_r:recovery_service:s0
+restrictions                              u:object_r:restrictions_service:s0
+rttmanager                                u:object_r:rttmanager_service:s0
+samplingprofiler                          u:object_r:samplingprofiler_service:s0
+scheduling_policy                         u:object_r:scheduling_policy_service:s0
+search                                    u:object_r:search_service:s0
+sensorservice                             u:object_r:sensorservice_service:s0
+serial                                    u:object_r:serial_service:s0
+servicediscovery                          u:object_r:servicediscovery_service:s0
+simphonebook_msim                         u:object_r:radio_service:s0
+simphonebook2                             u:object_r:radio_service:s0
+simphonebook                              u:object_r:radio_service:s0
+sip                                       u:object_r:radio_service:s0
+statusbar                                 u:object_r:statusbar_service:s0
+SurfaceFlinger                            u:object_r:surfaceflinger_service:s0
+task                                      u:object_r:task_service:s0
+telecom                                   u:object_r:telecom_service:s0
+telephony.registry                        u:object_r:registry_service:s0
+textservices                              u:object_r:textservices_service:s0
+trust                                     u:object_r:trust_service:s0
+tv_input                                  u:object_r:tv_input_service:s0
+uimode                                    u:object_r:uimode_service:s0
+updatelock                                u:object_r:updatelock_service:s0
+usagestats                                u:object_r:usagestats_service:s0
+usb                                       u:object_r:usb_service:s0
+user                                      u:object_r:user_service:s0
+vibrator                                  u:object_r:vibrator_service:s0
+voiceinteraction                          u:object_r:voiceinteraction_service:s0
+wallpaper                                 u:object_r:wallpaper_service:s0
+webviewupdate                             u:object_r:webviewupdate_service:s0
+wifip2p                                   u:object_r:wifip2p_service:s0
+wifiscanner                               u:object_r:wifiscanner_service:s0
+wifi                                      u:object_r:wifi_service:s0
+window                                    u:object_r:window_service:s0
+*                                         u:object_r:default_android_service:s0
diff --git a/sepolicy/servicemanager.te b/sepolicy/servicemanager.te
new file mode 100644
index 0000000..84605d1
--- /dev/null
+++ b/sepolicy/servicemanager.te
@@ -0,0 +1,17 @@
+# servicemanager - the Binder context manager
+type servicemanager, domain, domain_deprecated, mlstrustedsubject;
+type servicemanager_exec, exec_type, file_type;
+
+init_daemon_domain(servicemanager)
+
+# Note that we do not use the binder_* macros here.
+# servicemanager is unique in that it only provides
+# name service (aka context manager) for Binder.
+# As such, it only ever receives and transfers other references
+# created by other domains.  It never passes its own references
+# or initiates a Binder IPC.
+allow servicemanager self:binder set_context_mgr;
+allow servicemanager { domain -init }:binder transfer;
+
+# Check SELinux permissions.
+selinux_check_access(servicemanager)
diff --git a/sepolicy/sgdisk.te b/sepolicy/sgdisk.te
new file mode 100644
index 0000000..43636d4
--- /dev/null
+++ b/sepolicy/sgdisk.te
@@ -0,0 +1,22 @@
+# sgdisk called from vold
+type sgdisk, domain, domain_deprecated;
+type sgdisk_exec, exec_type, file_type;
+
+# Allowed to read/write low-level partition tables
+allow sgdisk block_device:dir search;
+allow sgdisk vold_device:blk_file rw_file_perms;
+
+# Inherit and use pty created by android_fork_execvp()
+allow sgdisk devpts:chr_file { read write ioctl getattr };
+
+# Allow stdin/out back to vold
+allow sgdisk vold:fd use;
+allow sgdisk vold:fifo_file { read write getattr };
+
+# Used to probe kernel to reload partition tables
+allow sgdisk self:capability sys_admin;
+
+# Only allow entry from vold
+neverallow { domain -vold } sgdisk:process transition;
+neverallow * sgdisk:process dyntransition;
+neverallow sgdisk { file_type fs_type -sgdisk_exec }:file entrypoint;
diff --git a/sepolicy/shared_relro.te b/sepolicy/shared_relro.te
new file mode 100644
index 0000000..30af14a
--- /dev/null
+++ b/sepolicy/shared_relro.te
@@ -0,0 +1,13 @@
+# Process which creates/updates shared RELRO files to be used by other apps.
+type shared_relro, domain, domain_deprecated;
+
+# The shared relro process is a Java program forked from the zygote, so it
+# inherits from app to get basic permissions it needs to run.
+app_domain(shared_relro)
+
+# Grant write access to the shared relro files/directory.
+allow shared_relro shared_relro_file:dir rw_dir_perms;
+allow shared_relro shared_relro_file:file create_file_perms;
+
+# Needs to contact the "webviewupdate" and "activity" services
+allow shared_relro webviewupdate_service:service_manager find;
diff --git a/sepolicy/shell.te b/sepolicy/shell.te
new file mode 100644
index 0000000..b7b4e03
--- /dev/null
+++ b/sepolicy/shell.te
@@ -0,0 +1,168 @@
+# Domain for shell processes spawned by ADB or console service.
+type shell, domain, mlstrustedsubject;
+type shell_exec, exec_type, file_type;
+
+# Create and use network sockets.
+net_domain(shell)
+
+# Run app_process.
+# XXX Transition into its own domain?
+app_domain(shell)
+
+# logcat
+read_logd(shell)
+control_logd(shell)
+# logcat -L (directly, or via dumpstate)
+allow shell pstorefs:dir search;
+allow shell pstorefs:file r_file_perms;
+# logpersistd (nee logcatd) files
+userdebug_or_eng(`
+  allow shell misc_logd_file:dir r_dir_perms;
+  allow shell misc_logd_file:file r_file_perms;
+')
+
+# Root fs.
+allow shell rootfs:dir r_dir_perms;
+
+# read files in /data/anr
+allow shell anr_data_file:dir r_dir_perms;
+allow shell anr_data_file:file r_file_perms;
+
+# Access /data/local/tmp.
+allow shell shell_data_file:dir create_dir_perms;
+allow shell shell_data_file:file create_file_perms;
+allow shell shell_data_file:file rx_file_perms;
+allow shell shell_data_file:lnk_file create_file_perms;
+
+# Read/execute files in /data/nativetest
+userdebug_or_eng(`
+  allow shell nativetest_data_file:dir r_dir_perms;
+  allow shell nativetest_data_file:file rx_file_perms;
+')
+
+# adb bugreport
+unix_socket_connect(shell, dumpstate, dumpstate)
+
+allow shell devpts:chr_file rw_file_perms;
+allow shell tty_device:chr_file rw_file_perms;
+allow shell console_device:chr_file rw_file_perms;
+allow shell input_device:dir r_dir_perms;
+allow shell input_device:chr_file rw_file_perms;
+r_dir_file(shell, system_file)
+allow shell system_file:file x_file_perms;
+allow shell toolbox_exec:file rx_file_perms;
+allow shell shell_exec:file rx_file_perms;
+allow shell zygote_exec:file rx_file_perms;
+
+r_dir_file(shell, apk_data_file)
+
+# Set properties.
+set_prop(shell, shell_prop)
+set_prop(shell, ctl_bugreport_prop)
+set_prop(shell, ctl_dumpstate_prop)
+set_prop(shell, dumpstate_prop)
+set_prop(shell, debug_prop)
+set_prop(shell, powerctl_prop)
+userdebug_or_eng(`set_prop(shell, logpersistd_logging_prop)')
+
+# systrace support - allow atrace to run
+allow shell debugfs_tracing:dir r_dir_perms;
+allow shell debugfs_tracing:file rw_file_perms;
+allow shell debugfs_trace_marker:file getattr;
+allow shell atrace_exec:file rx_file_perms;
+
+userdebug_or_eng(`
+  # "systrace --boot" support - allow boottrace service to run
+  allow shell boottrace_data_file:dir rw_dir_perms;
+  allow shell boottrace_data_file:file create_file_perms;
+  set_prop(shell, persist_debug_prop)
+')
+
+# allow shell to run dmesg
+allow shell kernel:system syslog_read;
+
+# allow shell access to services
+allow shell servicemanager:service_manager list;
+# don't allow shell to access GateKeeper service
+allow shell { service_manager_type -gatekeeper_service }:service_manager find;
+
+# allow shell to look through /proc/ for ps, top, netstat
+r_dir_file(shell, proc)
+r_dir_file(shell, proc_net)
+allow shell proc_interrupts:file r_file_perms;
+allow shell proc_meminfo:file r_file_perms;
+allow shell proc_stat:file r_file_perms;
+allow shell proc_timer:file r_file_perms;
+allow shell proc_zoneinfo:file r_file_perms;
+r_dir_file(shell, cgroup)
+allow shell domain:dir { search open read getattr };
+allow shell domain:{ file lnk_file } { open read getattr };
+
+# statvfs() of /proc and other labeled filesystems
+# (yaffs2, jffs2, ext2, ext3, ext4, xfs, btrfs, f2fs, squashfs)
+allow shell { proc labeledfs }:filesystem getattr;
+
+# stat() of /dev
+allow shell device:dir getattr;
+
+# allow shell to read /proc/pid/attr/current for ps -Z
+allow shell domain:process getattr;
+
+# Allow pulling the SELinux policy for CTS purposes
+allow shell selinuxfs:dir r_dir_perms;
+allow shell selinuxfs:file r_file_perms;
+
+# enable shell domain to read/write files/dirs for bootchart data
+# User will creates the start and stop file via adb shell
+# and read other files created by init process under /data/bootchart
+allow shell bootchart_data_file:dir rw_dir_perms;
+allow shell bootchart_data_file:file create_file_perms;
+
+# Make sure strace works for the non-privileged shell user
+allow shell self:process ptrace;
+
+# allow shell to get battery info
+allow shell sysfs_batteryinfo:file r_file_perms;
+allow shell sysfs:dir r_dir_perms;
+
+# Allow access to ion memory allocation device.
+allow shell ion_device:chr_file rw_file_perms;
+
+#
+# filesystem test for insecure chr_file's is done
+# via a host side test
+#
+allow shell dev_type:dir r_dir_perms;
+allow shell dev_type:chr_file getattr;
+
+# /dev/fd is a symlink
+allow shell proc:lnk_file getattr;
+
+#
+# filesystem test for insucre blk_file's is done
+# via hostside test
+#
+allow shell dev_type:blk_file getattr;
+
+###
+### Neverallow rules
+###
+
+# Do not allow shell to hard link to any files.
+# In particular, if shell hard links to app data
+# files, installd will not be able to guarantee the deletion
+# of the linked to file. Hard links also contribute to security
+# bugs, so we want to ensure the shell user never has this
+# capability.
+neverallow shell file_type:file link;
+
+# limit shell access to sensitive char drivers to
+# only getattr required for host side test.
+neverallow shell {
+  fuse_device
+  hw_random_device
+  kmem_device
+}:chr_file ~getattr;
+
+# Limit shell to only getattr on blk devices for host side tests.
+neverallow shell dev_type:blk_file ~getattr;
diff --git a/sepolicy/slideshow.te b/sepolicy/slideshow.te
new file mode 100644
index 0000000..3165a65
--- /dev/null
+++ b/sepolicy/slideshow.te
@@ -0,0 +1,14 @@
+# slideshow seclabel is specified in init.rc since
+# it lives in the rootfs and has no unique file type.
+type slideshow, domain, domain_deprecated;
+
+allow slideshow kmsg_device:chr_file rw_file_perms;
+wakelock_use(slideshow)
+allow slideshow device:dir r_dir_perms;
+allow slideshow self:capability sys_tty_config;
+allow slideshow graphics_device:dir r_dir_perms;
+allow slideshow graphics_device:chr_file rw_file_perms;
+allow slideshow input_device:dir r_dir_perms;
+allow slideshow input_device:chr_file r_file_perms;
+allow slideshow tty_device:chr_file rw_file_perms;
+
diff --git a/sepolicy/su.te b/sepolicy/su.te
new file mode 100644
index 0000000..5c98258
--- /dev/null
+++ b/sepolicy/su.te
@@ -0,0 +1,56 @@
+# File types must be defined for file_contexts.
+type su_exec, exec_type, file_type;
+
+userdebug_or_eng(`
+  # Domain used for su processes, as well as for adbd and adb shell
+  # after performing an adb root command.  The domain definition is
+  # wrapped to ensure that it does not exist at all on -user builds.
+  type su, domain, mlstrustedsubject;
+  domain_auto_trans(shell, su_exec, su)
+
+  # Allow dumpstate to call su on userdebug / eng builds to collect
+  # additional information.
+  domain_auto_trans(dumpstate, su_exec, su)
+
+  # Make sure that dumpstate runs the same from the "su" domain as
+  # from the "init" domain.
+  domain_auto_trans(su, dumpstate_exec, dumpstate)
+
+  # su is also permissive to permit setenforce.
+  permissive su;
+
+  # Add su to various domains
+  net_domain(su)
+  app_domain(su)
+
+  dontaudit su self:capability_class_set *;
+  dontaudit su kernel:security *;
+  dontaudit su kernel:system *;
+  dontaudit su self:memprotect *;
+  dontaudit su domain:process *;
+  dontaudit su domain:fd *;
+  dontaudit su domain:dir *;
+  dontaudit su domain:lnk_file *;
+  dontaudit su domain:{ fifo_file file } *;
+  dontaudit su domain:socket_class_set *;
+  dontaudit su domain:ipc_class_set *;
+  dontaudit su domain:key *;
+  dontaudit su fs_type:filesystem *;
+  dontaudit su {fs_type dev_type file_type}:dir_file_class_set *;
+  dontaudit su node_type:node *;
+  dontaudit su node_type:{ tcp_socket udp_socket rawip_socket } *;
+  dontaudit su netif_type:netif *;
+  dontaudit su port_type:socket_class_set *;
+  dontaudit su port_type:{ tcp_socket dccp_socket } *;
+  dontaudit su domain:peer *;
+  dontaudit su domain:binder *;
+  dontaudit su property_type:property_service *;
+  dontaudit su property_type:file *;
+  dontaudit su service_manager_type:service_manager *;
+  dontaudit su servicemanager:service_manager list;
+  dontaudit su keystore:keystore_key *;
+  dontaudit su domain:debuggerd *;
+  dontaudit su domain:drmservice *;
+  dontaudit su unlabeled:filesystem *;
+  dontaudit su postinstall_file:filesystem *;
+')
diff --git a/sepolicy/surfaceflinger.te b/sepolicy/surfaceflinger.te
new file mode 100644
index 0000000..fbe1dd0
--- /dev/null
+++ b/sepolicy/surfaceflinger.te
@@ -0,0 +1,68 @@
+# surfaceflinger - display compositor service
+type surfaceflinger, domain, domain_deprecated;
+type surfaceflinger_exec, exec_type, file_type;
+
+init_daemon_domain(surfaceflinger)
+typeattribute surfaceflinger mlstrustedsubject;
+
+# Perform Binder IPC.
+binder_use(surfaceflinger)
+binder_call(surfaceflinger, binderservicedomain)
+binder_call(surfaceflinger, appdomain)
+binder_call(surfaceflinger, bootanim)
+binder_service(surfaceflinger)
+
+# Binder IPC to bu, presently runs in adbd domain.
+binder_call(surfaceflinger, adbd)
+
+# Read /proc/pid files for Binder clients.
+r_dir_file(surfaceflinger, binderservicedomain)
+r_dir_file(surfaceflinger, appdomain)
+
+# Access the GPU.
+allow surfaceflinger gpu_device:chr_file rw_file_perms;
+
+# Access /dev/graphics/fb0.
+allow surfaceflinger graphics_device:dir search;
+allow surfaceflinger graphics_device:chr_file rw_file_perms;
+
+# Access /dev/video1.
+allow surfaceflinger video_device:dir r_dir_perms;
+allow surfaceflinger video_device:chr_file rw_file_perms;
+
+# Create and use netlink kobject uevent sockets.
+allow surfaceflinger self:netlink_kobject_uevent_socket create_socket_perms;
+
+# Set properties.
+set_prop(surfaceflinger, system_prop)
+set_prop(surfaceflinger, ctl_bootanim_prop)
+
+# Use open files supplied by an app.
+allow surfaceflinger app_data_file:file { read write };
+
+# Allow a dumpstate triggered screenshot
+binder_call(surfaceflinger, dumpstate)
+binder_call(surfaceflinger, shell)
+r_dir_file(surfaceflinger, dumpstate)
+
+# Needed on some devices for playing DRM protected content,
+# but seems expected and appropriate for all devices.
+allow surfaceflinger tee:unix_stream_socket connectto;
+allow surfaceflinger tee_device:chr_file rw_file_perms;
+
+
+# media.player service
+allow surfaceflinger mediaserver_service:service_manager find;
+allow surfaceflinger permission_service:service_manager find;
+allow surfaceflinger power_service:service_manager find;
+allow surfaceflinger surfaceflinger_service:service_manager { add find };
+allow surfaceflinger window_service:service_manager find;
+
+###
+### Neverallow rules
+###
+### surfaceflinger should NEVER do any of this
+
+# Do not allow accessing SDcard files as unsafe ejection could
+# cause the kernel to kill the process.
+neverallow surfaceflinger sdcard_type:file rw_file_perms;
diff --git a/sepolicy/system_app.te b/sepolicy/system_app.te
new file mode 100644
index 0000000..4c9c136
--- /dev/null
+++ b/sepolicy/system_app.te
@@ -0,0 +1,74 @@
+#
+# Apps that run with the system UID, e.g. com.android.system.ui,
+# com.android.settings.  These are not as privileged as the system
+# server.
+#
+type system_app, domain, domain_deprecated;
+app_domain(system_app)
+net_domain(system_app)
+binder_service(system_app)
+
+# Read and write /data/data subdirectory.
+allow system_app system_app_data_file:dir create_dir_perms;
+allow system_app system_app_data_file:{ file lnk_file } create_file_perms;
+
+# Read and write to /data/misc/user.
+allow system_app misc_user_data_file:dir create_dir_perms;
+allow system_app misc_user_data_file:file create_file_perms;
+
+# Access to vold-mounted storage for measuring free space
+allow system_app mnt_media_rw_file:dir search;
+
+# Read wallpaper file.
+allow system_app wallpaper_file:file r_file_perms;
+
+# Write to properties
+set_prop(system_app, bluetooth_prop)
+set_prop(system_app, debug_prop)
+set_prop(system_app, system_prop)
+set_prop(system_app, logd_prop)
+set_prop(system_app, net_radio_prop)
+set_prop(system_app, system_radio_prop)
+userdebug_or_eng(`set_prop(system_app, logpersistd_logging_prop)')
+auditallow system_app net_radio_prop:property_service set;
+auditallow system_app system_radio_prop:property_service set;
+
+# ctl interface
+set_prop(system_app, ctl_default_prop)
+set_prop(system_app, ctl_bugreport_prop)
+
+# Create /data/anr/traces.txt.
+allow system_app anr_data_file:dir ra_dir_perms;
+allow system_app anr_data_file:file create_file_perms;
+
+# Settings need to access app name and icon from asec
+allow system_app asec_apk_file:file r_file_perms;
+
+allow system_app servicemanager:service_manager list;
+allow system_app service_manager_type:service_manager find;
+
+allow system_app keystore:keystore_key {
+	get_state
+	get
+	insert
+	delete
+	exist
+	list
+	reset
+	password
+	lock
+	unlock
+	is_empty
+	sign
+	verify
+	grant
+	duplicate
+	clear_uid
+	user_changed
+};
+
+# /sys access
+allow system_app sysfs_zram:dir search;
+allow system_app sysfs_zram:file r_file_perms;
+
+control_logd(system_app)
diff --git a/sepolicy/system_server.te b/sepolicy/system_server.te
new file mode 100644
index 0000000..76e28d0
--- /dev/null
+++ b/sepolicy/system_server.te
@@ -0,0 +1,508 @@
+#
+# System Server aka system_server spawned by zygote.
+# Most of the framework services run in this process.
+#
+type system_server, domain, domain_deprecated, mlstrustedsubject;
+
+# Define a type for tmpfs-backed ashmem regions.
+tmpfs_domain(system_server)
+
+# For art.
+allow system_server dalvikcache_data_file:file execute;
+allow system_server dalvikcache_data_file:dir r_dir_perms;
+
+# /data/resource-cache
+allow system_server resourcecache_data_file:file r_file_perms;
+allow system_server resourcecache_data_file:dir r_dir_perms;
+
+# ptrace to processes in the same domain for debugging crashes.
+allow system_server self:process ptrace;
+
+# Child of the zygote.
+allow system_server zygote:fd use;
+allow system_server zygote:process sigchld;
+allow system_server zygote_tmpfs:file read;
+
+# May kill zygote on crashes.
+allow system_server zygote:process sigkill;
+
+# Read /system/bin/app_process.
+allow system_server zygote_exec:file r_file_perms;
+
+# Needed to close the zygote socket, which involves getopt / getattr
+allow system_server zygote:unix_stream_socket { getopt getattr };
+
+# system server gets network and bluetooth permissions.
+net_domain(system_server)
+bluetooth_domain(system_server)
+
+# These are the capabilities assigned by the zygote to the
+# system server.
+allow system_server self:capability {
+    kill
+    net_admin
+    net_bind_service
+    net_broadcast
+    net_raw
+    sys_boot
+    sys_nice
+    sys_resource
+    sys_time
+    sys_tty_config
+};
+
+wakelock_use(system_server)
+
+# Triggered by /proc/pid accesses, not allowed.
+dontaudit system_server self:capability sys_ptrace;
+
+# Trigger module auto-load.
+allow system_server kernel:system module_request;
+
+# Allow alarmtimers to be set
+allow system_server self:capability2 wake_alarm;
+
+# Use netlink uevent sockets.
+allow system_server self:netlink_kobject_uevent_socket create_socket_perms;
+
+# Use generic netlink sockets.
+allow system_server self:netlink_socket create_socket_perms;
+allow system_server self:netlink_generic_socket create_socket_perms;
+
+# Use generic "sockets" where the address family is not known
+# to the kernel.
+allow system_server self:socket create_socket_perms;
+
+# Set and get routes directly via netlink.
+allow system_server self:netlink_route_socket nlmsg_write;
+
+# Kill apps.
+allow system_server appdomain:process { sigkill signal };
+
+# Set scheduling info for apps.
+allow system_server appdomain:process { getsched setsched };
+allow system_server mediaserver:process { getsched setsched };
+
+# Read /proc/pid data for all domains. This is used by ProcessCpuTracker
+# within system_server to keep track of memory and CPU usage for
+# all processes on the device.
+r_dir_file(system_server, domain)
+
+# 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;
+
+# Read /proc/uid_cputime/show_uid_stat.
+allow system_server proc_uid_cputime_showstat:file r_file_perms;
+
+# Write /proc/uid_cputime/remove_uid_range.
+allow system_server proc_uid_cputime_removeuid:file { w_file_perms getattr };
+
+# Write to /proc/sysrq-trigger.
+allow system_server proc_sysrq:file rw_file_perms;
+
+# Read /proc/stat for CPU usage statistics
+allow system_server proc_stat:file r_file_perms;
+
+# Read /sys/kernel/debug/wakeup_sources.
+allow system_server debugfs:file r_file_perms;
+
+# The DhcpClient and WifiWatchdog use packet_sockets
+allow system_server self:packet_socket create_socket_perms;
+
+# NetworkDiagnostics requires explicit bind() calls to ping sockets. These aren't actually the same
+# as raw sockets, but the kernel doesn't yet distinguish between the two.
+allow system_server node:rawip_socket node_bind;
+
+# 3rd party VPN clients require a tun_socket to be created
+allow system_server self:tun_socket create_socket_perms;
+
+# Talk to init and various daemons via sockets.
+unix_socket_connect(system_server, installd, installd)
+unix_socket_connect(system_server, lmkd, lmkd)
+unix_socket_connect(system_server, mtpd, mtp)
+unix_socket_connect(system_server, netd, netd)
+unix_socket_connect(system_server, vold, vold)
+unix_socket_connect(system_server, zygote, zygote)
+unix_socket_connect(system_server, racoon, racoon)
+unix_socket_send(system_server, wpa, wpa)
+
+# Communicate over a socket created by surfaceflinger.
+allow system_server surfaceflinger:unix_stream_socket { read write setopt };
+
+# Perform Binder IPC.
+binder_use(system_server)
+binder_call(system_server, binderservicedomain)
+binder_call(system_server, gatekeeperd)
+binder_call(system_server, fingerprintd)
+binder_call(system_server, appdomain)
+binder_call(system_server, dumpstate)
+binder_service(system_server)
+
+# Ask debuggerd to dump backtraces for native stacks of interest.
+allow system_server { mediaserver sdcardd surfaceflinger inputflinger }:debuggerd dump_backtrace;
+
+# Read /proc/pid files for dumping stack traces of native processes.
+r_dir_file(system_server, mediaserver)
+r_dir_file(system_server, sdcardd)
+r_dir_file(system_server, surfaceflinger)
+r_dir_file(system_server, inputflinger)
+
+# Use sockets received over binder from various services.
+allow system_server mediaserver:tcp_socket rw_socket_perms;
+allow system_server mediaserver:udp_socket rw_socket_perms;
+
+# Check SELinux permissions.
+selinux_check_access(system_server)
+
+# XXX Label sysfs files with a specific type?
+allow system_server sysfs:file rw_file_perms;
+allow system_server sysfs_nfc_power_writable:file rw_file_perms;
+allow system_server sysfs_devices_system_cpu:file w_file_perms;
+allow system_server sysfs_mac_address:file r_file_perms;
+allow system_server sysfs_thermal:dir search;
+allow system_server sysfs_thermal:file r_file_perms;
+
+# Access devices.
+allow system_server device:dir r_dir_perms;
+allow system_server mdns_socket:sock_file rw_file_perms;
+allow system_server alarm_device:chr_file rw_file_perms;
+allow system_server gpu_device:chr_file rw_file_perms;
+allow system_server iio_device:chr_file rw_file_perms;
+allow system_server input_device:dir r_dir_perms;
+allow system_server input_device:chr_file rw_file_perms;
+allow system_server radio_device:chr_file r_file_perms;
+allow system_server tty_device:chr_file rw_file_perms;
+allow system_server usbaccessory_device:chr_file rw_file_perms;
+allow system_server video_device:dir r_dir_perms;
+allow system_server video_device:chr_file rw_file_perms;
+allow system_server adbd_socket:sock_file rw_file_perms;
+allow system_server rtc_device:chr_file rw_file_perms;
+allow system_server audio_device:dir r_dir_perms;
+
+# write access needed for MIDI
+allow system_server audio_device:chr_file rw_file_perms;
+
+# tun device used for 3rd party vpn apps
+allow system_server tun_device:chr_file rw_file_perms;
+
+# Manage system data files.
+allow system_server system_data_file:dir create_dir_perms;
+allow system_server system_data_file:notdevfile_class_set create_file_perms;
+allow system_server keychain_data_file:dir create_dir_perms;
+allow system_server keychain_data_file:file create_file_perms;
+allow system_server keychain_data_file:lnk_file create_file_perms;
+
+# Manage /data/app.
+allow system_server apk_data_file:dir create_dir_perms;
+allow system_server apk_data_file:file { create_file_perms link };
+allow system_server apk_tmp_file:dir create_dir_perms;
+allow system_server apk_tmp_file:file create_file_perms;
+
+# Manage /data/app-private.
+allow system_server apk_private_data_file:dir create_dir_perms;
+allow system_server apk_private_data_file:file create_file_perms;
+allow system_server apk_private_tmp_file:dir create_dir_perms;
+allow system_server apk_private_tmp_file:file create_file_perms;
+
+# Manage files within asec containers.
+allow system_server asec_apk_file:dir create_dir_perms;
+allow system_server asec_apk_file:file create_file_perms;
+allow system_server asec_public_file:file create_file_perms;
+
+# Manage /data/anr.
+allow system_server anr_data_file:dir create_dir_perms;
+allow system_server anr_data_file:file create_file_perms;
+
+# Manage /data/backup.
+allow system_server backup_data_file:dir create_dir_perms;
+allow system_server backup_data_file:file create_file_perms;
+
+# Write to /data/system/heapdump
+allow system_server heapdump_data_file:dir rw_dir_perms;
+allow system_server heapdump_data_file:file create_file_perms;
+
+# Manage /data/misc/adb.
+allow system_server adb_keys_file:dir create_dir_perms;
+allow system_server adb_keys_file:file create_file_perms;
+
+# Manage /data/misc/sms.
+# TODO:  Split into a separate type?
+allow system_server radio_data_file:dir create_dir_perms;
+allow system_server radio_data_file:file create_file_perms;
+
+# Manage /data/misc/systemkeys.
+allow system_server systemkeys_data_file:dir create_dir_perms;
+allow system_server systemkeys_data_file:file create_file_perms;
+
+# Access /data/tombstones.
+allow system_server tombstone_data_file:dir r_dir_perms;
+allow system_server tombstone_data_file:file r_file_perms;
+
+# Manage /data/misc/vpn.
+allow system_server vpn_data_file:dir create_dir_perms;
+allow system_server vpn_data_file:file create_file_perms;
+
+# Manage /data/misc/wifi.
+allow system_server wifi_data_file:dir create_dir_perms;
+allow system_server wifi_data_file:file create_file_perms;
+
+# Manage /data/misc/zoneinfo.
+allow system_server zoneinfo_data_file:dir create_dir_perms;
+allow system_server zoneinfo_data_file:file create_file_perms;
+
+# Walk /data/data subdirectories.
+# Types extracted from seapp_contexts type= fields.
+allow system_server { system_app_data_file bluetooth_data_file nfc_data_file radio_data_file shell_data_file app_data_file }:dir { getattr read search };
+# Also permit for unlabeled /data/data subdirectories and
+# for unlabeled asec containers on upgrades from 4.2.
+allow system_server unlabeled:dir r_dir_perms;
+# Read pkg.apk file before it has been relabeled by vold.
+allow system_server unlabeled:file r_file_perms;
+
+# Populate com.android.providers.settings/databases/settings.db.
+allow system_server system_app_data_file:dir create_dir_perms;
+allow system_server system_app_data_file:file create_file_perms;
+
+# Receive and use open app data files passed over binder IPC.
+# Types extracted from seapp_contexts type= fields.
+allow system_server { system_app_data_file bluetooth_data_file nfc_data_file radio_data_file shell_data_file app_data_file }:file { getattr read write };
+
+# Receive and use open /data/media files passed over binder IPC.
+allow system_server media_rw_data_file:file { getattr read write };
+
+# Relabel apk files.
+allow system_server { apk_tmp_file apk_private_tmp_file }:{ dir file } { relabelfrom relabelto };
+allow system_server { apk_data_file apk_private_data_file }:{ dir file } { relabelfrom relabelto };
+
+# Relabel wallpaper.
+allow system_server system_data_file:file relabelfrom;
+allow system_server wallpaper_file:file relabelto;
+allow system_server wallpaper_file:file { rw_file_perms unlink };
+
+# FingerprintService.java does a restorecon of the directory /data/system/users/[0-9]+/fpdata(/.*)?
+allow system_server system_data_file:dir relabelfrom;
+
+# Property Service write
+set_prop(system_server, system_prop)
+set_prop(system_server, safemode_prop)
+set_prop(system_server, dhcp_prop)
+set_prop(system_server, net_radio_prop)
+set_prop(system_server, system_radio_prop)
+set_prop(system_server, debug_prop)
+set_prop(system_server, powerctl_prop)
+set_prop(system_server, fingerprint_prop)
+set_prop(system_server, device_logging_prop)
+
+# ctl interface
+set_prop(system_server, ctl_default_prop)
+set_prop(system_server, ctl_dhcp_pan_prop)
+set_prop(system_server, ctl_bugreport_prop)
+
+# Create a socket for receiving info from wpa.
+type_transition system_server wifi_data_file:sock_file system_wpa_socket;
+type_transition system_server wpa_socket:sock_file system_wpa_socket;
+allow system_server wpa_socket:dir rw_dir_perms;
+allow system_server system_wpa_socket:sock_file create_file_perms;
+
+# Remove sockets created by wpa_supplicant
+allow system_server wpa_socket:sock_file unlink;
+
+# Create a socket for connections from debuggerd.
+type_transition system_server system_data_file:sock_file system_ndebug_socket "ndebugsocket";
+allow system_server system_ndebug_socket:sock_file create_file_perms;
+
+# Manage cache files.
+allow system_server { cache_file cache_recovery_file }:dir { relabelfrom create_dir_perms };
+allow system_server { cache_file cache_recovery_file }:file { relabelfrom create_file_perms };
+allow system_server { cache_file cache_recovery_file }:fifo_file create_file_perms;
+
+# Run system programs, e.g. dexopt. Needed? (b/28035297)
+allow system_server system_file:file x_file_perms;
+auditallow system_server system_file:file execute_no_trans;
+
+# LocationManager(e.g, GPS) needs to read and write
+# to uart driver and ctrl proc entry
+allow system_server gps_control:file rw_file_perms;
+
+# 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 unix_stream_socket } { getattr read write };
+
+# Allow abstract socket connection
+allow system_server rild:unix_stream_socket connectto;
+
+# BackupManagerService lets PMS create a data backup file
+allow system_server cache_backup_file:file create_file_perms;
+# Relabel /data/backup
+allow system_server backup_data_file:dir { relabelto relabelfrom };
+# Relabel /cache/.*\.{data|restore}
+allow system_server cache_backup_file:file { relabelto relabelfrom };
+# LocalTransport creates and relabels /cache/backup
+allow system_server cache_backup_file:dir { relabelto relabelfrom create_dir_perms };
+
+# Allow system to talk to usb device
+allow system_server usb_device:chr_file rw_file_perms;
+allow system_server usb_device:dir r_dir_perms;
+
+# Allow system to talk to sensors
+allow system_server sensors_device:chr_file rw_file_perms;
+
+# Read from HW RNG (needed by EntropyMixer).
+allow system_server hw_random_device:chr_file r_file_perms;
+
+# Read and delete files under /dev/fscklogs.
+r_dir_file(system_server, fscklogs)
+allow system_server fscklogs:dir { write remove_name };
+allow system_server fscklogs:file unlink;
+
+# logd access, system_server inherit logd write socket
+# (urge is to deprecate this long term)
+allow system_server zygote:unix_dgram_socket write;
+
+# Read from log daemon.
+read_logd(system_server)
+
+# Be consistent with DAC permissions. Allow system_server to write to
+# /sys/module/lowmemorykiller/parameters/adj
+# /sys/module/lowmemorykiller/parameters/minfree
+allow system_server sysfs_lowmemorykiller:file { getattr w_file_perms };
+
+# Read /sys/fs/pstore/console-ramoops
+# Don't worry about overly broad permissions for now, as there's
+# only one file in /sys/fs/pstore
+allow system_server pstorefs:dir r_dir_perms;
+allow system_server pstorefs:file r_file_perms;
+
+# /sys access
+allow system_server sysfs_zram:dir search;
+allow system_server sysfs_zram:file r_file_perms;
+
+allow system_server drmserver_service:service_manager find;
+allow system_server batteryproperties_service:service_manager find;
+allow system_server keystore_service:service_manager find;
+allow system_server gatekeeper_service:service_manager find;
+allow system_server fingerprintd_service:service_manager find;
+allow system_server mediaserver_service:service_manager find;
+allow system_server nfc_service:service_manager find;
+allow system_server radio_service:service_manager find;
+allow system_server system_server_service:service_manager { add find };
+allow system_server surfaceflinger_service:service_manager find;
+
+allow system_server keystore:keystore_key {
+	get_state
+	get
+	insert
+	delete
+	exist
+	list
+	reset
+	password
+	lock
+	unlock
+	is_empty
+	sign
+	verify
+	grant
+	duplicate
+	clear_uid
+	add_auth
+	user_changed
+};
+
+# Allow system server to search and write to the persistent factory reset
+# protection partition. This block device does not get wiped in a factory reset.
+allow system_server block_device:dir search;
+allow system_server frp_block_device:blk_file rw_file_perms;
+
+# Clean up old cgroups
+allow system_server cgroup:dir { remove_name rmdir };
+
+# /oem access
+r_dir_file(system_server, oemfs)
+
+# Allow resolving per-user storage symlinks
+allow system_server { mnt_user_file storage_file }:dir { getattr search };
+allow system_server { mnt_user_file storage_file }:lnk_file { getattr read };
+
+# Allow statfs() on storage devices, which happens fast enough that
+# we shouldn't be killed during unsafe removal
+allow system_server sdcard_type:dir { getattr search };
+
+# Traverse into expanded storage
+allow system_server mnt_expand_file:dir r_dir_perms;
+
+# Allow system process to relabel the fingerprint directory after mkdir
+# and delete the directory and files when no longer needed
+allow system_server fingerprintd_data_file:dir { r_dir_perms remove_name rmdir relabelto write };
+allow system_server fingerprintd_data_file:file { getattr unlink };
+
+userdebug_or_eng(`
+  # Allow system server to create and write method traces in /data/misc/trace.
+  allow system_server method_trace_data_file:dir w_dir_perms;
+  allow system_server method_trace_data_file:file { create w_file_perms };
+')
+
+# For AppFuse.
+allow system_server vold:fd use;
+allow system_server fuse_device:chr_file { read write ioctl getattr };
+
+# For configuring sdcardfs
+allow system_server configfs:dir { create_dir_perms };
+allow system_server configfs:file { getattr open unlink write };
+
+# Connect to adbd and use a socket transferred from it.
+# Used for e.g. jdwp.
+allow system_server adbd:unix_stream_socket connectto;
+allow system_server adbd:fd use;
+allow system_server adbd:unix_stream_socket { getattr getopt ioctl read write shutdown };
+
+###
+### Neverallow rules
+###
+### system_server should NEVER do any of this
+
+# Do not allow opening files from external storage as unsafe ejection
+# could cause the kernel to kill the system_server.
+neverallow system_server sdcard_type:dir { open read write };
+neverallow system_server sdcard_type:file rw_file_perms;
+
+# system server should never be operating on zygote spawned app data
+# files directly. Rather, they should always be passed via a
+# file descriptor.
+# Types extracted from seapp_contexts type= fields, excluding
+# those types that system_server needs to open directly.
+neverallow system_server { bluetooth_data_file nfc_data_file shell_data_file app_data_file }:file { open create unlink link };
+
+# Forking and execing is inherently dangerous and racy. See, for
+# example, https://www.linuxprogrammingblog.com/threads-and-fork-think-twice-before-using-them
+# Prevent the addition of new file execs to stop the problem from
+# getting worse. b/28035297
+neverallow system_server { file_type -toolbox_exec -logcat_exec -system_file }:file execute_no_trans;
+
+# System server should never transition to a new domain. This compliments
+# and enforces the already pre-existing PR_SET_NO_NEW_PRIVS flag.
+neverallow system_server *:process { transition dyntransition };
+
+# system_server should never be executing dex2oat. This is either
+# a bug (for example, bug 16317188), or represents an attempt by
+# 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;
+
+# system_server should never execute or load executable shared libraries
+# in /data except for /data/dalvik-cache files.
+neverallow system_server {
+  data_file_type
+  -dalvikcache_data_file #mapping with PROT_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;
+
+# system_server should never use JIT functionality
+neverallow system_server self:process execmem;
+neverallow system_server ashmem_device:chr_file execute;
+neverallow system_server system_server_tmpfs:file execute;
diff --git a/sepolicy/te_macros b/sepolicy/te_macros
new file mode 100644
index 0000000..ec97b3f
--- /dev/null
+++ b/sepolicy/te_macros
@@ -0,0 +1,322 @@
+#####################################
+# domain_trans(olddomain, type, newdomain)
+# Allow a transition from olddomain to newdomain
+# upon executing a file labeled with type.
+# This only allows the transition; it does not
+# cause it to occur automatically - use domain_auto_trans
+# if that is what you want.
+#
+define(`domain_trans', `
+# Old domain may exec the file and transition to the new domain.
+allow $1 $2:file { getattr open read execute };
+allow $1 $3:process transition;
+# New domain is entered by executing the file.
+allow $3 $2:file { entrypoint open read execute getattr };
+# New domain can send SIGCHLD to its caller.
+ifelse($1, `init', `', `allow $3 $1:process sigchld;')
+# Enable AT_SECURE, i.e. libc secure mode.
+dontaudit $1 $3:process noatsecure;
+# XXX dontaudit candidate but requires further study.
+allow $1 $3:process { siginh rlimitinh };
+')
+
+#####################################
+# domain_auto_trans(olddomain, type, newdomain)
+# Automatically transition from olddomain to newdomain
+# upon executing a file labeled with type.
+#
+define(`domain_auto_trans', `
+# Allow the necessary permissions.
+domain_trans($1,$2,$3)
+# Make the transition occur by default.
+type_transition $1 $2:process $3;
+')
+
+#####################################
+# file_type_trans(domain, dir_type, file_type)
+# Allow domain to create a file labeled file_type in a
+# directory labeled dir_type.
+# This only allows the transition; it does not
+# cause it to occur automatically - use file_type_auto_trans
+# if that is what you want.
+#
+define(`file_type_trans', `
+# Allow the domain to add entries to the directory.
+allow $1 $2:dir ra_dir_perms;
+# Allow the domain to create the file.
+allow $1 $3:notdevfile_class_set create_file_perms;
+allow $1 $3:dir create_dir_perms;
+')
+
+#####################################
+# file_type_auto_trans(domain, dir_type, file_type)
+# Automatically label new files with file_type when
+# they are created by domain in directories labeled dir_type.
+#
+define(`file_type_auto_trans', `
+# Allow the necessary permissions.
+file_type_trans($1, $2, $3)
+# Make the transition occur by default.
+type_transition $1 $2:dir $3;
+type_transition $1 $2:notdevfile_class_set $3;
+')
+
+#####################################
+# r_dir_file(domain, type)
+# Allow the specified domain to read directories, files
+# and symbolic links of the specified type.
+define(`r_dir_file', `
+allow $1 $2:dir r_dir_perms;
+allow $1 $2:{ file lnk_file } r_file_perms;
+')
+
+#####################################
+# tmpfs_domain(domain)
+# Define and allow access to a unique type for
+# this domain when creating tmpfs / shmem / ashmem files.
+define(`tmpfs_domain', `
+type $1_tmpfs, file_type;
+type_transition $1 tmpfs:file $1_tmpfs;
+allow $1 $1_tmpfs:file { read write };
+')
+
+#####################################
+# init_daemon_domain(domain)
+# Set up a transition from init to the daemon domain
+# upon executing its binary.
+define(`init_daemon_domain', `
+domain_auto_trans(init, $1_exec, $1)
+tmpfs_domain($1)
+')
+
+#####################################
+# app_domain(domain)
+# Allow a base set of permissions required for all apps.
+define(`app_domain', `
+typeattribute $1 appdomain;
+# Label ashmem objects with our own unique type.
+tmpfs_domain($1)
+# Map with PROT_EXEC.
+allow $1 $1_tmpfs:file execute;
+')
+
+#####################################
+# net_domain(domain)
+# Allow a base set of permissions required for network access.
+define(`net_domain', `
+typeattribute $1 netdomain;
+')
+
+#####################################
+# bluetooth_domain(domain)
+# Allow a base set of permissions required for bluetooth access.
+define(`bluetooth_domain', `
+typeattribute $1 bluetoothdomain;
+')
+
+#####################################
+# unix_socket_connect(clientdomain, socket, serverdomain)
+# Allow a local socket connection from clientdomain via
+# socket to serverdomain.
+#
+# Note: If you see denial records that distill to the
+# following allow rules:
+# allow clientdomain property_socket:sock_file write;
+# allow clientdomain init:unix_stream_socket connectto;
+# allow clientdomain something_prop:property_service set;
+#
+# This sequence is indicative of attempting to set a property.
+# use set_prop(sourcedomain, targetproperty)
+#
+define(`unix_socket_connect', `
+ifelse($2, `property', `
+    ifelse($3,`init', `
+       print(`deprecated: unix_socket_connect($1, $2, $3) Please use set_prop($1, <property name>) instead.')
+   ')
+')
+__unix_socket_connect__($1, $2, $3)
+')
+
+define(`__unix_socket_connect__', `
+allow $1 $2_socket:sock_file write;
+allow $1 $3:unix_stream_socket connectto;
+')
+
+#####################################
+# set_prop(sourcedomain, targetproperty)
+# Allows source domain to set the
+# targetproperty.
+#
+define(`set_prop', `
+__unix_socket_connect__($1, property, init)
+allow $1 $2:property_service set;
+get_prop($1, $2)
+')
+
+#####################################
+# get_prop(sourcedomain, targetproperty)
+# Allows source domain to read the
+# targetproperty.
+#
+define(`get_prop', `
+allow $1 $2:file r_file_perms;
+')
+
+#####################################
+# unix_socket_send(clientdomain, socket, serverdomain)
+# Allow a local socket send from clientdomain via
+# socket to serverdomain.
+define(`unix_socket_send', `
+allow $1 $2_socket:sock_file write;
+allow $1 $3:unix_dgram_socket sendto;
+')
+
+#####################################
+# binder_use(domain)
+# Allow domain to use Binder IPC.
+define(`binder_use', `
+# Call the servicemanager and transfer references to it.
+allow $1 servicemanager:binder { call transfer };
+# servicemanager performs getpidcon on clients.
+allow servicemanager $1:dir search;
+allow servicemanager $1:file { read open };
+allow servicemanager $1:process getattr;
+# rw access to /dev/binder and /dev/ashmem is presently granted to
+# all domains in domain.te.
+')
+
+#####################################
+# binder_call(clientdomain, serverdomain)
+# Allow clientdomain to perform binder IPC to serverdomain.
+define(`binder_call', `
+# Call the server domain and optionally transfer references to it.
+allow $1 $2:binder { call transfer };
+# Allow the serverdomain to transfer references to the client on the reply.
+allow $2 $1:binder transfer;
+# Receive and use open files from the server.
+allow $1 $2:fd use;
+')
+
+#####################################
+# binder_service(domain)
+# Mark a domain as being a Binder service domain.
+# Used to allow binder IPC to the various system services.
+define(`binder_service', `
+typeattribute $1 binderservicedomain;
+')
+
+#####################################
+# wakelock_use(domain)
+# Allow domain to manage wake locks
+define(`wakelock_use', `
+# Access /sys/power/wake_lock and /sys/power/wake_unlock
+allow $1 sysfs_wake_lock:file rw_file_perms;
+# Accessing these files requires CAP_BLOCK_SUSPEND
+allow $1 self:capability2 block_suspend;
+')
+
+#####################################
+# selinux_check_access(domain)
+# Allow domain to check SELinux permissions via selinuxfs.
+define(`selinux_check_access', `
+allow $1 selinuxfs:file rw_file_perms;
+allow $1 kernel:security compute_av;
+allow $1 self:netlink_selinux_socket *;
+')
+
+#####################################
+# selinux_check_context(domain)
+# Allow domain to check SELinux contexts via selinuxfs.
+define(`selinux_check_context', `
+allow $1 selinuxfs:file rw_file_perms;
+allow $1 kernel:security check_context;
+')
+
+#####################################
+# create_pty(domain)
+# Allow domain to create and use a pty, isolated from any other domain ptys.
+define(`create_pty', `
+# Each domain gets a unique devpts type.
+type $1_devpts, fs_type;
+# Label the pty with the unique type when created.
+type_transition $1 devpts:chr_file $1_devpts;
+# Allow use of the pty after creation.
+allow $1 $1_devpts:chr_file { open getattr read write ioctl };
+# Note: devpts:dir search and ptmx_device:chr_file rw_file_perms
+# allowed to everyone via domain.te.
+')
+
+#####################################
+# Non system_app application set
+#
+define(`non_system_app_set', `{ appdomain -system_app }')
+
+#####################################
+# Recovery only
+# SELinux rules which apply only to recovery mode
+#
+define(`recovery_only', ifelse(target_recovery, `true', $1, ))
+
+#####################################
+# Userdebug or eng builds
+# 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)))
+define(`eng', ifelse(target_build_variant, `eng', $1))
+
+#####################################
+# write_logd(domain)
+# Ability to write to android log
+# daemon via sockets
+define(`write_logd', `
+unix_socket_send($1, logdw, logd)
+allow $1 pmsg_device:chr_file w_file_perms;
+')
+
+#####################################
+# read_logd(domain)
+# Ability to run logcat and read from android
+# log daemon via sockets
+define(`read_logd', `
+allow $1 logcat_exec:file rx_file_perms;
+unix_socket_connect($1, logdr, logd)
+')
+
+#####################################
+# control_logd(domain)
+# Ability to control
+# android log daemon via sockets
+define(`control_logd', `
+# Group AID_LOG checked by filesystem & logd
+# to permit control commands
+unix_socket_connect($1, logd, logd)
+')
+
+#####################################
+# use_keystore(domain)
+# Ability to use keystore.
+# Keystore is requires the following permissions
+# to call getpidcon.
+define(`use_keystore', `
+  allow keystore $1:dir search;
+  allow keystore $1:file { read open };
+  allow keystore $1:process getattr;
+  allow $1 keystore_service:service_manager find;
+  binder_call($1, keystore)
+')
+
+###########################################
+# use_drmservice(domain)
+# Ability to use DrmService which requires
+# DrmService to call getpidcon.
+define(`use_drmservice', `
+  allow drmserver $1:dir search;
+  allow drmserver $1:file { read open };
+  allow drmserver $1:process getattr;
+')
+
+##########################################
+# print a message with a trailing newline
+# print(`args')
+define(`print', `errprint(`m4: '__file__: __line__`: $*
+')')
diff --git a/sepolicy/tee.te b/sepolicy/tee.te
new file mode 100644
index 0000000..8ea6b95
--- /dev/null
+++ b/sepolicy/tee.te
@@ -0,0 +1,15 @@
+##
+# trusted execution environment (tee) daemon
+#
+type tee, domain, domain_deprecated;
+type tee_exec, exec_type, file_type;
+type tee_device, dev_type;
+type tee_data_file, file_type, data_file_type;
+
+init_daemon_domain(tee)
+allow tee self:capability { dac_override };
+allow tee tee_device:chr_file rw_file_perms;
+allow tee tee_data_file:dir rw_dir_perms;
+allow tee tee_data_file:file create_file_perms;
+allow tee self:netlink_socket create_socket_perms;
+allow tee self:netlink_generic_socket create_socket_perms;
diff --git a/sepolicy/toolbox.te b/sepolicy/toolbox.te
new file mode 100644
index 0000000..55de7eb
--- /dev/null
+++ b/sepolicy/toolbox.te
@@ -0,0 +1,26 @@
+# Any toolbox command run by init.
+# At present, the only known usage is for running mkswap via fs_mgr.
+# Do NOT use this domain for toolbox when run by any other domain.
+type toolbox, domain, domain_deprecated;
+type toolbox_exec, exec_type, file_type;
+
+init_daemon_domain(toolbox)
+
+# /dev/__null__ created by init prior to policy load,
+# open fd inherited by fsck.
+allow toolbox tmpfs:chr_file { read write ioctl };
+
+# Inherit and use pty created by android_fork_execvp_ext().
+allow toolbox devpts:chr_file { read write getattr ioctl };
+
+# mkswap-specific.
+# Read/write block devices used for swap partitions.
+# Assign swap_block_device type any such partition in your
+# device/<vendor>/<product>/sepolicy/file_contexts file.
+allow toolbox block_device:dir search;
+allow toolbox swap_block_device:blk_file rw_file_perms;
+
+# Only allow entry from init via the toolbox binary.
+neverallow { domain -init } toolbox:process transition;
+neverallow * toolbox:process dyntransition;
+neverallow toolbox { file_type fs_type -toolbox_exec}:file entrypoint;
diff --git a/sepolicy/tools/Android.mk b/sepolicy/tools/Android.mk
new file mode 100644
index 0000000..7ded3a3
--- /dev/null
+++ b/sepolicy/tools/Android.mk
@@ -0,0 +1,54 @@
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := checkseapp
+LOCAL_MODULE_TAGS := optional
+LOCAL_C_INCLUDES := \
+		external/selinux/libsepol/include
+LOCAL_CFLAGS := -DLINK_SEPOL_STATIC -Wall -Werror
+LOCAL_SRC_FILES := check_seapp.c
+LOCAL_STATIC_LIBRARIES := libsepol
+LOCAL_WHOLE_STATIC_LIBRARIES := libpcre2
+LOCAL_CXX_STL := none
+
+include $(BUILD_HOST_EXECUTABLE)
+
+###################################
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := checkfc
+LOCAL_MODULE_TAGS := optional
+LOCAL_C_INCLUDES := external/selinux/libsepol/include \
+                    external/libselinux/include
+LOCAL_CFLAGS := -Wall -Werror
+LOCAL_SRC_FILES := checkfc.c
+LOCAL_STATIC_LIBRARIES := libsepol libselinux
+LOCAL_CXX_STL := none
+
+include $(BUILD_HOST_EXECUTABLE)
+
+##################################
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := insertkeys.py
+LOCAL_SRC_FILES := insertkeys.py
+LOCAL_MODULE_CLASS := EXECUTABLES
+LOCAL_IS_HOST_MODULE := true
+LOCAL_MODULE_TAGS := optional
+
+include $(BUILD_PREBUILT)
+###################################
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := sepolicy-check
+LOCAL_MODULE_TAGS := optional
+LOCAL_C_INCLUDES := external/selinux/libsepol/include
+LOCAL_CFLAGS := -Wall -Werror
+LOCAL_SRC_FILES := sepolicy-check.c
+LOCAL_STATIC_LIBRARIES := libsepol
+LOCAL_CXX_STL := none
+
+include $(BUILD_HOST_EXECUTABLE)
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/sepolicy/tools/README b/sepolicy/tools/README
new file mode 100644
index 0000000..6035c03
--- /dev/null
+++ b/sepolicy/tools/README
@@ -0,0 +1,63 @@
+This directory contains a number of tools related to policy, some of
+which are used in building and validating the policy and others are
+available for help in auditing and analyzing policy.  The tools are
+described further below.
+
+checkfc
+   A utility for checking the validity of a file_contexts or a
+   property_contexts configuration file.  Used as part of the policy
+   build to validate both files.  Requires the sepolicy file as an
+   argument in order to check the validity of the security contexts
+   in the file_contexts or property_contexts file.
+
+   Usage1:
+   checkfc sepolicy file_contexts
+   checkfc -p sepolicy property_contexts
+
+   Also used to compare two file_contexts or file_contexts.bin files.
+   Displays one of subset, equal, superset, or incomparable.
+
+   Usage2:
+   checkfc -c file_contexts1 file_contexts2
+
+   Example:
+   $ checkfc -c out/target/product/shamu/system/etc/general_file_contexts out/target/product/shamu/root/file_contexts.bin
+   subset
+
+checkseapp
+    A utility for merging together the main seapp_contexts
+    configuration and the device-specific one, and simultaneously
+    checking the validity of the configurations. Used as part of the
+    policy build process to merge and validate the configuration.
+
+    Usage:
+    checkseapp -p sepolicy input_seapp_contexts0 [input_seapp_contexts1...] -o seapp_contexts
+
+insertkeys.py
+    A helper script for mapping tags in the signature stanzas of
+    mac_permissions.xml to public keys found in pem files.  This
+    script is described further in the top-level sepolicy/README.
+
+post_process_mac_perms
+    A tool to help modify an existing mac_permissions.xml with additional app
+    certs not already found in that policy. This becomes useful when a directory
+    containing apps is searched and the certs from those apps are added to the
+    policy not already explicitly listed.
+
+    Usage:
+    post_process_mac_perms [-h] -s SEINFO -d DIR -f POLICY
+
+      -s SEINFO, --seinfo SEINFO  seinfo tag for each generated stanza
+      -d DIR, --dir DIR           Directory to search for apks
+      -f POLICY, --file POLICY    mac_permissions.xml policy file
+
+sepolicy-check
+    A tool for auditing a sepolicy file for any allow rule that grants
+    a given permission.
+
+    Usage:
+    sepolicy-check -s <domain> -t <type> -c <class> -p <permission> -P out/target/product/<board>/root/sepolicy
+
+sepolicy-analyze
+    A tool for performing various kinds of analysis on a sepolicy
+    file.
diff --git a/sepolicy/tools/check_seapp.c b/sepolicy/tools/check_seapp.c
new file mode 100644
index 0000000..26a47b5
--- /dev/null
+++ b/sepolicy/tools/check_seapp.c
@@ -0,0 +1,1252 @@
+#include <stdio.h>
+#include <stdarg.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <stdint.h>
+#include <search.h>
+#include <stdbool.h>
+#include <sepol/sepol.h>
+#include <sepol/policydb/policydb.h>
+#include <pcre2.h>
+
+#define TABLE_SIZE 1024
+#define KVP_NUM_OF_RULES (sizeof(rules) / sizeof(key_map))
+#define log_set_verbose() do { logging_verbose = 1; log_info("Enabling verbose\n"); } while(0)
+#define log_error(fmt, ...) log_msg(stderr, "Error: ", fmt, ##__VA_ARGS__)
+#define log_warn(fmt, ...) log_msg(stderr, "Warning: ", fmt, ##__VA_ARGS__)
+#define log_info(fmt, ...) if (logging_verbose ) { log_msg(stdout, "Info: ", fmt, ##__VA_ARGS__); }
+
+/**
+ * Initializes an empty, static list.
+ */
+#define list_init(free_fn) { .head = NULL, .tail = NULL, .freefn = (free_fn) }
+
+/**
+ * given an item in the list, finds the offset for the container
+ * it was stored in.
+ *
+ * @element The element from the list
+ * @type The container type ie what you allocated that has the list_element structure in it.
+ * @name The name of the field that is the list_element
+ *
+ */
+#define list_entry(element, type, name) \
+		(type *)(((uint8_t *)(element)) - (uint8_t *)&(((type *)NULL)->name))
+
+/**
+ * Iterates over the list, do not free elements from the list when using this.
+ * @list The list head to walk
+ * @var The variable name for the cursor
+ */
+#define list_for_each(list, var) \
+	for(var = (list)->head; var != NULL; var = var->next) /*NOLINT*/
+
+
+typedef struct hash_entry hash_entry;
+typedef enum key_dir key_dir;
+typedef enum data_type data_type;
+typedef enum rule_map_switch rule_map_switch;
+typedef enum map_match map_match;
+typedef struct key_map key_map;
+typedef struct kvp kvp;
+typedef struct rule_map rule_map;
+typedef struct policy_info policy_info;
+typedef struct list_element list_element;
+typedef struct list list;
+typedef struct key_map_regex key_map_regex;
+typedef struct file_info file_info;
+
+enum map_match {
+	map_no_matches,
+	map_input_matched,
+	map_matched
+};
+
+const char *map_match_str[] = {
+	"do not match",
+	"match on all inputs",
+	"match on everything"
+};
+
+/**
+ * Whether or not the "key" from a key vaue pair is considered an
+ * input or an output.
+ */
+enum key_dir {
+	dir_in, dir_out
+};
+
+struct list_element {
+	list_element *next;
+};
+
+struct list {
+	list_element *head;
+	list_element *tail;
+	void (*freefn)(list_element *e);
+};
+
+struct key_map_regex {
+	pcre2_code *compiled;
+	pcre2_match_data *match_data;
+};
+
+/**
+ * The workhorse of the logic. This struct maps key value pairs to
+ * an associated set of meta data maintained in rule_map_new()
+ */
+struct key_map {
+	char *name;
+	key_dir dir;
+	char *data;
+	key_map_regex regex;
+	bool (*fn_validate)(char *value, char **errmsg);
+};
+
+/**
+ * Key value pair struct, this represents the raw kvp values coming
+ * from the rules files.
+ */
+struct kvp {
+	char *key;
+	char *value;
+};
+
+/**
+ * Rules are made up of meta data and an associated set of kvp stored in a
+ * key_map array.
+ */
+struct rule_map {
+	bool is_never_allow;
+	list violations;
+	list_element listify;
+	char *key; /** key value before hashing */
+	size_t length; /** length of the key map */
+	int lineno; /** Line number rule was encounter on */
+	char *filename; /** File it was found in */
+	key_map m[]; /** key value mapping */
+};
+
+struct hash_entry {
+	list_element listify;
+	rule_map *r; /** The rule map to store at that location */
+};
+
+/**
+ * Data associated for a policy file
+ */
+struct policy_info {
+
+	char *policy_file_name; /** policy file path name */
+	FILE *policy_file;      /** file handle to the policy file */
+	sepol_policydb_t *db;
+	sepol_policy_file_t *pf;
+	sepol_handle_t *handle;
+	sepol_context_t *con;
+};
+
+struct file_info {
+	FILE *file; /** file itself */
+	const char *name; /** name of file. do not free, these are not alloc'd */
+	list_element listify;
+};
+
+static void input_file_list_freefn(list_element *e);
+static void line_order_list_freefn(list_element *e);
+static void rule_map_free(rule_map *rm, bool is_in_htable);
+
+/** Set to !0 to enable verbose logging */
+static int logging_verbose = 0;
+
+/** file handle to the output file */
+static file_info out_file;
+
+static list input_file_list = list_init(input_file_list_freefn);
+
+static policy_info pol = {
+	.policy_file_name = NULL,
+	.policy_file = NULL,
+	.db = NULL,
+	.pf = NULL,
+	.handle = NULL,
+	.con = NULL
+};
+
+/**
+ * Head pointer to a linked list of
+ * rule map table entries (hash_entry), used for
+ * preserving the order of entries
+ * based on "first encounter"
+ */
+static list line_order_list = list_init(line_order_list_freefn);
+
+/*
+ * List of hash_entrys for never allow rules.
+ */
+static list nallow_list = list_init(line_order_list_freefn);
+
+/* validation call backs */
+static bool validate_bool(char *value, char **errmsg);
+static bool validate_levelFrom(char *value, char **errmsg);
+static bool validate_selinux_type(char *value, char **errmsg);
+static bool validate_selinux_level(char *value, char **errmsg);
+
+/**
+ * The heart of the mapping process, this must be updated if a new key value pair is added
+ * to a rule.
+ */
+key_map rules[] = {
+                /*Inputs*/
+                { .name = "isSystemServer", .dir = dir_in, .fn_validate = validate_bool },
+                { .name = "isOwner",        .dir = dir_in, .fn_validate = validate_bool },
+                { .name = "user",           .dir = dir_in,                              },
+                { .name = "seinfo",         .dir = dir_in,                              },
+                { .name = "name",           .dir = dir_in,                              },
+                { .name = "path",           .dir = dir_in,                              },
+                { .name = "isPrivApp",      .dir = dir_in, .fn_validate = validate_bool },
+                /*Outputs*/
+                { .name = "domain",         .dir = dir_out, .fn_validate = validate_selinux_type  },
+                { .name = "type",           .dir = dir_out, .fn_validate = validate_selinux_type  },
+                { .name = "levelFromUid",   .dir = dir_out, .fn_validate = validate_bool          },
+                { .name = "levelFrom",      .dir = dir_out, .fn_validate = validate_levelFrom     },
+                { .name = "level",          .dir = dir_out, .fn_validate = validate_selinux_level },
+};
+
+/**
+ * Appends to the end of the list.
+ * @list The list to append to
+ * @e the element to append
+ */
+void list_append(list *list, list_element *e) {
+
+	memset(e, 0, sizeof(*e));
+
+	if (list->head == NULL ) {
+		list->head = list->tail = e;
+		return;
+	}
+
+	list->tail->next = e;
+	list->tail = e;
+	return;
+}
+
+/**
+ * Free's all the elements in the specified list.
+ * @list The list to free
+ */
+static void list_free(list *list) {
+
+	list_element *tmp;
+	list_element *cursor = list->head;
+
+	while (cursor) {
+		tmp = cursor;
+		cursor = cursor->next;
+		if (list->freefn) {
+			list->freefn(tmp);
+		}
+	}
+}
+
+/*
+ * called when the lists are freed
+ */
+static void line_order_list_freefn(list_element *e) {
+	hash_entry *h = list_entry(e, typeof(*h), listify);
+	rule_map_free(h->r, true);
+	free(h);
+}
+
+static void input_file_list_freefn(list_element *e) {
+	file_info *f = list_entry(e, typeof(*f), listify);
+
+	if (f->file) {
+		fclose(f->file);
+	}
+	free(f);
+}
+
+/**
+ * Send a logging message to a file
+ * @param out
+ * 	Output file to send message too
+ * @param prefix
+ * 	A special prefix to write to the file, such as "Error:"
+ * @param fmt
+ * 	The printf style formatter to use, such as "%d"
+ */
+static void __attribute__ ((format(printf, 3, 4)))
+log_msg(FILE *out, const char *prefix, const char *fmt, ...) {
+
+	fprintf(out, "%s", prefix);
+	va_list args;
+	va_start(args, fmt);
+	vfprintf(out, fmt, args);
+	va_end(args);
+}
+
+/**
+ * Checks for a type in the policy.
+ * @param db
+ * 	The policy db to search
+ * @param type
+ * 	The type to search for
+ * @return
+ * 	1 if the type is found, 0 otherwise.
+ * @warning
+ * 	This function always returns 1 if libsepol is not linked
+ * 	statically to this executable and LINK_SEPOL_STATIC is not
+ * 	defined.
+ */
+static int check_type(sepol_policydb_t *db, char *type) {
+
+	int rc = 1;
+#if defined(LINK_SEPOL_STATIC)
+	policydb_t *d = (policydb_t *)db;
+	hashtab_datum_t dat;
+	dat = hashtab_search(d->p_types.table, type);
+	rc = (dat == NULL) ? 0 : 1;
+#endif
+	return rc;
+}
+
+static bool match_regex(key_map *assert, const key_map *check) {
+
+	char *tomatch = check->data;
+
+	int ret = pcre2_match(assert->regex.compiled, (PCRE2_SPTR) tomatch,
+				PCRE2_ZERO_TERMINATED, 0, 0,
+				assert->regex.match_data, NULL);
+
+	/* ret > 0 from pcre2_match means matched */
+	return ret > 0;
+}
+
+static bool compile_regex(key_map *km, int *errcode, PCRE2_SIZE *erroff) {
+
+	size_t size;
+	char *anchored;
+
+	/*
+	 * Explicitly anchor all regex's
+	 * The size is the length of the string to anchor (km->data), the anchor
+	 * characters ^ and $ and the null byte. Hence strlen(km->data) + 3
+	 */
+	size = strlen(km->data) + 3;
+	anchored = alloca(size);
+	sprintf(anchored, "^%s$", km->data);
+
+	km->regex.compiled = pcre2_compile((PCRE2_SPTR) anchored,
+						PCRE2_ZERO_TERMINATED,
+						PCRE2_DOTALL,
+						errcode, erroff,
+						NULL);
+	if (!km->regex.compiled) {
+		return false;
+	}
+
+	km->regex.match_data = pcre2_match_data_create_from_pattern(
+			km->regex.compiled, NULL);
+	if (!km->regex.match_data) {
+		pcre2_code_free(km->regex.compiled);
+		return false;
+	}
+	return true;
+}
+
+static bool validate_bool(char *value, char **errmsg) {
+
+	if (!strcmp("true", value) || !strcmp("false", value)) {
+		return true;
+	}
+
+	*errmsg = "Expecting \"true\" or \"false\"";
+	return false;
+}
+
+static bool validate_levelFrom(char *value, char **errmsg) {
+
+	if(strcasecmp(value, "none") && strcasecmp(value, "all") &&
+		strcasecmp(value, "app") && strcasecmp(value, "user")) {
+		*errmsg = "Expecting one of: \"none\", \"all\", \"app\" or \"user\"";
+		return false;
+	}
+	return true;
+}
+
+static bool validate_selinux_type(char *value, char **errmsg) {
+
+	/*
+	 * No policy file present means we cannot check
+	 * SE Linux types
+	 */
+	if (!pol.policy_file) {
+		return true;
+	}
+
+	if(!check_type(pol.db, value)) {
+		*errmsg = "Expecting a valid SELinux type";
+		return false;
+	}
+
+	return true;
+}
+
+static bool validate_selinux_level(char *value, char **errmsg) {
+
+	/*
+	 * No policy file present means we cannot check
+	 * SE Linux MLS
+	 */
+	if (!pol.policy_file) {
+		return true;
+	}
+
+	int ret = sepol_mls_check(pol.handle, pol.db, value);
+	if (ret < 0) {
+		*errmsg = "Expecting a valid SELinux MLS value";
+		return false;
+	}
+
+	return true;
+}
+
+/**
+ * Validates a key_map against a set of enforcement rules, this
+ * function exits the application on a type that cannot be properly
+ * checked
+ *
+ * @param m
+ * 	The key map to check
+ * @param lineno
+ * 	The line number in the source file for the corresponding key map
+ * @return
+ * 	true if valid, false if invalid
+ */
+static bool key_map_validate(key_map *m, const char *filename, int lineno,
+		bool is_neverallow) {
+
+	PCRE2_SIZE erroff;
+	int errcode;
+	bool rc = true;
+	char *key = m->name;
+	char *value = m->data;
+	char *errmsg = NULL;
+	char errstr[256];
+
+	log_info("Validating %s=%s\n", key, value);
+
+	/*
+	 * Neverallows are completely skipped from sanity checking so you can match
+	 * un-unspecified inputs.
+	 */
+	if (is_neverallow) {
+		if (!m->regex.compiled) {
+			rc = compile_regex(m, &errcode, &erroff);
+			if (!rc) {
+				pcre2_get_error_message(errcode,
+							(PCRE2_UCHAR*) errstr,
+							sizeof(errstr));
+				log_error("Invalid regex on line %d : %s PCRE error: %s at offset %lu",
+						lineno, value, errstr, erroff);
+			}
+		}
+		goto out;
+	}
+
+	/* If the key has a validation routine, call it */
+	if (m->fn_validate) {
+		rc = m->fn_validate(value, &errmsg);
+
+		if (!rc) {
+			log_error("Could not validate key \"%s\" for value \"%s\" on line: %d in file: \"%s\": %s\n", key, value,
+			lineno, filename, errmsg);
+		}
+	}
+
+out:
+	log_info("Key map validate returning: %d\n", rc);
+	return rc;
+}
+
+/**
+ * Prints a rule map back to a file
+ * @param fp
+ * 	The file handle to print too
+ * @param r
+ * 	The rule map to print
+ */
+static void rule_map_print(FILE *fp, rule_map *r) {
+
+	size_t i;
+	key_map *m;
+
+	for (i = 0; i < r->length; i++) {
+		m = &(r->m[i]);
+		if (i < r->length - 1)
+			fprintf(fp, "%s=%s ", m->name, m->data);
+		else
+			fprintf(fp, "%s=%s", m->name, m->data);
+	}
+}
+
+/**
+ * Compare two rule maps for equality
+ * @param rmA
+ * 	a rule map to check
+ * @param rmB
+ * 	a rule map to check
+ * @return
+ *  a map_match enum indicating the result
+ */
+static map_match rule_map_cmp(rule_map *rmA, rule_map *rmB) {
+
+	size_t i;
+	size_t j;
+	int inputs_found = 0;
+	int num_of_matched_inputs = 0;
+	int input_mode = 0;
+	size_t matches = 0;
+	key_map *mA;
+	key_map *mB;
+
+	for (i = 0; i < rmA->length; i++) {
+		mA = &(rmA->m[i]);
+
+		for (j = 0; j < rmB->length; j++) {
+			mB = &(rmB->m[j]);
+			input_mode = 0;
+
+			if (strcmp(mA->name, mB->name))
+				continue;
+
+			if (strcmp(mA->data, mB->data))
+				continue;
+
+			if (mB->dir != mA->dir)
+				continue;
+			else if (mB->dir == dir_in) {
+				input_mode = 1;
+				inputs_found++;
+			}
+
+			if (input_mode) {
+				log_info("Matched input lines: name=%s data=%s\n", mA->name, mA->data);
+				num_of_matched_inputs++;
+			}
+
+			/* Match found, move on */
+			log_info("Matched lines: name=%s data=%s", mA->name, mA->data);
+			matches++;
+			break;
+		}
+	}
+
+	/* If they all matched*/
+	if (matches == rmA->length) {
+		log_info("Rule map cmp MATCH\n");
+		return map_matched;
+	}
+
+	/* They didn't all match but the input's did */
+	else if (num_of_matched_inputs == inputs_found) {
+		log_info("Rule map cmp INPUT MATCH\n");
+		return map_input_matched;
+	}
+
+	/* They didn't all match, and the inputs didn't match, ie it didn't
+	 * match */
+	else {
+		log_info("Rule map cmp NO MATCH\n");
+		return map_no_matches;
+	}
+}
+
+/**
+ * Frees a rule map
+ * @param rm
+ * 	rule map to be freed.
+ * @is_in_htable
+ * 	True if the rule map has been added to the hash table, false
+ * 	otherwise.
+ */
+static void rule_map_free(rule_map *rm, bool is_in_htable) {
+
+	size_t i;
+	size_t len = rm->length;
+	for (i = 0; i < len; i++) {
+		key_map *m = &(rm->m[i]);
+		free(m->data);
+
+		if (m->regex.compiled) {
+			pcre2_code_free(m->regex.compiled);
+		}
+
+		if (m->regex.match_data) {
+			pcre2_match_data_free(m->regex.match_data);
+		}
+	}
+
+	/*
+	 * hdestroy() frees comparsion keys for non glibc
+	 * on GLIBC we always free on NON-GLIBC we free if
+	 * it is not in the htable.
+	 */
+	if (rm->key) {
+#ifdef __GLIBC__
+		/* silence unused warning */
+		(void)is_in_htable;
+		free(rm->key);
+#else
+		if (!is_in_htable) {
+			free(rm->key);
+		}
+#endif
+	}
+
+	free(rm->filename);
+	free(rm);
+}
+
+static void free_kvp(kvp *k) {
+	free(k->key);
+	free(k->value);
+}
+
+/**
+ * Checks a rule_map for any variation of KVP's that shouldn't be allowed.
+ * It builds an assertion failure list for each rule map.
+ * Note that this function logs all errors.
+ *
+ * Current Checks:
+ * 1. That a specified name entry should have a specified seinfo entry as well.
+ * 2. That no rule violates a neverallow
+ * @param rm
+ *  The rule map to check for validity.
+ */
+static void rule_map_validate(rule_map *rm) {
+
+	size_t i, j;
+	const key_map *rule;
+	key_map *nrule;
+	hash_entry *e;
+	rule_map *assert;
+	list_element *cursor;
+
+	list_for_each(&nallow_list, cursor) {
+		e = list_entry(cursor, typeof(*e), listify);
+		assert = e->r;
+
+		size_t cnt = 0;
+
+		for (j = 0; j < assert->length; j++) {
+			nrule = &(assert->m[j]);
+
+			// mark that nrule->name is for a null check
+			bool is_null_check = !strcmp(nrule->data, "\"\"");
+
+			for (i = 0; i < rm->length; i++) {
+				rule = &(rm->m[i]);
+
+				if (!strcmp(rule->name, nrule->name)) {
+
+					/* the name was found, (data cannot be false) then it was specified */
+					is_null_check = false;
+
+					if (match_regex(nrule, rule)) {
+						cnt++;
+					}
+				}
+			}
+
+			/*
+			 * the nrule was marked in a null check and we never found a match on nrule, thus
+			 * it matched and we update the cnt
+			 */
+			if (is_null_check) {
+				cnt++;
+			}
+		}
+		if (cnt == assert->length) {
+			list_append(&rm->violations, &assert->listify);
+		}
+	}
+}
+
+/**
+ * Given a set of key value pairs, this will construct a new rule map.
+ * On error this function calls exit.
+ * @param keys
+ * 	Keys from a rule line to map
+ * @param num_of_keys
+ * 	The length of the keys array
+ * @param lineno
+ * 	The line number the keys were extracted from
+ * @return
+ * 	A rule map pointer.
+ */
+static rule_map *rule_map_new(kvp keys[], size_t num_of_keys, int lineno,
+		const char *filename, bool is_never_allow) {
+
+	size_t i = 0, j = 0;
+	rule_map *new_map = NULL;
+	kvp *k = NULL;
+	key_map *r = NULL, *x = NULL;
+	bool seen[KVP_NUM_OF_RULES];
+
+	for (i = 0; i < KVP_NUM_OF_RULES; i++)
+		seen[i] = false;
+
+	new_map = calloc(1, (num_of_keys * sizeof(key_map)) + sizeof(rule_map));
+	if (!new_map)
+		goto oom;
+
+	new_map->is_never_allow = is_never_allow;
+	new_map->length = num_of_keys;
+	new_map->lineno = lineno;
+	new_map->filename = strdup(filename);
+	if (!new_map->filename) {
+		goto oom;
+	}
+
+	/* For all the keys in a rule line*/
+	for (i = 0; i < num_of_keys; i++) {
+		k = &(keys[i]);
+		r = &(new_map->m[i]);
+
+		for (j = 0; j < KVP_NUM_OF_RULES; j++) {
+			x = &(rules[j]);
+
+			/* Only assign key name to map name */
+			if (strcasecmp(k->key, x->name)) {
+				if (i == KVP_NUM_OF_RULES) {
+					log_error("No match for key: %s\n", k->key);
+					goto err;
+				}
+				continue;
+			}
+
+			if (seen[j]) {
+					log_error("Duplicated key: %s\n", k->key);
+					goto err;
+			}
+			seen[j] = true;
+
+			memcpy(r, x, sizeof(key_map));
+
+			/* Assign rule map value to one from file */
+			r->data = strdup(k->value);
+			if (!r->data)
+				goto oom;
+
+			/* Enforce type check*/
+			log_info("Validating keys!\n");
+			if (!key_map_validate(r, filename, lineno, new_map->is_never_allow)) {
+				log_error("Could not validate\n");
+				goto err;
+			}
+
+			/*
+			 * Only build key off of inputs with the exception of neverallows.
+			 * Neverallows are keyed off of all key value pairs,
+			 */
+			if (r->dir == dir_in || new_map->is_never_allow) {
+				char *tmp;
+				int key_len = strlen(k->key);
+				int val_len = strlen(k->value);
+				int l = (new_map->key) ? strlen(new_map->key) : 0;
+				l = l + key_len + val_len;
+				l += 1;
+
+				tmp = realloc(new_map->key, l);
+				if (!tmp)
+					goto oom;
+
+				if (!new_map->key)
+					memset(tmp, 0, l);
+
+				new_map->key = tmp;
+
+				strncat(new_map->key, k->key, key_len);
+				strncat(new_map->key, k->value, val_len);
+			}
+			break;
+		}
+		free_kvp(k);
+	}
+
+	if (new_map->key == NULL) {
+		log_error("Strange, no keys found, input file corrupt perhaps?\n");
+		goto err;
+	}
+
+	return new_map;
+
+oom:
+	log_error("Out of memory!\n");
+err:
+	if(new_map) {
+		rule_map_free(new_map, false);
+		for (; i < num_of_keys; i++) {
+			k = &(keys[i]);
+			free_kvp(k);
+		}
+	}
+	return NULL;
+}
+
+/**
+ * Print the usage of the program
+ */
+static void usage() {
+	printf(
+	        "checkseapp [options] <input file>\n"
+		        "Processes an seapp_contexts file specified by argument <input file> (default stdin) "
+		        "and allows later declarations to override previous ones on a match.\n"
+		        "Options:\n"
+		        "-h - print this help message\n"
+		        "-v - enable verbose debugging informations\n"
+		        "-p policy file - specify policy file for strict checking of output selectors against the policy\n"
+		        "-o output file - specify output file or - for stdout. No argument runs in silent mode and outputs nothing\n");
+}
+
+static void init() {
+
+	bool has_out_file;
+	list_element *cursor;
+	file_info *tmp;
+
+	/* input files if the list is empty, use stdin */
+	if (!input_file_list.head) {
+		log_info("Using stdin for input\n");
+		tmp = malloc(sizeof(*tmp));
+		if (!tmp) {
+			log_error("oom");
+			exit(EXIT_FAILURE);
+		}
+		tmp->name = "stdin";
+		tmp->file = stdin;
+		list_append(&input_file_list, &(tmp->listify));
+	}
+	else {
+		list_for_each(&input_file_list, cursor) {
+			tmp = list_entry(cursor, typeof(*tmp), listify);
+
+			log_info("Opening input file: \"%s\"\n", tmp->name);
+			tmp->file = fopen(tmp->name, "r");
+			if (!tmp->file) {
+				log_error("Could not open file: %s error: %s\n", tmp->name,
+						strerror(errno));
+				exit(EXIT_FAILURE);
+			}
+		}
+	}
+
+	has_out_file = out_file.name != NULL;
+
+	/* If output file is -, then use stdout, else open the path */
+	if (has_out_file && !strcmp(out_file.name, "-")) {
+		out_file.file = stdout;
+		out_file.name = "stdout";
+	}
+	else if (has_out_file) {
+		out_file.file = fopen(out_file.name, "w+");
+	}
+
+	if (has_out_file && !out_file.file) {
+		log_error("Could not open file: \"%s\" error: \"%s\"\n", out_file.name,
+				strerror(errno));
+		exit(EXIT_FAILURE);
+	}
+
+	if (pol.policy_file_name) {
+		log_info("Opening policy file: %s\n", pol.policy_file_name);
+		pol.policy_file = fopen(pol.policy_file_name, "rb");
+		if (!pol.policy_file) {
+			log_error("Could not open file: %s error: %s\n",
+					pol.policy_file_name, strerror(errno));
+			exit(EXIT_FAILURE);
+		}
+
+		pol.handle = sepol_handle_create();
+		if (!pol.handle) {
+			log_error("Could not create sepolicy handle: %s\n",
+					strerror(errno));
+			exit(EXIT_FAILURE);
+		}
+
+		if (sepol_policy_file_create(&pol.pf) < 0) {
+			log_error("Could not create sepolicy file: %s!\n",
+					strerror(errno));
+			exit(EXIT_FAILURE);
+		}
+
+		sepol_policy_file_set_fp(pol.pf, pol.policy_file);
+		sepol_policy_file_set_handle(pol.pf, pol.handle);
+
+		if (sepol_policydb_create(&pol.db) < 0) {
+			log_error("Could not create sepolicy db: %s!\n",
+					strerror(errno));
+			exit(EXIT_FAILURE);
+		}
+
+		if (sepol_policydb_read(pol.db, pol.pf) < 0) {
+			log_error("Could not lod policy file to db: %s!\n",
+					strerror(errno));
+			exit(EXIT_FAILURE);
+		}
+	}
+
+	list_for_each(&input_file_list, cursor) {
+		tmp = list_entry(cursor, typeof(*tmp), listify);
+		log_info("Input file set to: \"%s\"\n", tmp->name);
+	}
+
+	log_info("Policy file set to: \"%s\"\n",
+			(pol.policy_file_name == NULL) ? "None" : pol.policy_file_name);
+	log_info("Output file set to: \"%s\"\n", out_file.name);
+
+#if !defined(LINK_SEPOL_STATIC)
+	log_warn("LINK_SEPOL_STATIC is not defined\n""Not checking types!");
+#endif
+
+}
+
+/**
+ * Handle parsing and setting the global flags for the command line
+ * options. This function calls exit on failure.
+ * @param argc
+ * 	argument count
+ * @param argv
+ * 	argument list
+ */
+static void handle_options(int argc, char *argv[]) {
+
+	int c;
+	file_info *input_file;
+
+	while ((c = getopt(argc, argv, "ho:p:v")) != -1) {
+		switch (c) {
+		case 'h':
+			usage();
+			exit(EXIT_SUCCESS);
+		case 'o':
+			out_file.name = optarg;
+			break;
+		case 'p':
+			pol.policy_file_name = optarg;
+			break;
+		case 'v':
+			log_set_verbose();
+			break;
+		case '?':
+			if (optopt == 'o' || optopt == 'p')
+				log_error("Option -%c requires an argument.\n", optopt);
+			else if (isprint (optopt))
+				log_error("Unknown option `-%c'.\n", optopt);
+			else {
+				log_error(
+						"Unknown option character `\\x%x'.\n",
+						optopt);
+			}
+		default:
+			exit(EXIT_FAILURE);
+		}
+	}
+
+	for (c = optind; c < argc; c++) {
+
+		input_file = calloc(1, sizeof(*input_file));
+		if (!input_file) {
+			log_error("oom");
+			exit(EXIT_FAILURE);
+		}
+		input_file->name = argv[c];
+		list_append(&input_file_list, &input_file->listify);
+	}
+}
+
+/**
+ * Adds a rule to the hash table and to the ordered list if needed.
+ * @param rm
+ * 	The rule map to add.
+ */
+static void rule_add(rule_map *rm) {
+
+	map_match cmp;
+	ENTRY e;
+	ENTRY *f;
+	hash_entry *entry;
+	hash_entry *tmp;
+	list *list_to_addto;
+
+	e.key = rm->key;
+
+	log_info("Searching for key: %s\n", e.key);
+	/* Check to see if it has already been added*/
+	f = hsearch(e, FIND);
+
+	/*
+	 * Since your only hashing on a partial key, the inputs we need to handle
+	 * when you want to override the outputs for a given input set, as well as
+	 * checking for duplicate entries.
+	 */
+	if(f) {
+		log_info("Existing entry found!\n");
+		tmp = (hash_entry *)f->data;
+		cmp = rule_map_cmp(rm, tmp->r);
+		log_error("Duplicate line detected in file: %s\n"
+			  "Lines %d and %d %s!\n",
+			  rm->filename, tmp->r->lineno, rm->lineno,
+			  map_match_str[cmp]);
+		rule_map_free(rm, false);
+		goto err;
+	}
+	/* It wasn't found, just add the rule map to the table */
+	else {
+
+		entry = malloc(sizeof(hash_entry));
+		if (!entry)
+			goto oom;
+
+		entry->r = rm;
+		e.data = entry;
+
+		f = hsearch(e, ENTER);
+		if(f == NULL) {
+			goto oom;
+		}
+
+		/* new entries must be added to the ordered list */
+		entry->r = rm;
+		list_to_addto = rm->is_never_allow ? &nallow_list : &line_order_list;
+		list_append(list_to_addto, &entry->listify);
+	}
+
+	return;
+oom:
+	if (e.key)
+		free(e.key);
+	if (entry)
+		free(entry);
+	if (rm)
+		free(rm);
+	log_error("Out of memory in function: %s\n", __FUNCTION__);
+err:
+	exit(EXIT_FAILURE);
+}
+
+static void parse_file(file_info *in_file) {
+
+	char *p;
+	size_t len;
+	char *token;
+	char *saveptr;
+	bool is_never_allow;
+	bool found_whitespace;
+
+	size_t lineno = 0;
+	char *name = NULL;
+	char *value = NULL;
+	size_t token_cnt = 0;
+
+	char line_buf[BUFSIZ];
+	kvp keys[KVP_NUM_OF_RULES];
+
+	while (fgets(line_buf, sizeof(line_buf) - 1, in_file->file)) {
+		lineno++;
+		is_never_allow = false;
+		found_whitespace = false;
+		log_info("Got line %zu\n", lineno);
+		len = strlen(line_buf);
+		if (line_buf[len - 1] == '\n')
+			line_buf[len - 1] = '\0';
+		p = line_buf;
+
+		/* neverallow lines must start with neverallow (ie ^neverallow) */
+		if (!strncasecmp(p, "neverallow", strlen("neverallow"))) {
+			p += strlen("neverallow");
+			is_never_allow = true;
+		}
+
+		/* strip trailing whitespace skip comments */
+		while (isspace(*p)) {
+			p++;
+			found_whitespace = true;
+		}
+		if (*p == '#' || *p == '\0')
+			continue;
+
+		token = strtok_r(p, " \t", &saveptr);
+		if (!token)
+			goto err;
+
+		token_cnt = 0;
+		memset(keys, 0, sizeof(kvp) * KVP_NUM_OF_RULES);
+		while (1) {
+
+			name = token;
+			value = strchr(name, '=');
+			if (!value)
+				goto err;
+			*value++ = 0;
+
+			keys[token_cnt].key = strdup(name);
+			if (!keys[token_cnt].key)
+				goto oom;
+
+			keys[token_cnt].value = strdup(value);
+			if (!keys[token_cnt].value)
+				goto oom;
+
+			token_cnt++;
+
+			token = strtok_r(NULL, " \t", &saveptr);
+			if (!token)
+				break;
+
+		} /*End token parsing */
+
+		rule_map *r = rule_map_new(keys, token_cnt, lineno, in_file->name, is_never_allow);
+		if (!r)
+			goto err;
+		rule_add(r);
+
+	} /* End file parsing */
+	return;
+
+err:
+	log_error("Reading file: \"%s\" line: %zu name: \"%s\" value: \"%s\"\n",
+		in_file->name, lineno, name, value);
+	if(found_whitespace && name && !strcasecmp(name, "neverallow")) {
+		log_error("perhaps whitespace before neverallow\n");
+	}
+	exit(EXIT_FAILURE);
+oom:
+	log_error("In function %s:  Out of memory\n", __FUNCTION__);
+	exit(EXIT_FAILURE);
+}
+
+/**
+ * Parses the seapp_contexts file and neverallow file
+ * and adds them to the hash table and ordered list entries
+ * when it encounters them.
+ * Calls exit on failure.
+ */
+static void parse() {
+
+	file_info *current;
+	list_element *cursor;
+	list_for_each(&input_file_list, cursor) {
+		current = list_entry(cursor, typeof(*current), listify);
+		parse_file(current);
+	}
+}
+
+static void validate() {
+
+	list_element *cursor, *v;
+	bool found_issues = false;
+	hash_entry *e;
+	rule_map *r;
+	list_for_each(&line_order_list, cursor) {
+		e = list_entry(cursor, typeof(*e), listify);
+		rule_map_validate(e->r);
+	}
+
+	list_for_each(&line_order_list, cursor) {
+		e = list_entry(cursor, typeof(*e), listify);
+		r = e->r;
+		list_for_each(&r->violations, v) {
+			found_issues = true;
+			log_error("Rule in File \"%s\" on line %d: \"", e->r->filename, e->r->lineno);
+			rule_map_print(stderr, e->r);
+			r = list_entry(v, rule_map, listify);
+			fprintf(stderr, "\" violates neverallow in File \"%s\" on line %d: \"", r->filename, r->lineno);
+			rule_map_print(stderr, r);
+			fprintf(stderr, "\"\n");
+		}
+	}
+
+	if (found_issues) {
+		exit(EXIT_FAILURE);
+	}
+}
+
+/**
+ * Should be called after parsing to cause the printing of the rule_maps
+ * stored in the ordered list, head first, which preserves the "first encountered"
+ * ordering.
+ */
+static void output() {
+
+	hash_entry *e;
+	list_element *cursor;
+
+	if (!out_file.file) {
+		log_info("No output file, not outputting.\n");
+		return;
+	}
+
+	list_for_each(&line_order_list, cursor) {
+		e = list_entry(cursor, hash_entry, listify);
+		rule_map_print(out_file.file, e->r);
+		fprintf(out_file.file, "\n");
+	}
+}
+
+/**
+ * This function is registered to the at exit handler and should clean up
+ * the programs dynamic resources, such as memory and fd's.
+ */
+static void cleanup() {
+
+	/* Only close this when it was opened by me and not the crt */
+	if (out_file.name && strcmp(out_file.name, "stdout") && out_file.file) {
+		log_info("Closing file: %s\n", out_file.name);
+		fclose(out_file.file);
+	}
+
+	if (pol.policy_file) {
+
+		log_info("Closing file: %s\n", pol.policy_file_name);
+		fclose(pol.policy_file);
+
+		if (pol.db)
+			sepol_policydb_free(pol.db);
+
+		if (pol.pf)
+			sepol_policy_file_free(pol.pf);
+
+		if (pol.handle)
+			sepol_handle_destroy(pol.handle);
+	}
+
+	log_info("Freeing lists\n");
+	list_free(&input_file_list);
+	list_free(&line_order_list);
+	list_free(&nallow_list);
+	hdestroy();
+}
+
+int main(int argc, char *argv[]) {
+	if (!hcreate(TABLE_SIZE)) {
+		log_error("Could not create hash table: %s\n", strerror(errno));
+		exit(EXIT_FAILURE);
+	}
+	atexit(cleanup);
+	handle_options(argc, argv);
+	init();
+	log_info("Starting to parse\n");
+	parse();
+	log_info("Parsing completed, generating output\n");
+	validate();
+	output();
+	log_info("Success, generated output\n");
+	exit(EXIT_SUCCESS);
+}
diff --git a/sepolicy/tools/checkfc.c b/sepolicy/tools/checkfc.c
new file mode 100644
index 0000000..e7d19b0
--- /dev/null
+++ b/sepolicy/tools/checkfc.c
@@ -0,0 +1,379 @@
+#include <getopt.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sepol/module.h>
+#include <sepol/policydb/policydb.h>
+#include <sepol/sepol.h>
+#include <selinux/selinux.h>
+#include <selinux/label.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+static const char * const CHECK_FC_ASSERT_ATTRS[] = { "fs_type", "dev_type", "file_type", NULL };
+static const char * const CHECK_PC_ASSERT_ATTRS[] = { "property_type", NULL };
+static const char * const CHECK_SC_ASSERT_ATTRS[] = { "service_manager_type", NULL };
+
+typedef enum filemode filemode;
+enum filemode {
+    filemode_file_contexts = 0,
+    filemode_property_contexts,
+    filemode_service_contexts
+};
+
+static struct {
+    /* policy */
+    struct {
+        union {
+            /* Union these so we don't have to cast */
+            sepol_policydb_t *sdb;
+            policydb_t *pdb;
+        };
+        sepol_policy_file_t *pf;
+        sepol_handle_t *handle;
+        FILE *file;
+#define SEHANDLE_CNT 2
+        struct selabel_handle *sehnd[SEHANDLE_CNT];
+    } sepolicy;
+
+    /* assertions */
+    struct {
+        const char * const *attrs; /* for the original set to print on error */
+        ebitmap_t set;             /* the ebitmap representation of the attrs */
+    } assert;
+
+} global_state;
+
+static const char * const *filemode_to_assert_attrs(filemode mode)
+{
+    switch (mode) {
+    case filemode_file_contexts:
+        return CHECK_FC_ASSERT_ATTRS;
+    case filemode_property_contexts:
+        return CHECK_PC_ASSERT_ATTRS;
+    case filemode_service_contexts:
+        return CHECK_SC_ASSERT_ATTRS;
+    }
+    /* die on invalid parameters */
+    fprintf(stderr, "Error: Invalid mode of operation: %d\n", mode);
+    exit(1);
+}
+
+static int get_attr_bit(policydb_t *policydb, const char *attr_name)
+{
+    struct type_datum *attr = hashtab_search(policydb->p_types.table, (char *)attr_name);
+    if (!attr) {
+        fprintf(stderr, "Error: \"%s\" is not defined in this policy.\n", attr_name);
+        return -1;
+    }
+
+    if (attr->flavor != TYPE_ATTRIB) {
+        fprintf(stderr, "Error: \"%s\" is not an attribute in this policy.\n", attr_name);
+        return -1;
+    }
+
+    return attr->s.value - 1;
+}
+
+static bool ebitmap_attribute_assertion_init(ebitmap_t *assertions, const char * const attributes[])
+{
+
+    while (*attributes) {
+
+        int bit_pos = get_attr_bit(global_state.sepolicy.pdb, *attributes);
+        if (bit_pos < 0) {
+            /* get_attr_bit() logs error */
+            return false;
+        }
+
+        int err = ebitmap_set_bit(assertions, bit_pos, 1);
+        if (err) {
+            fprintf(stderr, "Error: setting bit on assertion ebitmap!\n");
+            return false;
+        }
+        attributes++;
+    }
+    return true;
+}
+
+static bool is_type_of_attribute_set(policydb_t *policydb, const char *type_name,
+        ebitmap_t *attr_set)
+{
+    struct type_datum *type = hashtab_search(policydb->p_types.table, (char *)type_name);
+    if (!type) {
+        fprintf(stderr, "Error: \"%s\" is not defined in this policy.\n", type_name);
+        return false;
+    }
+
+    if (type->flavor != TYPE_TYPE) {
+        fprintf(stderr, "Error: \"%s\" is not a type in this policy.\n", type_name);
+        return false;
+    }
+
+    ebitmap_t dst;
+    ebitmap_init(&dst);
+
+    /* Take the intersection, if the set is empty, then its a failure */
+    int rc = ebitmap_and(&dst, attr_set, &policydb->type_attr_map[type->s.value - 1]);
+    if (rc) {
+        fprintf(stderr, "Error: Could not perform ebitmap_and: %d\n", rc);
+        exit(1);
+    }
+
+    bool res = (bool)ebitmap_length(&dst);
+
+    ebitmap_destroy(&dst);
+    return res;
+}
+
+static void dump_char_array(FILE *stream, const char * const *strings)
+{
+
+    const char * const *p = strings;
+
+    fprintf(stream, "\"");
+
+    while (*p) {
+        const char *s = *p++;
+        const char *fmt = *p ? "%s, " : "%s\"";
+        fprintf(stream, fmt, s);
+    }
+}
+
+static int validate(char **contextp)
+{
+    bool res;
+    char *context = *contextp;
+
+    sepol_context_t *ctx;
+    int rc = sepol_context_from_string(global_state.sepolicy.handle, context,
+            &ctx);
+    if (rc < 0) {
+        fprintf(stderr, "Error: Could not allocate context from string");
+        exit(1);
+    }
+
+    rc = sepol_context_check(global_state.sepolicy.handle,
+            global_state.sepolicy.sdb, ctx);
+    if (rc < 0) {
+        goto out;
+    }
+
+    const char *type_name = sepol_context_get_type(ctx);
+
+    uint32_t len = ebitmap_length(&global_state.assert.set);
+    if (len > 0) {
+        res = !is_type_of_attribute_set(global_state.sepolicy.pdb, type_name,
+                &global_state.assert.set);
+        if (res) {
+            fprintf(stderr, "Error: type \"%s\" is not of set: ", type_name);
+            dump_char_array(stderr, global_state.assert.attrs);
+            fprintf(stderr, "\n");
+            /* The calls above did not affect rc, so set error before going to out */
+            rc = -1;
+            goto out;
+        }
+    }
+    /* Success: Although it should be 0, we explicitly set rc to 0 for clarity */
+    rc = 0;
+
+ out:
+    sepol_context_free(ctx);
+    return rc;
+}
+
+static void usage(char *name) {
+    fprintf(stderr, "usage1:  %s [-p|-s] [-e] sepolicy context_file\n\n"
+        "Parses a context file and checks for syntax errors.\n"
+        "The context_file is assumed to be a file_contexts file\n"
+        "unless the -p or -s option is used to indicate the property or service backend respectively.\n"
+        "If -e is specified, then the context_file is allowed to be empty.\n\n"
+
+        "usage2:  %s -c file_contexts1 file_contexts2\n\n"
+        "Compares two file contexts files and reports one of subset, equal, superset, or incomparable.\n\n",
+        name, name);
+    exit(1);
+}
+
+static void cleanup(void) {
+
+    if (global_state.sepolicy.file) {
+        fclose(global_state.sepolicy.file);
+    }
+
+    if (global_state.sepolicy.sdb) {
+        sepol_policydb_free(global_state.sepolicy.sdb);
+    }
+
+    if (global_state.sepolicy.pf) {
+        sepol_policy_file_free(global_state.sepolicy.pf);
+    }
+
+    if (global_state.sepolicy.handle) {
+        sepol_handle_destroy(global_state.sepolicy.handle);
+    }
+
+    ebitmap_destroy(&global_state.assert.set);
+
+    int i;
+    for (i = 0; i < SEHANDLE_CNT; i++) {
+        struct selabel_handle *sehnd = global_state.sepolicy.sehnd[i];
+        if (sehnd) {
+            selabel_close(sehnd);
+        }
+    }
+}
+
+static void do_compare_and_die_on_error(struct selinux_opt opts[], unsigned int backend, char *paths[])
+{
+    enum selabel_cmp_result result;
+     char *result_str[] = { "subset", "equal", "superset", "incomparable" };
+     int i;
+
+     opts[0].value = NULL; /* not validating against a policy when comparing */
+
+     for (i = 0; i < SEHANDLE_CNT; i++) {
+         opts[1].value = paths[i];
+         global_state.sepolicy.sehnd[i] = selabel_open(backend, opts, 2);
+         if (!global_state.sepolicy.sehnd[i]) {
+             fprintf(stderr, "Error: could not load context file from %s\n", paths[i]);
+             exit(1);
+         }
+     }
+
+     result = selabel_cmp(global_state.sepolicy.sehnd[0], global_state.sepolicy.sehnd[1]);
+     printf("%s\n", result_str[result]);
+}
+
+static void do_fc_check_and_die_on_error(struct selinux_opt opts[], unsigned int backend, filemode mode,
+        const char *sepolicy_file, const char *context_file, bool allow_empty)
+{
+    struct stat sb;
+    if (stat(context_file, &sb) < 0) {
+        perror("Error: could not get stat on file contexts file");
+        exit(1);
+    }
+
+    if (sb.st_size == 0) {
+        /* Nothing to check on empty file_contexts file if allowed*/
+        if (allow_empty) {
+            return;
+        }
+        /* else: We could throw the error here, but libselinux backend will catch it */
+    }
+
+    global_state.sepolicy.file = fopen(sepolicy_file, "r");
+    if (!global_state.sepolicy.file) {
+      perror("Error: could not open policy file");
+      exit(1);
+    }
+
+    global_state.sepolicy.handle = sepol_handle_create();
+    if (!global_state.sepolicy.handle) {
+        fprintf(stderr, "Error: could not create policy handle: %s\n", strerror(errno));
+        exit(1);
+    }
+
+    if (sepol_policy_file_create(&global_state.sepolicy.pf) < 0) {
+      perror("Error: could not create policy handle");
+      exit(1);
+    }
+
+    sepol_policy_file_set_fp(global_state.sepolicy.pf, global_state.sepolicy.file);
+    sepol_policy_file_set_handle(global_state.sepolicy.pf, global_state.sepolicy.handle);
+
+    int rc = sepol_policydb_create(&global_state.sepolicy.sdb);
+    if (rc < 0) {
+      perror("Error: could not create policy db");
+      exit(1);
+    }
+
+    rc = sepol_policydb_read(global_state.sepolicy.sdb, global_state.sepolicy.pf);
+    if (rc < 0) {
+      perror("Error: could not read file into policy db");
+      exit(1);
+    }
+
+    global_state.assert.attrs = filemode_to_assert_attrs(mode);
+
+    bool ret = ebitmap_attribute_assertion_init(&global_state.assert.set, global_state.assert.attrs);
+    if (!ret) {
+        /* error messages logged by ebitmap_attribute_assertion_init() */
+        exit(1);
+    }
+
+    selinux_set_callback(SELINUX_CB_VALIDATE,
+                         (union selinux_callback)&validate);
+
+    opts[1].value = context_file;
+
+    global_state.sepolicy.sehnd[0] = selabel_open(backend, opts, 2);
+    if (!global_state.sepolicy.sehnd[0]) {
+      fprintf(stderr, "Error: could not load context file from %s\n", context_file);
+      exit(1);
+    }
+}
+
+int main(int argc, char **argv)
+{
+  struct selinux_opt opts[] = {
+    { SELABEL_OPT_VALIDATE, (void*)1 },
+    { SELABEL_OPT_PATH, NULL }
+  };
+
+  // Default backend unless changed by input argument.
+  unsigned int backend = SELABEL_CTX_FILE;
+
+  bool allow_empty = false;
+  bool compare = false;
+  char c;
+
+  filemode mode = filemode_file_contexts;
+
+  while ((c = getopt(argc, argv, "cpse")) != -1) {
+    switch (c) {
+      case 'c':
+        compare = true;
+        break;
+      case 'e':
+        allow_empty = true;
+        break;
+      case 'p':
+        mode = filemode_property_contexts;
+        backend = SELABEL_CTX_ANDROID_PROP;
+        break;
+      case 's':
+        mode = filemode_service_contexts;
+        backend = SELABEL_CTX_ANDROID_PROP;
+        break;
+      case 'h':
+      default:
+        usage(argv[0]);
+        break;
+    }
+  }
+
+  int index = optind;
+  if (argc - optind != 2) {
+    usage(argv[0]);
+  }
+
+  if (compare && backend != SELABEL_CTX_FILE) {
+    usage(argv[0]);
+  }
+
+  atexit(cleanup);
+
+  if (compare) {
+      do_compare_and_die_on_error(opts, backend, &(argv[index]));
+  } else {
+      /* remaining args are sepolicy file and context file  */
+      char *sepolicy_file = argv[index];
+      char *context_file = argv[index + 1];
+
+      do_fc_check_and_die_on_error(opts, backend, mode, sepolicy_file, context_file, allow_empty);
+  }
+  exit(0);
+}
diff --git a/sepolicy/tools/fc_sort/Android.mk b/sepolicy/tools/fc_sort/Android.mk
new file mode 100644
index 0000000..f78d550
--- /dev/null
+++ b/sepolicy/tools/fc_sort/Android.mk
@@ -0,0 +1,12 @@
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := fc_sort
+LOCAL_MODULE_TAGS := optional
+LOCAL_SRC_FILES := fc_sort.c
+LOCAL_CXX_STL := none
+
+include $(BUILD_HOST_EXECUTABLE)
+
+###################################
diff --git a/sepolicy/tools/fc_sort/MODULE_LICENSE_GPL b/sepolicy/tools/fc_sort/MODULE_LICENSE_GPL
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/sepolicy/tools/fc_sort/MODULE_LICENSE_GPL
diff --git a/sepolicy/tools/fc_sort/NOTICE b/sepolicy/tools/fc_sort/NOTICE
new file mode 100644
index 0000000..5b6e7c6
--- /dev/null
+++ b/sepolicy/tools/fc_sort/NOTICE
@@ -0,0 +1,340 @@
+		    GNU GENERAL PUBLIC LICENSE
+		       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+                       59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+		    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+			    NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
+
+	    How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/sepolicy/tools/fc_sort/README b/sepolicy/tools/fc_sort/README
new file mode 100644
index 0000000..0210dc7
--- /dev/null
+++ b/sepolicy/tools/fc_sort/README
@@ -0,0 +1,9 @@
+fc_sort is a tool used for sorting the file_contexts entries based on a heuristic that is
+ covered by a Fedora document. That document can be found here:
+ * https://fedoraproject.org/wiki/SELinux/ManagingFileContext
+
+The tool itself originates from:
+ * https://github.com/TresysTechnology/refpolicy
+
+It can be updated to the current tip of master branch with the below command:
+$ wget https://raw.githubusercontent.com/TresysTechnology/refpolicy/master/support/fc_sort.c
diff --git a/sepolicy/tools/fc_sort/fc_sort.c b/sepolicy/tools/fc_sort/fc_sort.c
new file mode 100644
index 0000000..f4d2cd0
--- /dev/null
+++ b/sepolicy/tools/fc_sort/fc_sort.c
@@ -0,0 +1,567 @@
+/* Copyright 2005,2013 Tresys Technology
+ *
+ * Some parts of this came from matchpathcon.c in libselinux
+ */
+
+/* PURPOSE OF THIS PROGRAM
+ * The original setfiles sorting algorithm did not take into
+ * account regular expression specificity. With the current
+ * strict and targeted policies this is not an issue because
+ * the file contexts are partially hand sorted and concatenated
+ * in the right order so that the matches are generally correct.
+ * The way reference policy and loadable policy modules handle
+ * file contexts makes them come out in an unpredictable order
+ * and therefore setfiles (or this standalone tool) need to sort
+ * the regular expressions in a deterministic and stable way.
+ */
+
+#define BUF_SIZE 4096;
+#define _GNU_SOURCE
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+typedef unsigned char bool_t;
+
+/* file_context_node
+ * A node used in a linked list of file contexts.c
+ * Each node contains the regular expression, the type and
+ *  the context, as well as information about the regular
+ *  expression. The regular expression data (meta, stem_len
+ *  and str_len) can be filled in by using the fc_fill_data
+ *  function after the regular expression has been loaded.
+ * next points to the next node in the linked list.
+ */
+typedef struct file_context_node {
+	char *path;
+	char *file_type;
+	char *context;
+	bool_t meta;
+	int stem_len;
+	int str_len;
+	struct file_context_node *next;
+} file_context_node_t;
+
+void file_context_node_destroy(file_context_node_t *x)
+{
+	free(x->path);
+	free(x->file_type);
+	free(x->context);
+}
+
+
+
+/* file_context_bucket
+ * A node used in a linked list of buckets that contain
+ *  file_context_node's.
+ * Each node contains a pointer to a file_context_node which
+ *  is the header of its linked list. This linked list is the
+ *  content of this bucket.
+ * next points to the next bucket in the linked list.
+ */
+typedef struct file_context_bucket {
+	file_context_node_t *data;
+	struct file_context_bucket *next;
+} file_context_bucket_t;
+
+
+
+/* fc_compare
+ * Compares two file contexts' regular expressions and returns:
+ *    -1 if a is less specific than b
+ *     0 if a and be are equally specific
+ *     1 if a is more specific than b
+ * The comparison is based on the following statements,
+ *  in order from most important to least important, given a and b:
+ *     If a is a regular expression and b is not,
+ *      -> a is less specific than b.
+ *     If a's stem length is shorter than b's stem length,
+ *      -> a is less specific than b.
+ *     If a's string length is shorter than b's string length,
+ *      -> a is less specific than b.
+ *     If a does not have a specified type and b does,
+ *      -> a is less specific than b.
+ */
+int fc_compare(file_context_node_t *a, file_context_node_t *b)
+{
+	/* Check to see if either a or b have meta characters
+	 *  and the other doesn't. */
+	if (a->meta && !b->meta)
+		return -1;
+	if (b->meta && !a->meta)
+		return 1;
+
+	/* Check to see if either a or b have a shorter stem
+	 *  length than the other. */
+	if (a->stem_len < b->stem_len)
+		return -1;
+	if (b->stem_len < a->stem_len)
+		return 1;
+
+	/* Check to see if either a or b have a shorter string
+	 *  length than the other. */
+	if (a->str_len < b->str_len)
+		return -1;
+	if (b->str_len < a->str_len)
+		return 1;
+
+	/* Check to see if either a or b has a specified type
+	 *  and the other doesn't. */
+	if (!a->file_type && b->file_type)
+		return -1;
+	if (!b->file_type && a->file_type)
+		return 1;
+
+	/* If none of the above conditions were satisfied,
+	 * then a and b are equally specific. */
+	return 0;
+}
+
+
+
+/* fc_merge
+ * Merges two sorted file context linked lists into one
+ *  sorted one.
+ * Pass two lists a and b, and after the completion of fc_merge,
+ *  the final list is contained in a, and b is empty.
+ */
+file_context_node_t *fc_merge(file_context_node_t *a,
+				   file_context_node_t *b)
+{
+	file_context_node_t *a_current;
+	file_context_node_t *b_current;
+	file_context_node_t *temp;
+	file_context_node_t *jumpto;
+
+
+
+	/* If a is a empty list, and b is not,
+	 *  set a as b and proceed to the end. */
+	if (!a && b)
+		a = b;
+	/* If b is an empty list, leave a as it is. */
+	else if (!b) {
+	} else {
+		/* Make it so the list a has the lesser
+		 *  first element always. */
+		if (fc_compare(a, b) == 1) {
+			temp = a;
+			a = b;
+			b = temp;
+		}
+		a_current = a;
+		b_current = b;
+
+		/* Merge by inserting b's nodes in between a's nodes. */
+		while (a_current->next && b_current) {
+			jumpto = a_current->next;
+
+			/* Insert b's nodes in between the current a node
+			 *  and the next a node.*/
+			while (b_current && a_current->next &&
+			       fc_compare(a_current->next,
+					  b_current) != -1) {
+
+
+				temp = a_current->next;
+				a_current->next = b_current;
+				b_current = b_current->next;
+				a_current->next->next = temp;
+				a_current = a_current->next;
+			}
+
+			/* Skip all the inserted node from b to the
+			 *  next node in the original a. */
+			a_current = jumpto;
+		}
+
+
+		/* if there is anything left in b to be inserted,
+		   put it on the end */
+		if (b_current) {
+			a_current->next = b_current;
+		}
+	}
+
+	return a;
+}
+
+
+
+/* fc_merge_sort
+ * Sorts file contexts from least specific to more specific.
+ * The bucket linked list is passed and after the completion
+ *  of the fc_merge_sort function, there is only one bucket
+ *  (pointed to by master) that contains a linked list
+ *  of all the file contexts, in sorted order.
+ * Explanation of the algorithm:
+ *  The algorithm implemented in fc_merge_sort is an iterative
+ *   implementation of merge sort.
+ *  At first, each bucket has a linked list of file contexts
+ *   that are 1 element each.
+ *  Each pass, each odd numbered bucket is merged into the bucket
+ *   before it. This halves the number of buckets each pass.
+ *  It will continue passing over the buckets (as described above)
+ *   until there is only  one bucket left, containing the list of
+ *   file contexts, sorted.
+ */
+void fc_merge_sort(file_context_bucket_t *master)
+{
+
+
+	file_context_bucket_t *current;
+	file_context_bucket_t *temp;
+
+	/* Loop until master is the only bucket left
+	 * so that this will stop when master contains
+	 * the sorted list. */
+	while (master->next) {
+		current = master;
+
+		/* This loop merges buckets two-by-two. */
+		while (current) {
+
+			if (current->next) {
+
+				current->data =
+				    fc_merge(current->data,
+					     current->next->data);
+
+
+
+				temp = current->next;
+				current->next = current->next->next;
+
+				free(temp);
+
+			}
+
+
+			current = current->next;
+		}
+	}
+
+
+}
+
+
+
+/* fc_fill_data
+ * This processes a regular expression in a file context
+ *  and sets the data held in file_context_node, namely
+ *  meta, str_len and stem_len.
+ * The following changes are made to fc_node after the
+ *  the completion of the function:
+ *     fc_node->meta =		1 if path has a meta character, 0 if not.
+ *     fc_node->str_len =	The string length of the entire path
+ *     fc_node->stem_len = 	The number of characters up until
+ *				 the first meta character.
+ */
+void fc_fill_data(file_context_node_t *fc_node)
+{
+	int c = 0;
+
+	fc_node->meta = 0;
+	fc_node->stem_len = 0;
+	fc_node->str_len = 0;
+
+	/* Process until the string termination character
+	 *  has been reached.
+	 * Note: this while loop has been adapted from
+	 *  spec_hasMetaChars in matchpathcon.c from
+	 *  libselinux-1.22. */
+	while (fc_node->path[c] != '\0') {
+		switch (fc_node->path[c]) {
+		case '.':
+		case '^':
+		case '$':
+		case '?':
+		case '*':
+		case '+':
+		case '|':
+		case '[':
+		case '(':
+		case '{':
+			/* If a meta character is found,
+			 *  set meta to one */
+			fc_node->meta = 1;
+			break;
+		case '\\':
+			/* If a escape character is found,
+			 *  skip the next character. */
+			c++;
+		default:
+			/* If no meta character has been found yet,
+			 *  add one to the stem length. */
+			if (!fc_node->meta)
+				fc_node->stem_len++;
+			break;
+		}
+
+		fc_node->str_len++;
+		c++;
+	}
+}
+
+/* main
+ * This program takes in two arguments, the input filename and the
+ *  output filename. The input file should be syntactically correct.
+ * Overall what is done in the main is read in the file and store each
+ *  line of code, sort it, then output it to the output file.
+ */
+int main(int argc, char *argv[])
+{
+	int lines;
+	size_t start, finish, regex_len, context_len;
+	size_t line_len, buf_len, i, j;
+	char *input_name, *output_name, *line_buf;
+
+	file_context_node_t *temp;
+	file_context_node_t *head;
+	file_context_node_t *current;
+	file_context_bucket_t *master;
+	file_context_bucket_t *bcurrent;
+
+	FILE *in_file, *out_file;
+
+
+	/* Check for the correct number of command line arguments. */
+	if (argc < 2 || argc > 3) {
+		fprintf(stderr, "Usage: %s <infile> [<outfile>]\n",argv[0]);
+		return 1;
+	}
+
+	input_name = argv[1];
+	output_name = (argc >= 3) ? argv[2] : NULL;
+
+	i = j = lines = 0;
+
+	/* Open the input file. */
+	if (!(in_file = fopen(input_name, "r"))) {
+		fprintf(stderr, "Error: failure opening input file for read.\n");
+		return 1;
+	}
+
+	/* Initialize the head of the linked list. */
+	head = current = (file_context_node_t*)malloc(sizeof(file_context_node_t));
+	head->next = NULL;
+
+	/* Parse the file into a file_context linked list. */
+	line_buf = NULL;
+
+	while ( getline(&line_buf, &buf_len, in_file) != -1 ){
+		line_len = strlen(line_buf);
+		if( line_len == 0 || line_len == 1)
+			continue;
+		/* Get rid of whitespace from the front of the line. */
+		for (i = 0; i < line_len; i++) {
+			if (!isspace(line_buf[i]))
+				break;
+		}
+
+
+		if (i >= line_len)
+			continue;
+		/* Check if the line isn't empty and isn't a comment */
+		if (line_buf[i] == '#')
+			continue;
+
+		/* We have a valid line - allocate a new node. */
+		temp = (file_context_node_t *)malloc(sizeof(file_context_node_t));
+		if (!temp) {
+			fprintf(stderr, "Error: failure allocating memory.\n");
+			return 1;
+		}
+		temp->next = NULL;
+		memset(temp, 0, sizeof(file_context_node_t));
+
+		/* Parse out the regular expression from the line. */
+		start = i;
+
+
+		while (i < line_len && (!isspace(line_buf[i])))
+			i++;
+		finish = i;
+
+
+		regex_len = finish - start;
+
+		if (regex_len == 0) {
+			file_context_node_destroy(temp);
+			free(temp);
+
+
+			continue;
+		}
+
+		temp->path = (char*)strndup(&line_buf[start], regex_len);
+		if (!temp->path) {
+			file_context_node_destroy(temp);
+			free(temp);
+			fprintf(stderr, "Error: failure allocating memory.\n");
+			return 1;
+		}
+
+		/* Get rid of whitespace after the regular expression. */
+		for (; i < line_len; i++) {
+
+			if (!isspace(line_buf[i]))
+				break;
+		}
+
+		if (i == line_len) {
+			file_context_node_destroy(temp);
+			free(temp);
+			continue;
+		}
+
+		/* Parse out the type from the line (if it
+			*  is there). */
+		if (line_buf[i] == '-') {
+			temp->file_type = (char *)malloc(sizeof(char) * 3);
+			if (!(temp->file_type)) {
+				fprintf(stderr, "Error: failure allocating memory.\n");
+				return 1;
+			}
+
+			if( i + 2 >= line_len ) {
+				file_context_node_destroy(temp);
+				free(temp);
+
+				continue;
+			}
+
+			/* Fill the type into the array. */
+			temp->file_type[0] = line_buf[i];
+			temp->file_type[1] = line_buf[i + 1];
+			i += 2;
+			temp->file_type[2] = 0;
+
+			/* Get rid of whitespace after the type. */
+			for (; i < line_len; i++) {
+				if (!isspace(line_buf[i]))
+					break;
+			}
+
+			if (i == line_len) {
+
+				file_context_node_destroy(temp);
+				free(temp);
+				continue;
+			}
+		}
+
+		/* Parse out the context from the line. */
+		start = i;
+		while (i < line_len && (!isspace(line_buf[i])))
+			i++;
+		finish = i;
+
+		context_len = finish - start;
+
+		temp->context = (char*)strndup(&line_buf[start], context_len);
+		if (!temp->context) {
+			file_context_node_destroy(temp);
+			free(temp);
+			fprintf(stderr, "Error: failure allocating memory.\n");
+			return 1;
+		}
+
+		/* Set all the data about the regular
+			*  expression. */
+		fc_fill_data(temp);
+
+		/* Link this line of code at the end of
+			*  the linked list. */
+		current->next = temp;
+		current = current->next;
+		lines++;
+
+
+		free(line_buf);
+		line_buf = NULL;
+	}
+	fclose(in_file);
+
+	/* Create the bucket linked list from the earlier linked list. */
+	current = head->next;
+	bcurrent = master =
+	    (file_context_bucket_t *)
+	    malloc(sizeof(file_context_bucket_t));
+	bcurrent->next = NULL;
+	bcurrent->data = NULL;
+
+	/* Go until all the nodes have been put in individual buckets. */
+	while (current) {
+		/* Copy over the file context line into the bucket. */
+		bcurrent->data = current;
+		current = current->next;
+
+		/* Detach the node in the bucket from the old list. */
+		bcurrent->data->next = NULL;
+
+		/* If there should be another bucket, put one at the end. */
+		if (current) {
+			bcurrent->next =
+			    (file_context_bucket_t *)
+			    malloc(sizeof(file_context_bucket_t));
+			if (!(bcurrent->next)) {
+				printf
+				    ("Error: failure allocating memory.\n");
+				return -1;
+			}
+
+			/* Make sure the new bucket thinks it's the end of the
+			 *  list. */
+			bcurrent->next->next = NULL;
+
+			bcurrent = bcurrent->next;
+		}
+
+	}
+
+	/* Sort the bucket list. */
+	fc_merge_sort(master);
+
+	/* Open the output file. */
+	if (output_name) {
+		if (!(out_file = fopen(output_name, "w"))) {
+			printf("Error: failure opening output file for write.\n");
+			return -1;
+		}
+	} else {
+		out_file = stdout;
+	}
+
+	/* Output the sorted file_context linked list to the output file. */
+	current = master->data;
+	while (current) {
+		/* Output the path. */
+		fprintf(out_file, "%s\t\t", current->path);
+
+		/* Output the type, if there is one. */
+		if (current->file_type) {
+			fprintf(out_file, "%s\t", current->file_type);
+		}
+
+		/* Output the context. */
+		fprintf(out_file, "%s\n", current->context);
+
+		/* Remove the node. */
+		temp = current;
+		current = current->next;
+
+		file_context_node_destroy(temp);
+		free(temp);
+
+	}
+	free(master);
+
+	if (output_name) {
+		fclose(out_file);
+	}
+
+	return 0;
+}
diff --git a/sepolicy/tools/insertkeys.py b/sepolicy/tools/insertkeys.py
new file mode 100755
index 0000000..ca1e432
--- /dev/null
+++ b/sepolicy/tools/insertkeys.py
@@ -0,0 +1,267 @@
+#!/usr/bin/env python
+
+from xml.sax import saxutils, handler, make_parser
+from optparse import OptionParser
+import ConfigParser
+import logging
+import base64
+import sys
+import os
+
+__VERSION = (0, 1)
+
+'''
+This tool reads a mac_permissions.xml and replaces keywords in the signature
+clause with keys provided by pem files.
+'''
+
+class GenerateKeys(object):
+    def __init__(self, path):
+        '''
+        Generates an object with Base16 and Base64 encoded versions of the keys
+        found in the supplied pem file argument. PEM files can contain multiple
+        certs, however this seems to be unused in Android as pkg manager grabs
+        the first cert in the APK. This will however support multiple certs in
+        the resulting generation with index[0] being the first cert in the pem
+        file.
+        '''
+
+        self._base64Key = list()
+        self._base16Key = list()
+
+        if not os.path.isfile(path):
+            sys.exit("Path " + path + " does not exist or is not a file!")
+
+        pkFile = open(path, 'rb').readlines()
+        base64Key = ""
+        lineNo = 1
+        certNo = 1
+        inCert = False
+        for line in pkFile:
+            line = line.strip()
+            # Are we starting the certificate?
+            if line == "-----BEGIN CERTIFICATE-----":
+                if inCert:
+                    sys.exit("Encountered another BEGIN CERTIFICATE without END CERTIFICATE on " +
+                             "line: " + str(lineNo))
+
+                inCert = True
+
+            # Are we ending the ceritifcate?
+            elif line == "-----END CERTIFICATE-----":
+                if not inCert:
+                    sys.exit("Encountered END CERTIFICATE before BEGIN CERTIFICATE on line: "
+                            + str(lineNo))
+
+                # If we ended the certificate trip the flag
+                inCert = False
+
+                # Sanity check the input
+                if len(base64Key) == 0:
+                    sys.exit("Empty certficate , certificate "+ str(certNo) + " found in file: "
+                            + path)
+
+                # ... and append the certificate to the list
+                # Base 64 includes uppercase. DO NOT tolower()
+                self._base64Key.append(base64Key)
+                try:
+                    # Pkgmanager and setool see hex strings with lowercase, lets be consistent
+                    self._base16Key.append(base64.b16encode(base64.b64decode(base64Key)).lower())
+                except TypeError:
+                    sys.exit("Invalid certificate, certificate "+ str(certNo) + " found in file: "
+                            + path)
+
+                # After adding the key, reset the accumulator as pem files may have subsequent keys
+                base64Key=""
+
+                # And increment your cert number
+                certNo = certNo + 1
+
+            # If we haven't started the certificate, then we should not encounter any data
+            elif not inCert:
+                if line is not "":
+                    sys.exit("Detected erroneous line \""+ line + "\" on " + str(lineNo)
+                        + " in pem file: " + path)
+
+            # else we have started the certicate and need to append the data
+            elif inCert:
+                base64Key += line
+
+            else:
+                # We should never hit this assert, if we do then an unaccounted for state
+                # was entered that was NOT addressed by the if/elif statements above
+                assert(False == True)
+
+            # The last thing to do before looping up is to increment line number
+            lineNo = lineNo + 1
+
+    def __len__(self):
+        return len(self._base16Key)
+
+    def __str__(self):
+        return str(self.getBase16Keys())
+
+    def getBase16Keys(self):
+        return self._base16Key
+
+    def getBase64Keys(self):
+        return self._base64Key
+
+class ParseConfig(ConfigParser.ConfigParser):
+
+    # This must be lowercase
+    OPTION_WILDCARD_TAG = "all"
+
+    def generateKeyMap(self, target_build_variant, key_directory):
+
+        keyMap = dict()
+
+        for tag in self.sections():
+
+            options = self.options(tag)
+
+            for option in options:
+
+                # Only generate the key map for debug or release,
+                # not both!
+                if option != target_build_variant and \
+                option != ParseConfig.OPTION_WILDCARD_TAG:
+                    logging.info("Skipping " + tag + " : " + option +
+                        " because target build variant is set to " +
+                        str(target_build_variant))
+                    continue
+
+                if tag in keyMap:
+                    sys.exit("Duplicate tag detected " + tag)
+
+                tag_path = os.path.expandvars(self.get(tag, option))
+                path = os.path.join(key_directory, tag_path)
+
+                keyMap[tag] = GenerateKeys(path)
+
+                # Multiple certificates may exist in
+                # the pem file. GenerateKeys supports
+                # this however, the mac_permissions.xml
+                # as well as PMS do not.
+                assert len(keyMap[tag]) == 1
+
+        return keyMap
+
+class ReplaceTags(handler.ContentHandler):
+
+    DEFAULT_TAG = "default"
+    PACKAGE_TAG = "package"
+    POLICY_TAG = "policy"
+    SIGNER_TAG = "signer"
+    SIGNATURE_TAG = "signature"
+
+    TAGS_WITH_CHILDREN = [ DEFAULT_TAG, PACKAGE_TAG, POLICY_TAG, SIGNER_TAG ]
+
+    XML_ENCODING_TAG = '<?xml version="1.0" encoding="iso-8859-1"?>'
+
+    def __init__(self, keyMap, out=sys.stdout):
+
+        handler.ContentHandler.__init__(self)
+        self._keyMap = keyMap
+        self._out = out
+        self._out.write(ReplaceTags.XML_ENCODING_TAG)
+        self._out.write("<!-- AUTOGENERATED FILE DO NOT MODIFY -->")
+        self._out.write("<policy>")
+
+    def __del__(self):
+        self._out.write("</policy>")
+
+    def startElement(self, tag, attrs):
+        if tag == ReplaceTags.POLICY_TAG:
+            return
+
+        self._out.write('<' + tag)
+
+        for (name, value) in attrs.items():
+
+            if name == ReplaceTags.SIGNATURE_TAG and value in self._keyMap:
+                for key in self._keyMap[value].getBase16Keys():
+                    logging.info("Replacing " + name + " " + value + " with " + key)
+                    self._out.write(' %s="%s"' % (name, saxutils.escape(key)))
+            else:
+                self._out.write(' %s="%s"' % (name, saxutils.escape(value)))
+
+        if tag in ReplaceTags.TAGS_WITH_CHILDREN:
+            self._out.write('>')
+        else:
+            self._out.write('/>')
+
+    def endElement(self, tag):
+        if tag == ReplaceTags.POLICY_TAG:
+            return
+
+        if tag in ReplaceTags.TAGS_WITH_CHILDREN:
+            self._out.write('</%s>' % tag)
+
+    def characters(self, content):
+        if not content.isspace():
+            self._out.write(saxutils.escape(content))
+
+    def ignorableWhitespace(self, content):
+        pass
+
+    def processingInstruction(self, target, data):
+        self._out.write('<?%s %s?>' % (target, data))
+
+if __name__ == "__main__":
+
+    # Intentional double space to line up equls signs and opening " for
+    # readability.
+    usage  = "usage: %prog [options] CONFIG_FILE MAC_PERMISSIONS_FILE [MAC_PERMISSIONS_FILE...]\n"
+    usage += "This tool allows one to configure an automatic inclusion\n"
+    usage += "of signing keys into the mac_permision.xml file(s) from the\n"
+    usage += "pem files. If mulitple mac_permision.xml files are included\n"
+    usage += "then they are unioned to produce a final version."
+
+    version = "%prog " + str(__VERSION)
+
+    parser = OptionParser(usage=usage, version=version)
+
+    parser.add_option("-v", "--verbose",
+                      action="store_true", dest="verbose", default=False,
+                      help="Print internal operations to stdout")
+
+    parser.add_option("-o", "--output", default="stdout", dest="output_file",
+                      metavar="FILE", help="Specify an output file, default is stdout")
+
+    parser.add_option("-c", "--cwd", default=os.getcwd(), dest="root",
+                      metavar="DIR", help="Specify a root (CWD) directory to run this from, it" \
+                                          "chdirs' AFTER loading the config file")
+
+    parser.add_option("-t", "--target-build-variant", default="eng", dest="target_build_variant",
+                      help="Specify the TARGET_BUILD_VARIANT, defaults to eng")
+
+    parser.add_option("-d", "--key-directory", default="", dest="key_directory",
+                      help="Specify a parent directory for keys")
+
+    (options, args) = parser.parse_args()
+
+    if len(args) < 2:
+        parser.error("Must specify a config file (keys.conf) AND mac_permissions.xml file(s)!")
+
+    logging.basicConfig(level=logging.INFO if options.verbose == True else logging.WARN)
+
+    # Read the config file
+    config = ParseConfig()
+    config.read(args[0])
+
+    os.chdir(options.root)
+
+    output_file = sys.stdout if options.output_file == "stdout" else open(options.output_file, "w")
+    logging.info("Setting output file to: " + options.output_file)
+
+    # Generate the key list
+    key_map = config.generateKeyMap(options.target_build_variant.lower(), options.key_directory)
+    logging.info("Generate key map:")
+    for k in key_map:
+        logging.info(k + " : " + str(key_map[k]))
+    # Generate the XML file with markup replaced with keys
+    parser = make_parser()
+    parser.setContentHandler(ReplaceTags(key_map, output_file))
+    for f in args[1:]:
+        parser.parse(f)
diff --git a/sepolicy/tools/post_process_mac_perms b/sepolicy/tools/post_process_mac_perms
new file mode 100755
index 0000000..25893ed
--- /dev/null
+++ b/sepolicy/tools/post_process_mac_perms
@@ -0,0 +1,106 @@
+#!/usr/bin/env python
+#
+# Copyright (C) 2013 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""
+Tool to help modify an existing mac_permissions.xml with additional app
+certs not already found in that policy. This becomes useful when a directory
+containing apps is searched and the certs from those apps are added to the
+policy not already explicitly listed.
+"""
+
+import sys
+import os
+import argparse
+from base64 import b16encode, b64decode
+import fileinput
+import re
+import subprocess
+import zipfile
+
+PEM_CERT_RE = """-----BEGIN CERTIFICATE-----
+(.+?)
+-----END CERTIFICATE-----
+"""
+def collect_certs_for_app(filename):
+  app_certs = set()
+  with zipfile.ZipFile(filename, 'r') as apkzip:
+    for info in apkzip.infolist():
+      name = info.filename
+      if name.startswith('META-INF/') and name.endswith(('.DSA', '.RSA')):
+        cmd = ['openssl', 'pkcs7', '-inform', 'DER',
+               '-outform', 'PEM', '-print_certs']
+        p = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE,
+                             stderr=subprocess.PIPE)
+        pem_string, err = p.communicate(apkzip.read(name))
+        if err and err.strip():
+          raise RuntimeError('Problem running openssl on %s (%s)' % (filename, e))
+
+        # turn multiline base64 to single line base16
+        transform = lambda x: b16encode(b64decode(x.replace('\n', ''))).lower()
+        results = re.findall(PEM_CERT_RE, pem_string, re.DOTALL)
+        certs = [transform(i) for i in results]
+
+        app_certs.update(certs)
+
+  return app_certs
+
+def add_leftover_certs(args):
+  all_app_certs = set()
+  for dirpath, _, files in os.walk(args.dir):
+    transform = lambda x: os.path.join(dirpath, x)
+    condition = lambda x: x.endswith('.apk')
+    apps = [transform(i) for i in files if condition(i)]
+
+    # Collect certs for each app found
+    for app in apps:
+      app_certs = collect_certs_for_app(app)
+      all_app_certs.update(app_certs)
+
+  if all_app_certs:
+    policy_certs = set()
+    with open(args.policy, 'r') as f:
+      cert_pattern = 'signature="([a-fA-F0-9]+)"'
+      policy_certs = re.findall(cert_pattern, f.read())
+
+    cert_diff = all_app_certs.difference(policy_certs)
+
+    # Build xml stanzas
+    inner_tag = '<seinfo value="%s"/>' % args.seinfo
+    stanza = '<signer signature="%s">%s</signer>'
+    new_stanzas = [stanza % (cert, inner_tag) for cert in cert_diff]
+    mac_perms_string = ''.join(new_stanzas)
+    mac_perms_string += '</policy>'
+
+    # Inline replace with new policy stanzas
+    for line in fileinput.input(args.policy, inplace=True):
+      sys.stdout.write(line.replace('</policy>', mac_perms_string))
+
+def main(argv):
+  parser = argparse.ArgumentParser(description=__doc__)
+
+  parser.add_argument('-s', '--seinfo', dest='seinfo', required=True,
+                      help='seinfo tag for each generated stanza')
+  parser.add_argument('-d', '--dir', dest='dir', required=True,
+                      help='Directory to search for apks')
+  parser.add_argument('-f', '--file', dest='policy', required=True,
+                      help='mac_permissions.xml policy file')
+
+  parser.set_defaults(func=add_leftover_certs)
+  args = parser.parse_args()
+  args.func(args)
+
+if __name__ == '__main__':
+  main(sys.argv)
diff --git a/sepolicy/tools/sepolicy-analyze/Android.mk b/sepolicy/tools/sepolicy-analyze/Android.mk
new file mode 100644
index 0000000..7568351
--- /dev/null
+++ b/sepolicy/tools/sepolicy-analyze/Android.mk
@@ -0,0 +1,14 @@
+LOCAL_PATH:= $(call my-dir)
+
+###################################
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := sepolicy-analyze
+LOCAL_MODULE_TAGS := optional
+LOCAL_C_INCLUDES := external/selinux/libsepol/include
+LOCAL_CFLAGS := -Wall -Werror
+LOCAL_SRC_FILES := sepolicy-analyze.c dups.c neverallow.c perm.c typecmp.c booleans.c attribute.c utils.c
+LOCAL_STATIC_LIBRARIES := libsepol
+LOCAL_CXX_STL := none
+
+include $(BUILD_HOST_EXECUTABLE)
diff --git a/sepolicy/tools/sepolicy-analyze/README b/sepolicy/tools/sepolicy-analyze/README
new file mode 100644
index 0000000..d18609a
--- /dev/null
+++ b/sepolicy/tools/sepolicy-analyze/README
@@ -0,0 +1,94 @@
+sepolicy-analyze
+    A component-ized tool for performing various kinds of analysis on a
+    sepolicy file.  The current kinds of analysis that are currently
+    supported include:
+
+    TYPE EQUIVALENCE (typecmp)
+    sepolicy-analyze out/target/product/<board>/root/sepolicy typecmp -e
+
+    Display all type pairs that are "equivalent", i.e. they are
+    identical with respect to allow rules, including indirect allow
+    rules via attributes and default-enabled conditional rules
+    (i.e. default boolean values yield a true conditional expression).
+
+    Equivalent types are candidates for being coalesced into a single
+    type.  However, there may be legitimate reasons for them to remain
+    separate, for example: - the types may differ in a respect not
+    included in the current analysis, such as default-disabled
+    conditional rules, audit-related rules (auditallow or dontaudit),
+    default type transitions, or constraints (e.g. mls), or - the
+    current policy may be overly permissive with respect to one or the
+    other of the types and thus the correct action may be to tighten
+    access to one or the other rather than coalescing them together,
+    or - the domains that would in fact have different accesses to the
+    types may not yet be defined or may be unconfined in the policy
+    you are analyzing.
+
+    TYPE DIFFERENCE (typecmp)
+    sepolicy-analyze out/target/product/<board>/root/sepolicy typecmp -d
+
+    Display type pairs that differ and the first difference found
+    between the two types.  This may be used in looking for similar
+    types that are not equivalent but may be candidates for coalescing.
+
+    DUPLICATE ALLOW RULES (dups)
+    sepolicy-analyze out/target/product/<board>/root/sepolicy dups
+
+    Displays duplicate allow rules, i.e. pairs of allow rules that
+    grant the same permissions where one allow rule is written
+    directly in terms of individual types and the other is written in
+    terms of attributes associated with those same types.  The rule
+    with individual types is a candidate for removal.  The rule with
+    individual types may be directly represented in the source policy
+    or may be a result of expansion of a type negation (e.g. domain
+    -foo -bar is expanded to individual allow rules by the policy
+    compiler).  Domains with unconfineddomain will typically have such
+    duplicate rules as a natural side effect and can be ignored.
+
+    PERMISSIVE DOMAINS (permissive)
+    sepolicy-analyze out/target/product/<board>/root/sepolicy permissive
+
+    Displays domains in the policy that are permissive, i.e. avc
+    denials are logged but not enforced for these domains.  While
+    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"]
+
+    Check whether the sepolicy file violates any of the neverallow rules
+    from the neverallows.conf file or a given string,  which contain neverallow
+    statements in the same format as the SELinux policy.conf file, i.e. after
+    m4 macro expansion of the rules from a .te file.  You can use an entire
+    policy.conf file as the neverallows.conf file and sepolicy-analyze will
+    ignore everything except for the neverallows within it.  You can also
+    specify this as a command-line string argument, which could be useful for
+    quickly checking an individual expanded rule or group of rules. If there are
+    no violations, sepolicy-analyze will exit successfully with no output.
+    Otherwise, sepolicy-analyze will report all violations and exit
+    with a non-zero exit status.
+
+    The -w or --warn option may be used to warn on any types, attributes,
+    classes, or permissions from a neverallow rule that could not be resolved
+    within the sepolicy file.  This can be normal due to differences between
+    the policy from which the neverallow rules were taken and the policy
+    being checked.  Such values are ignored for the purposes of neverallow
+    checking.
+
+    The -d or --debug option may be used to cause sepolicy-analyze to emit the
+    neverallow rules as it parses them.  This is principally a debugging facility
+    for the parser but could also be used to extract neverallow rules from
+    a full policy.conf file and output them in a more easily parsed format.
diff --git a/sepolicy/tools/sepolicy-analyze/attribute.c b/sepolicy/tools/sepolicy-analyze/attribute.c
new file mode 100644
index 0000000..474bda2
--- /dev/null
+++ b/sepolicy/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/sepolicy/tools/sepolicy-analyze/attribute.h b/sepolicy/tools/sepolicy-analyze/attribute.h
new file mode 100644
index 0000000..05adcbd
--- /dev/null
+++ b/sepolicy/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/sepolicy/tools/sepolicy-analyze/booleans.c b/sepolicy/tools/sepolicy-analyze/booleans.c
new file mode 100644
index 0000000..c3b605d
--- /dev/null
+++ b/sepolicy/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/sepolicy/tools/sepolicy-analyze/booleans.h b/sepolicy/tools/sepolicy-analyze/booleans.h
new file mode 100644
index 0000000..bfbe0e1
--- /dev/null
+++ b/sepolicy/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/sepolicy/tools/sepolicy-analyze/dups.c b/sepolicy/tools/sepolicy-analyze/dups.c
new file mode 100644
index 0000000..88c2be2
--- /dev/null
+++ b/sepolicy/tools/sepolicy-analyze/dups.c
@@ -0,0 +1,91 @@
+#include <stdbool.h>
+#include <stdio.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include "dups.h"
+
+void dups_usage() {
+    fprintf(stderr, "\tdups\n");
+}
+
+static int find_dups_helper(avtab_key_t * k, avtab_datum_t * d,
+                            void *args)
+{
+    policydb_t *policydb = args;
+    ebitmap_t *sattr, *tattr;
+    ebitmap_node_t *snode, *tnode;
+    unsigned int i, j;
+    avtab_key_t avkey;
+    avtab_ptr_t node;
+    struct type_datum *stype, *ttype, *stype2, *ttype2;
+    bool attrib1, attrib2;
+
+    if (!(k->specified & AVTAB_ALLOWED))
+        return 0;
+
+    if (k->source_type == k->target_type)
+        return 0; /* self rule */
+
+    avkey.target_class = k->target_class;
+    avkey.specified = k->specified;
+
+    sattr = &policydb->type_attr_map[k->source_type - 1];
+    tattr = &policydb->type_attr_map[k->target_type - 1];
+    stype = policydb->type_val_to_struct[k->source_type - 1];
+    ttype = policydb->type_val_to_struct[k->target_type - 1];
+    attrib1 = stype->flavor || ttype->flavor;
+    ebitmap_for_each_bit(sattr, snode, i) {
+        if (!ebitmap_node_get_bit(snode, i))
+            continue;
+        ebitmap_for_each_bit(tattr, tnode, j) {
+            if (!ebitmap_node_get_bit(tnode, j))
+                continue;
+            avkey.source_type = i + 1;
+            avkey.target_type = j + 1;
+            if (avkey.source_type == k->source_type &&
+                avkey.target_type == k->target_type)
+                continue;
+            if (avkey.source_type == avkey.target_type)
+                continue; /* self rule */
+            stype2 = policydb->type_val_to_struct[avkey.source_type - 1];
+            ttype2 = policydb->type_val_to_struct[avkey.target_type - 1];
+            attrib2 = stype2->flavor || ttype2->flavor;
+            if (attrib1 && attrib2)
+                continue; /* overlapping attribute-based rules */
+            for (node = avtab_search_node(&policydb->te_avtab, &avkey);
+                 node != NULL;
+                 node = avtab_search_node_next(node, avkey.specified)) {
+                uint32_t perms = node->datum.data & d->data;
+                if ((attrib1 && perms == node->datum.data) ||
+                    (attrib2 && perms == d->data)) {
+                    /*
+                     * The attribute-based rule is a superset of the
+                     * non-attribute-based rule.  This is a dup.
+                     */
+                    printf("Duplicate allow rule found:\n");
+                    display_allow(policydb, k, i, d->data);
+                    display_allow(policydb, &node->key, i, node->datum.data);
+                    printf("\n");
+                }
+            }
+        }
+    }
+
+    return 0;
+}
+
+static int find_dups(policydb_t * policydb)
+{
+    if (avtab_map(&policydb->te_avtab, find_dups_helper, policydb))
+        return -1;
+    return 0;
+}
+
+int dups_func (int argc, __attribute__ ((unused)) char **argv, policydb_t *policydb) {
+    if (argc != 1) {
+        USAGE_ERROR = true;
+        return -1;
+    }
+    return find_dups(policydb);
+}
diff --git a/sepolicy/tools/sepolicy-analyze/dups.h b/sepolicy/tools/sepolicy-analyze/dups.h
new file mode 100644
index 0000000..0e77224
--- /dev/null
+++ b/sepolicy/tools/sepolicy-analyze/dups.h
@@ -0,0 +1,11 @@
+#ifndef DUPS_H
+#define DUPS_H
+
+#include <sepol/policydb/policydb.h>
+
+#include "utils.h"
+
+void dups_usage(void);
+int dups_func(int argc, char **argv, policydb_t *policydb);
+
+#endif /* DUPS_H */
diff --git a/sepolicy/tools/sepolicy-analyze/neverallow.c b/sepolicy/tools/sepolicy-analyze/neverallow.c
new file mode 100644
index 0000000..b288ea7
--- /dev/null
+++ b/sepolicy/tools/sepolicy-analyze/neverallow.c
@@ -0,0 +1,515 @@
+#include <ctype.h>
+#include <fcntl.h>
+#include <getopt.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include "neverallow.h"
+
+static int debug;
+static int warn;
+
+void neverallow_usage() {
+    fprintf(stderr, "\tneverallow [-w|--warn] [-d|--debug] [-n|--neverallows <neverallow-rules>] | [-f|--file <neverallow-file>]\n");
+}
+
+static int read_typeset(policydb_t *policydb, char **ptr, char *end,
+                        type_set_t *typeset, uint32_t *flags)
+{
+    const char *keyword = "self";
+    size_t keyword_size = strlen(keyword), len;
+    char *p = *ptr;
+    unsigned openparens = 0;
+    char *start, *id;
+    type_datum_t *type;
+    struct ebitmap_node *n;
+    unsigned int bit;
+    bool negate = false;
+    int rc;
+
+    do {
+        while (p < end && isspace(*p))
+            p++;
+
+        if (p == end)
+            goto err;
+
+        if (*p == '~') {
+            if (debug)
+                printf(" ~");
+            typeset->flags = TYPE_COMP;
+            p++;
+            while (p < end && isspace(*p))
+                p++;
+            if (p == end)
+                goto err;
+        }
+
+        if (*p == '{') {
+            if (debug && !openparens)
+                printf(" {");
+            openparens++;
+            p++;
+            continue;
+        }
+
+        if (*p == '}') {
+            if (debug && openparens == 1)
+                printf(" }");
+            if (openparens == 0)
+                goto err;
+            openparens--;
+            p++;
+            continue;
+        }
+
+        if (*p == '*') {
+            if (debug)
+                printf(" *");
+            typeset->flags = TYPE_STAR;
+            p++;
+            continue;
+        }
+
+        if (*p == '-') {
+            if (debug)
+                printf(" -");
+            negate = true;
+            p++;
+            continue;
+        }
+
+        if (*p == '#') {
+            while (p < end && *p != '\n')
+                p++;
+            continue;
+        }
+
+        start = p;
+        while (p < end && !isspace(*p) && *p != ':' && *p != ';' && *p != '{' && *p != '}' && *p != '#')
+            p++;
+
+        if (p == start)
+            goto err;
+
+        len = p - start;
+        if (len == keyword_size && !strncmp(start, keyword, keyword_size)) {
+            if (debug)
+                printf(" self");
+            *flags |= RULE_SELF;
+            continue;
+        }
+
+        id = calloc(1, len + 1);
+        if (!id)
+            goto err;
+        memcpy(id, start, len);
+        if (debug)
+            printf(" %s", id);
+        type = hashtab_search(policydb->p_types.table, id);
+        if (!type) {
+            if (warn)
+                fprintf(stderr, "Warning!  Type or attribute %s used in neverallow undefined in policy being checked.\n", id);
+            negate = false;
+            continue;
+        }
+        free(id);
+
+        if (type->flavor == TYPE_ATTRIB) {
+            if (negate)
+                rc = ebitmap_union(&typeset->negset, &policydb->attr_type_map[type->s.value - 1]);
+            else
+                rc = ebitmap_union(&typeset->types, &policydb->attr_type_map[type->s.value - 1]);
+        } else if (negate) {
+            rc = ebitmap_set_bit(&typeset->negset, type->s.value - 1, 1);
+        } else {
+            rc = ebitmap_set_bit(&typeset->types, type->s.value - 1, 1);
+        }
+
+        negate = false;
+
+        if (rc)
+            goto err;
+
+    } while (p < end && openparens);
+
+    if (p == end)
+        goto err;
+
+    if (typeset->flags & TYPE_STAR) {
+        for (bit = 0; bit < policydb->p_types.nprim; bit++) {
+            if (ebitmap_get_bit(&typeset->negset, bit))
+                continue;
+            if (policydb->type_val_to_struct[bit] &&
+                policydb->type_val_to_struct[bit]->flavor == TYPE_ATTRIB)
+                continue;
+            if (ebitmap_set_bit(&typeset->types, bit, 1))
+                goto err;
+        }
+    }
+
+    ebitmap_for_each_bit(&typeset->negset, n, bit) {
+        if (!ebitmap_node_get_bit(n, bit))
+            continue;
+        if (ebitmap_set_bit(&typeset->types, bit, 0))
+            goto err;
+    }
+
+    if (typeset->flags & TYPE_COMP) {
+        for (bit = 0; bit < policydb->p_types.nprim; bit++) {
+            if (policydb->type_val_to_struct[bit] &&
+                policydb->type_val_to_struct[bit]->flavor == TYPE_ATTRIB)
+                continue;
+            if (ebitmap_get_bit(&typeset->types, bit))
+                ebitmap_set_bit(&typeset->types, bit, 0);
+            else {
+                if (ebitmap_set_bit(&typeset->types, bit, 1))
+                    goto err;
+            }
+        }
+    }
+
+    if (warn && ebitmap_length(&typeset->types) == 0 && !(*flags))
+        fprintf(stderr, "Warning!  Empty type set\n");
+
+    *ptr = p;
+    return 0;
+err:
+    return -1;
+}
+
+static int read_classperms(policydb_t *policydb, char **ptr, char *end,
+                           class_perm_node_t **perms)
+{
+    char *p = *ptr;
+    unsigned openparens = 0;
+    char *id, *start;
+    class_datum_t *cls = NULL;
+    perm_datum_t *perm = NULL;
+    class_perm_node_t *classperms = NULL, *node = NULL;
+    bool complement = false;
+
+    while (p < end && isspace(*p))
+        p++;
+
+    if (p == end || *p != ':')
+        goto err;
+    p++;
+
+    if (debug)
+        printf(" :");
+
+    do {
+        while (p < end && isspace(*p))
+            p++;
+
+        if (p == end)
+            goto err;
+
+        if (*p == '{') {
+            if (debug && !openparens)
+                printf(" {");
+            openparens++;
+            p++;
+            continue;
+        }
+
+        if (*p == '}') {
+            if (debug && openparens == 1)
+                printf(" }");
+            if (openparens == 0)
+                goto err;
+            openparens--;
+            p++;
+            continue;
+        }
+
+        if (*p == '#') {
+            while (p < end && *p != '\n')
+                p++;
+            continue;
+        }
+
+        start = p;
+        while (p < end && !isspace(*p) && *p != '{' && *p != '}' && *p != ';' && *p != '#')
+            p++;
+
+        if (p == start)
+            goto err;
+
+        id = calloc(1, p - start + 1);
+        if (!id)
+            goto err;
+        memcpy(id, start, p - start);
+        if (debug)
+            printf(" %s", id);
+        cls = hashtab_search(policydb->p_classes.table, id);
+        if (!cls) {
+            if (warn)
+                fprintf(stderr, "Warning!  Class %s used in neverallow undefined in policy being checked.\n", id);
+            continue;
+        }
+
+        node = calloc(1, sizeof *node);
+        if (!node)
+            goto err;
+        node->tclass = cls->s.value;
+        node->next = classperms;
+        classperms = node;
+        free(id);
+    } while (p < end && openparens);
+
+    if (p == end)
+        goto err;
+
+    if (warn && !classperms)
+        fprintf(stderr, "Warning!  Empty class set\n");
+
+    do {
+        while (p < end && isspace(*p))
+            p++;
+
+        if (p == end)
+            goto err;
+
+        if (*p == '~') {
+            if (debug)
+                printf(" ~");
+            complement = true;
+            p++;
+            while (p < end && isspace(*p))
+                p++;
+            if (p == end)
+                goto err;
+        }
+
+        if (*p == '{') {
+            if (debug && !openparens)
+                printf(" {");
+            openparens++;
+            p++;
+            continue;
+        }
+
+        if (*p == '}') {
+            if (debug && openparens == 1)
+                printf(" }");
+            if (openparens == 0)
+                goto err;
+            openparens--;
+            p++;
+            continue;
+        }
+
+        if (*p == '#') {
+            while (p < end && *p != '\n')
+                p++;
+            continue;
+        }
+
+        start = p;
+        while (p < end && !isspace(*p) && *p != '{' && *p != '}' && *p != ';' && *p != '#')
+            p++;
+
+        if (p == start)
+            goto err;
+
+        id = calloc(1, p - start + 1);
+        if (!id)
+            goto err;
+        memcpy(id, start, p - start);
+        if (debug)
+            printf(" %s", id);
+
+        if (!strcmp(id, "*")) {
+            for (node = classperms; node; node = node->next)
+                node->data = ~0;
+            continue;
+        }
+
+        for (node = classperms; node; node = node->next) {
+            cls = policydb->class_val_to_struct[node->tclass-1];
+            perm = hashtab_search(cls->permissions.table, id);
+            if (cls->comdatum && !perm)
+                perm = hashtab_search(cls->comdatum->permissions.table, id);
+            if (!perm) {
+                if (warn)
+                    fprintf(stderr, "Warning!  Permission %s used in neverallow undefined in class %s in policy being checked.\n", id, policydb->p_class_val_to_name[node->tclass-1]);
+                continue;
+            }
+            node->data |= 1U << (perm->s.value - 1);
+        }
+        free(id);
+    } while (p < end && openparens);
+
+    if (p == end)
+        goto err;
+
+    if (complement) {
+        for (node = classperms; node; node = node->next)
+            node->data = ~node->data;
+    }
+
+    if (warn) {
+        for (node = classperms; node; node = node->next)
+            if (!node->data)
+                fprintf(stderr, "Warning!  Empty permission set\n");
+    }
+
+    *perms = classperms;
+    *ptr = p;
+    return 0;
+err:
+    return -1;
+}
+
+static int check_neverallows(policydb_t *policydb, char *text, char *end)
+{
+    const char *keyword = "neverallow";
+    size_t keyword_size = strlen(keyword), len;
+    struct avrule *neverallows = NULL, *avrule;
+    char *p, *start;
+
+    p = text;
+    while (p < end) {
+        while (p < end && isspace(*p))
+            p++;
+
+        if (*p == '#') {
+            while (p < end && *p != '\n')
+                p++;
+            continue;
+        }
+
+        start = p;
+        while (p < end && !isspace(*p))
+            p++;
+
+        len = p - start;
+        if (len != keyword_size || strncmp(start, keyword, keyword_size))
+            continue;
+
+        if (debug)
+            printf("neverallow");
+
+        avrule = calloc(1, sizeof *avrule);
+        if (!avrule)
+            goto err;
+
+        avrule->specified = AVRULE_NEVERALLOW;
+
+        if (read_typeset(policydb, &p, end, &avrule->stypes, &avrule->flags))
+            goto err;
+
+        if (read_typeset(policydb, &p, end, &avrule->ttypes, &avrule->flags))
+            goto err;
+
+        if (read_classperms(policydb, &p, end, &avrule->perms))
+            goto err;
+
+        while (p < end && *p != ';')
+            p++;
+
+        if (p == end || *p != ';')
+            goto err;
+
+        if (debug)
+            printf(";\n");
+
+        avrule->next = neverallows;
+        neverallows = avrule;
+    }
+
+    if (!neverallows)
+        goto err;
+
+    return check_assertions(NULL, policydb, neverallows);
+err:
+    if (errno == ENOMEM) {
+        fprintf(stderr, "Out of memory while parsing neverallow rules\n");
+    } else
+        fprintf(stderr, "Error while parsing neverallow rules\n");
+    return -1;
+}
+
+static int check_neverallows_file(policydb_t *policydb, const char *filename)
+{
+    int fd;
+    struct stat sb;
+    char *text, *end;
+
+    fd = open(filename, O_RDONLY);
+    if (fd < 0) {
+        fprintf(stderr, "Could not open %s:  %s\n", filename, strerror(errno));
+        return -1;
+    }
+    if (fstat(fd, &sb) < 0) {
+        fprintf(stderr, "Can't stat '%s':  %s\n", filename, strerror(errno));
+        close(fd);
+        return -1;
+    }
+    text = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
+    end = text + sb.st_size;
+    if (text == MAP_FAILED) {
+        fprintf(stderr, "Can't mmap '%s':  %s\n", filename, strerror(errno));
+        close(fd);
+        return -1;
+    }
+    close(fd);
+    return check_neverallows(policydb, text, end);
+}
+
+static int check_neverallows_string(policydb_t *policydb, char *string, size_t len)
+{
+    char *text, *end;
+    text = string;
+    end = text + len;
+    return check_neverallows(policydb, text, end);
+}
+
+int neverallow_func (int argc, char **argv, policydb_t *policydb) {
+    char *rules = 0, *file = 0;
+    char ch;
+
+    struct option neverallow_options[] = {
+        {"debug", no_argument, NULL, 'd'},
+        {"file_input", required_argument, NULL, 'f'},
+        {"neverallow", required_argument, NULL, 'n'},
+        {"warn", no_argument, NULL, 'w'},
+        {NULL, 0, NULL, 0}
+    };
+
+    while ((ch = getopt_long(argc, argv, "df:n:w", neverallow_options, NULL)) != -1) {
+        switch (ch) {
+        case 'd':
+            debug = 1;
+            break;
+        case 'f':
+            file = optarg;
+            break;
+        case 'n':
+            rules = optarg;
+            break;
+        case 'w':
+            warn = 1;
+            break;
+        default:
+            USAGE_ERROR = true;
+            return -1;
+        }
+    }
+
+    if (!(rules || file) || (rules && file)){
+        USAGE_ERROR = true;
+        return -1;
+    }
+    if (file) {
+        return check_neverallows_file(policydb, file);
+    } else {
+        return check_neverallows_string(policydb, rules, strlen(rules));
+    }
+}
diff --git a/sepolicy/tools/sepolicy-analyze/neverallow.h b/sepolicy/tools/sepolicy-analyze/neverallow.h
new file mode 100644
index 0000000..be80822
--- /dev/null
+++ b/sepolicy/tools/sepolicy-analyze/neverallow.h
@@ -0,0 +1,11 @@
+#ifndef NEVERALLOW_H
+#define NEVERALLOW_H
+
+#include <sepol/policydb/policydb.h>
+
+#include "utils.h"
+
+void neverallow_usage(void);
+int neverallow_func(int argc, char **argv, policydb_t *policydb);
+
+#endif /* NEVERALLOW_H */
diff --git a/sepolicy/tools/sepolicy-analyze/perm.c b/sepolicy/tools/sepolicy-analyze/perm.c
new file mode 100644
index 0000000..4cc4869
--- /dev/null
+++ b/sepolicy/tools/sepolicy-analyze/perm.c
@@ -0,0 +1,30 @@
+#include "perm.h"
+
+void permissive_usage() {
+    fprintf(stderr, "\tpermissive\n");
+}
+
+static int list_permissive(policydb_t * policydb)
+{
+    struct ebitmap_node *n;
+    unsigned int bit;
+
+    /*
+     * iterate over all domains and check if domain is in permissive
+     */
+    ebitmap_for_each_bit(&policydb->permissive_map, n, bit)
+    {
+        if (ebitmap_node_get_bit(n, bit)) {
+            printf("%s\n", policydb->p_type_val_to_name[bit -1]);
+        }
+    }
+    return 0;
+}
+
+int permissive_func (int argc, __attribute__ ((unused)) char **argv, policydb_t *policydb) {
+    if (argc != 1) {
+        USAGE_ERROR = true;
+        return -1;
+    }
+    return list_permissive(policydb);
+}
diff --git a/sepolicy/tools/sepolicy-analyze/perm.h b/sepolicy/tools/sepolicy-analyze/perm.h
new file mode 100644
index 0000000..16e619a
--- /dev/null
+++ b/sepolicy/tools/sepolicy-analyze/perm.h
@@ -0,0 +1,11 @@
+#ifndef PERM_H
+#define PERM_H
+
+#include <sepol/policydb/policydb.h>
+
+#include "utils.h"
+
+void permissive_usage(void);
+int permissive_func(int argc, char **argv, policydb_t *policydb);
+
+#endif /* PERM_H */
diff --git a/sepolicy/tools/sepolicy-analyze/sepolicy-analyze.c b/sepolicy/tools/sepolicy-analyze/sepolicy-analyze.c
new file mode 100644
index 0000000..b70eaaa
--- /dev/null
+++ b/sepolicy/tools/sepolicy-analyze/sepolicy-analyze.c
@@ -0,0 +1,65 @@
+#include <stddef.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "dups.h"
+#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]))
+
+#define COMP(x) { #x, sizeof(#x) - 1, x ##_usage, x ##_func }
+static struct {
+    const char *key;
+    size_t keylen;
+    void (*usage) (void);
+    int (*func) (int argc, char **argv, policydb_t *policydb);
+} analyze_components[] = {
+    COMP(dups),
+    COMP(neverallow),
+    COMP(permissive),
+    COMP(typecmp),
+    COMP(booleans),
+    COMP(attribute)
+};
+
+void usage(char *arg0)
+{
+    int i;
+
+    fprintf(stderr, "%s must be called on a policy file with a component and the appropriate arguments specified\n", arg0);
+    fprintf(stderr, "%s <policy-file>:\n", arg0);
+    for(i = 0; i < NUM_COMPONENTS; i++) {
+        analyze_components[i].usage();
+    }
+    exit(1);
+}
+
+int main(int argc, char **argv)
+{
+    char *policy;
+    struct policy_file pf;
+    policydb_t policydb;
+    int rc;
+    int i;
+
+    if (argc < 3)
+        usage(argv[0]);
+    policy = argv[1];
+    if(load_policy(policy, &policydb, &pf))
+        exit(1);
+    for(i = 0; i < NUM_COMPONENTS; i++) {
+        if (!strcmp(analyze_components[i].key, argv[2])) {
+            rc = analyze_components[i].func(argc - 2, argv + 2, &policydb);
+            if (rc && USAGE_ERROR) {
+                usage(argv[0]); }
+            return rc;
+        }
+    }
+    usage(argv[0]);
+    exit(0);
+}
diff --git a/sepolicy/tools/sepolicy-analyze/typecmp.c b/sepolicy/tools/sepolicy-analyze/typecmp.c
new file mode 100644
index 0000000..5fffd63
--- /dev/null
+++ b/sepolicy/tools/sepolicy-analyze/typecmp.c
@@ -0,0 +1,295 @@
+#include <getopt.h>
+#include <sepol/policydb/expand.h>
+
+#include "typecmp.h"
+
+void typecmp_usage() {
+    fprintf(stderr, "\ttypecmp [-d|--diff] [-e|--equiv]\n");
+}
+
+static int insert_type_rule(avtab_key_t * k, avtab_datum_t * d,
+                            struct avtab_node *type_rules)
+{
+    struct avtab_node *p, *c, *n;
+
+    for (p = type_rules, c = type_rules->next; c; p = c, c = c->next) {
+        /*
+         * Find the insertion point, keeping the list
+         * ordered by source type, then target type, then
+         * target class.
+         */
+        if (k->source_type < c->key.source_type)
+            break;
+        if (k->source_type == c->key.source_type &&
+            k->target_type < c->key.target_type)
+            break;
+        if (k->source_type == c->key.source_type &&
+            k->target_type == c->key.target_type &&
+            k->target_class <= c->key.target_class)
+            break;
+    }
+
+    if (c &&
+        k->source_type == c->key.source_type &&
+        k->target_type == c->key.target_type &&
+        k->target_class == c->key.target_class) {
+        c->datum.data |= d->data;
+        return 0;
+    }
+
+    /* Insert the rule */
+    n = malloc(sizeof(struct avtab_node));
+    if (!n) {
+        fprintf(stderr, "out of memory\n");
+        exit(1);
+    }
+
+    n->key = *k;
+    n->datum = *d;
+    n->next = p->next;
+    p->next = n;
+    return 0;
+}
+
+static int create_type_rules_helper(avtab_key_t * k, avtab_datum_t * d,
+                                    void *args)
+{
+    struct avtab_node *type_rules = args;
+    avtab_key_t key;
+
+    /*
+     * Insert the rule into the list for
+     * the source type.  The source type value
+     * is cleared as we want to compare against other type
+     * rules with different source types.
+     */
+    key = *k;
+    key.source_type = 0;
+    if (k->source_type == k->target_type) {
+        /* Clear target type as well; this is a self rule. */
+        key.target_type = 0;
+    }
+    if (insert_type_rule(&key, d, &type_rules[k->source_type - 1]))
+        return -1;
+
+    if (k->source_type == k->target_type)
+        return 0;
+
+    /*
+     * If the target type differs, then we also
+     * insert the rule into the list for the target
+     * type.  We clear the target type value so that
+     * we can compare against other type rules with
+     * different target types.
+     */
+    key = *k;
+    key.target_type = 0;
+    if (insert_type_rule(&key, d, &type_rules[k->target_type - 1]))
+        return -1;
+
+    return 0;
+}
+
+static int create_type_rules(avtab_key_t * k, avtab_datum_t * d, void *args)
+{
+    if (k->specified & AVTAB_ALLOWED)
+        return create_type_rules_helper(k, d, args);
+    return 0;
+}
+
+static int create_type_rules_cond(avtab_key_t * k, avtab_datum_t * d,
+                                  void *args)
+{
+    if ((k->specified & (AVTAB_ALLOWED|AVTAB_ENABLED)) ==
+        (AVTAB_ALLOWED|AVTAB_ENABLED))
+        return create_type_rules_helper(k, d, args);
+    return 0;
+}
+
+static void free_type_rules(struct avtab_node *l)
+{
+    struct avtab_node *tmp;
+
+    while (l) {
+        tmp = l;
+        l = l->next;
+        free(tmp);
+    }
+}
+
+static int find_match(policydb_t *policydb, struct avtab_node *l1,
+                      int idx1, struct avtab_node *l2, int idx2)
+{
+    struct avtab_node *c;
+    uint32_t perms1, perms2;
+
+    for (c = l2; c; c = c->next) {
+        if (l1->key.source_type < c->key.source_type)
+            break;
+        if (l1->key.source_type == c->key.source_type &&
+            l1->key.target_type < c->key.target_type)
+            break;
+        if (l1->key.source_type == c->key.source_type &&
+            l1->key.target_type == c->key.target_type &&
+            l1->key.target_class <= c->key.target_class)
+            break;
+    }
+
+    if (c &&
+        l1->key.source_type == c->key.source_type &&
+        l1->key.target_type == c->key.target_type &&
+        l1->key.target_class == c->key.target_class) {
+        perms1 = l1->datum.data & ~c->datum.data;
+        perms2 = c->datum.data & ~l1->datum.data;
+        if (perms1 || perms2) {
+            if (perms1)
+                display_allow(policydb, &l1->key, idx1, perms1);
+            if (perms2)
+                display_allow(policydb, &c->key, idx2, perms2);
+            printf("\n");
+            return 1;
+        }
+    }
+
+    return 0;
+}
+
+static int analyze_types(policydb_t * policydb, char diff, char equiv)
+{
+    avtab_t exp_avtab, exp_cond_avtab;
+    struct avtab_node *type_rules, *l1, *l2;
+    struct type_datum *type;
+    size_t i, j;
+
+    /*
+     * Create a list of access vector rules for each type
+     * from the access vector table.
+     */
+    type_rules = malloc(sizeof(struct avtab_node) * policydb->p_types.nprim);
+    if (!type_rules) {
+        fprintf(stderr, "out of memory\n");
+        exit(1);
+    }
+    memset(type_rules, 0, sizeof(struct avtab_node) * policydb->p_types.nprim);
+
+    if (avtab_init(&exp_avtab) || avtab_init(&exp_cond_avtab)) {
+        fputs("out of memory\n", stderr);
+        return -1;
+    }
+
+    if (expand_avtab(policydb, &policydb->te_avtab, &exp_avtab)) {
+        fputs("out of memory\n", stderr);
+        avtab_destroy(&exp_avtab);
+        return -1;
+    }
+
+    if (expand_avtab(policydb, &policydb->te_cond_avtab, &exp_cond_avtab)) {
+        fputs("out of memory\n", stderr);
+        avtab_destroy(&exp_avtab); /*  */
+        return -1;
+    }
+
+    if (avtab_map(&exp_avtab, create_type_rules, type_rules))
+        exit(1);
+
+    if (avtab_map(&exp_cond_avtab, create_type_rules_cond, type_rules))
+        exit(1);
+
+    avtab_destroy(&exp_avtab);
+    avtab_destroy(&exp_cond_avtab);
+
+    /*
+     * Compare the type lists and identify similar types.
+     */
+    for (i = 0; i < policydb->p_types.nprim - 1; i++) {
+        if (!type_rules[i].next)
+            continue;
+        type = policydb->type_val_to_struct[i];
+        if (type->flavor) {
+            free_type_rules(type_rules[i].next);
+            type_rules[i].next = NULL;
+            continue;
+        }
+        for (j = i + 1; j < policydb->p_types.nprim; j++) {
+            type = policydb->type_val_to_struct[j];
+            if (type->flavor) {
+                free_type_rules(type_rules[j].next);
+                type_rules[j].next = NULL;
+                continue;
+            }
+            for (l1 = type_rules[i].next, l2 = type_rules[j].next;
+                 l1 && l2; l1 = l1->next, l2 = l2->next) {
+                if (l1->key.source_type != l2->key.source_type)
+                    break;
+                if (l1->key.target_type != l2->key.target_type)
+                    break;
+                if (l1->key.target_class != l2->key.target_class
+                    || l1->datum.data != l2->datum.data)
+                    break;
+            }
+            if (l1 || l2) {
+                if (diff) {
+                    printf
+                        ("Types %s and %s differ, starting with:\n",
+                         policydb->p_type_val_to_name[i],
+                         policydb->p_type_val_to_name[j]);
+
+                    if (l1 && l2) {
+                        if (find_match(policydb, l1, i, l2, j))
+                            continue;
+                        if (find_match(policydb, l2, j, l1, i))
+                            continue;
+                    }
+                    if (l1)
+                        display_allow(policydb, &l1->key, i, l1->datum.data);
+                    if (l2)
+                        display_allow(policydb, &l2->key, j, l2->datum.data);
+                    printf("\n");
+                }
+                continue;
+            }
+            free_type_rules(type_rules[j].next);
+            type_rules[j].next = NULL;
+            if (equiv) {
+                printf("Types %s and %s are equivalent.\n",
+                       policydb->p_type_val_to_name[i],
+                       policydb->p_type_val_to_name[j]);
+            }
+        }
+        free_type_rules(type_rules[i].next);
+        type_rules[i].next = NULL;
+    }
+
+    free(type_rules);
+    return 0;
+}
+
+int typecmp_func (int argc, char **argv, policydb_t *policydb) {
+    char ch, diff = 0, equiv = 0;
+
+    struct option typecmp_options[] = {
+        {"diff", no_argument, NULL, 'd'},
+        {"equiv", no_argument, NULL, 'e'},
+        {NULL, 0, NULL, 0}
+    };
+
+    while ((ch = getopt_long(argc, argv, "de", typecmp_options, NULL)) != -1) {
+        switch (ch) {
+        case 'd':
+            diff = 1;
+            break;
+        case 'e':
+            equiv = 1;
+            break;
+        default:
+            USAGE_ERROR = true;
+            return -1;
+        }
+    }
+
+    if (!(diff || equiv)) {
+        USAGE_ERROR = true;
+        return -1;
+    }
+    return analyze_types(policydb, diff, equiv);
+}
diff --git a/sepolicy/tools/sepolicy-analyze/typecmp.h b/sepolicy/tools/sepolicy-analyze/typecmp.h
new file mode 100644
index 0000000..f93daaa
--- /dev/null
+++ b/sepolicy/tools/sepolicy-analyze/typecmp.h
@@ -0,0 +1,11 @@
+#ifndef TYPECMP_H
+#define TYPECMP_H
+
+#include <sepol/policydb/policydb.h>
+
+#include "utils.h"
+
+void typecmp_usage(void);
+int typecmp_func(int argc, char **argv, policydb_t *policydb);
+
+#endif /* TYPECMP_H */
diff --git a/sepolicy/tools/sepolicy-analyze/utils.c b/sepolicy/tools/sepolicy-analyze/utils.c
new file mode 100644
index 0000000..5e52f59
--- /dev/null
+++ b/sepolicy/tools/sepolicy-analyze/utils.c
@@ -0,0 +1,68 @@
+#include <fcntl.h>
+#include <sepol/policydb/policydb.h>
+#include <sepol/policydb/util.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include "utils.h"
+
+bool USAGE_ERROR = false;
+
+void display_allow(policydb_t *policydb, avtab_key_t *key, int idx, uint32_t perms)
+{
+    printf("    allow %s %s:%s { %s };\n",
+           policydb->p_type_val_to_name[key->source_type
+                                        ? key->source_type - 1 : idx],
+           key->target_type == key->source_type ? "self" :
+           policydb->p_type_val_to_name[key->target_type
+                                        ? key->target_type - 1 : idx],
+           policydb->p_class_val_to_name[key->target_class - 1],
+           sepol_av_to_string
+           (policydb, key->target_class, perms));
+}
+
+int load_policy(char *filename, policydb_t * policydb, struct policy_file *pf)
+{
+    int fd;
+    struct stat sb;
+    void *map;
+    int ret;
+
+    fd = open(filename, O_RDONLY);
+    if (fd < 0) {
+        fprintf(stderr, "Can't open '%s':  %s\n", filename, strerror(errno));
+        return 1;
+    }
+    if (fstat(fd, &sb) < 0) {
+        fprintf(stderr, "Can't stat '%s':  %s\n", filename, strerror(errno));
+        close(fd);
+        return 1;
+    }
+    map = mmap(NULL, sb.st_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
+    if (map == MAP_FAILED) {
+        fprintf(stderr, "Can't mmap '%s':  %s\n", filename, strerror(errno));
+        close(fd);
+        return 1;
+    }
+
+    policy_file_init(pf);
+    pf->type = PF_USE_MEMORY;
+    pf->data = map;
+    pf->len = sb.st_size;
+    if (policydb_init(policydb)) {
+        fprintf(stderr, "Could not initialize policydb!\n");
+        close(fd);
+        munmap(map, sb.st_size);
+        return 1;
+    }
+    ret = policydb_read(policydb, pf, 0);
+    if (ret) {
+        fprintf(stderr, "error(s) encountered while parsing configuration\n");
+        close(fd);
+        munmap(map, sb.st_size);
+        return 1;
+    }
+
+    return 0;
+}
diff --git a/sepolicy/tools/sepolicy-analyze/utils.h b/sepolicy/tools/sepolicy-analyze/utils.h
new file mode 100644
index 0000000..83f5a78
--- /dev/null
+++ b/sepolicy/tools/sepolicy-analyze/utils.h
@@ -0,0 +1,16 @@
+#ifndef UTILS_H
+#define UTILS_H
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <sepol/policydb/avtab.h>
+#include <sepol/policydb/policydb.h>
+
+
+extern bool USAGE_ERROR;
+
+void display_allow(policydb_t *policydb, avtab_key_t *key, int idx, uint32_t perms);
+
+int load_policy(char *filename, policydb_t * policydb, struct policy_file *pf);
+
+#endif /* UTILS_H */
diff --git a/sepolicy/tools/sepolicy-check.c b/sepolicy/tools/sepolicy-check.c
new file mode 100644
index 0000000..713e7c1
--- /dev/null
+++ b/sepolicy/tools/sepolicy-check.c
@@ -0,0 +1,296 @@
+#include <getopt.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <sepol/policydb/policydb.h>
+#include <sepol/policydb/services.h>
+#include <sepol/policydb/expand.h>
+
+#define EQUALS 0
+#define NOT 1
+#define ANY 2
+
+void usage(char *arg0) {
+	fprintf(stderr, "%s -s <source> -t <target> -c <class> -p <perm> -P <policy file>\n", arg0);
+	exit(1);
+}
+
+void *cmalloc(size_t s) {
+	void *t = malloc(s);
+	if (t == NULL) {
+		fprintf(stderr, "Out of memory\n");
+		exit(1);
+	}
+	return t;
+}
+
+int parse_ops(char **arg) {
+	switch (*arg[0]) {
+		case '-':
+			*arg = *arg + 1;
+			return NOT;
+		case '*':
+			return ANY;
+		default:
+			return EQUALS;
+	}
+}
+
+int check(int op, uint16_t arg1, uint16_t arg2) {
+	switch (op) {
+		case EQUALS:
+			return arg1 == arg2;
+		case NOT:
+			return arg1 != arg2;
+		case ANY:
+			return 1;
+		default:
+			fprintf(stderr, "Bad op while checking!");
+			return 2;
+	}
+}
+
+int check_perm(avtab_ptr_t current, perm_datum_t *perm) {
+	uint16_t perm_bitmask = 1U << (perm->s.value - 1);
+	return (current->datum.data & perm_bitmask) != 0;
+}
+
+
+int expand_and_check(int s_op, uint32_t source_type,
+		     int t_op, uint32_t target_type,
+		     int c_op, uint32_t target_class,
+		     perm_datum_t *perm, policydb_t *policy, avtab_t *avtab) {
+	avtab_t exp_avtab;
+	avtab_ptr_t cur;
+	unsigned int i;
+	int match;
+
+	if (avtab_init(&exp_avtab)) {
+		fputs("out of memory\n", stderr);
+		return -1;
+	}
+
+	if (expand_avtab(policy, avtab, &exp_avtab)) {
+		fputs("out of memory\n", stderr);
+		avtab_destroy(&exp_avtab);
+		return -1;
+	}
+
+	for (i = 0; i < exp_avtab.nslot; i++) {
+		for (cur = exp_avtab.htable[i]; cur; cur = cur->next) {
+			match = 1;
+			match &= check(s_op, source_type, cur->key.source_type);
+			match &= check(t_op, target_type, cur->key.target_type);
+			match &= check(c_op, target_class, cur->key.target_class);
+			match &= check_perm(cur, perm);
+			if (match) {
+				avtab_destroy(&exp_avtab);
+				return 1;
+			}
+		}
+	}
+
+	avtab_destroy(&exp_avtab);
+	return 0;
+}
+
+/*
+ * Checks to see if a rule matching the given arguments already exists.
+ *
+ * The format for the arguments is as follows:
+ *
+ * - A bare string is treated as a literal and will be matched by equality.
+ * - A string starting with "-" will be matched by inequality.
+ * - A string starting with "*" will be treated as a wildcard.
+ *
+ * The return codes for this function are as follows:
+ *
+ * - 0 indicates a successful return without a match
+ * - 1 indicates a successful return with a match
+ * - -1 indicates an error
+ */
+int check_rule(char *s, char *t, char *c, char *p, policydb_t *policy) {
+	type_datum_t *src = NULL;
+	type_datum_t *tgt = NULL;
+	class_datum_t *cls = NULL;
+	perm_datum_t *perm = NULL;
+	int s_op = parse_ops(&s);
+	int t_op = parse_ops(&t);
+	int c_op = parse_ops(&c);
+	int p_op = parse_ops(&p);
+	avtab_key_t key;
+	int match;
+
+	key.source_type = key.target_type = key.target_class = 0;
+
+	if (s_op != ANY) {
+		src = hashtab_search(policy->p_types.table, s);
+		if (src == NULL) {
+			fprintf(stderr, "source type %s does not exist\n", s);
+			return -1;
+		}
+	}
+	if (t_op != ANY) {
+		tgt = hashtab_search(policy->p_types.table, t);
+		if (tgt == NULL) {
+			fprintf(stderr, "target type %s does not exist\n", t);
+			return -1;
+		}
+	}
+	if (c_op != ANY) {
+		cls = hashtab_search(policy->p_classes.table, c);
+		if (cls == NULL) {
+			fprintf(stderr, "class %s does not exist\n", c);
+			return -1;
+		}
+	}
+	if (p_op != ANY) {
+		perm = hashtab_search(cls->permissions.table, p);
+		if (perm == NULL) {
+			if (cls->comdatum == NULL) {
+				fprintf(stderr, "perm %s does not exist in class %s\n", p, c);
+				return -1;
+			}
+			perm = hashtab_search(cls->comdatum->permissions.table, p);
+			if (perm == NULL) {
+				fprintf(stderr, "perm %s does not exist in class %s\n", p, c);
+				return -1;
+			}
+		}
+	}
+
+	if (s_op != ANY)
+		key.source_type = src->s.value;
+	if (t_op != ANY)
+		key.target_type = tgt->s.value;
+	if (c_op != ANY)
+		key.target_class = cls->s.value;
+
+	/* Check unconditional rules after attribute expansion. */
+	match = expand_and_check(s_op, key.source_type,
+				 t_op, key.target_type,
+				 c_op, key.target_class,
+				 perm, policy, &policy->te_avtab);
+	if (match)
+		return match;
+
+	/* Check conditional rules after attribute expansion. */
+	return expand_and_check(s_op, key.source_type,
+				t_op, key.target_type,
+				c_op, key.target_class,
+				perm, policy, &policy->te_cond_avtab);
+}
+
+int load_policy(char *filename, policydb_t *policydb, struct policy_file *pf) {
+	int fd;
+	struct stat sb;
+	void *map;
+	int ret;
+
+	fd = open(filename, O_RDONLY);
+	if (fd < 0) {
+		fprintf(stderr, "Can't open '%s':  %s\n", filename, strerror(errno));
+		return 1;
+	}
+	if (fstat(fd, &sb) < 0) {
+		fprintf(stderr, "Can't stat '%s':  %s\n", filename, strerror(errno));
+		close(fd);
+		return 1;
+	}
+	map = mmap(NULL, sb.st_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
+	if (map == MAP_FAILED) {
+		fprintf(stderr, "Can't mmap '%s':  %s\n", filename, strerror(errno));
+		close(fd);
+		return 1;
+	}
+
+	policy_file_init(pf);
+	pf->type = PF_USE_MEMORY;
+	pf->data = map;
+	pf->len = sb.st_size;
+	if (policydb_init(policydb)) {
+		fprintf(stderr, "Could not initialize policydb!\n");
+		close(fd);
+		munmap(map, sb.st_size);
+		return 1;
+	}
+	ret = policydb_read(policydb, pf, 0);
+	if (ret) {
+		fprintf(stderr, "error(s) encountered while parsing configuration\n");
+		close(fd);
+		munmap(map, sb.st_size);
+		return 1;
+	}
+
+	return 0;
+}
+
+
+int main(int argc, char **argv)
+{
+	char *policy = NULL, *source = NULL, *target = NULL, *class = NULL, *perm = NULL;
+	policydb_t policydb;
+	struct policy_file pf;
+	sidtab_t sidtab;
+	char ch;
+	int match = 1;
+
+	struct option long_options[] = {
+			{"source", required_argument, NULL, 's'},
+			{"target", required_argument, NULL, 't'},
+			{"class", required_argument, NULL, 'c'},
+			{"perm", required_argument, NULL, 'p'},
+			{"policy", required_argument, NULL, 'P'},
+			{NULL, 0, NULL, 0}
+	};
+
+	while ((ch = getopt_long(argc, argv, "s:t:c:p:P:", long_options, NULL)) != -1) {
+		switch (ch) {
+			case 's':
+				source = optarg;
+				break;
+			case 't':
+				target = optarg;
+				break;
+			case 'c':
+				class = optarg;
+				break;
+			case 'p':
+				perm = optarg;
+				break;
+			case 'P':
+				policy = optarg;
+				break;
+			default:
+				usage(argv[0]);
+		}
+	}
+
+	if (!source || !target || !class || !perm || !policy)
+		usage(argv[0]);
+
+	sepol_set_policydb(&policydb);
+	sepol_set_sidtab(&sidtab);
+
+	if (load_policy(policy, &policydb, &pf))
+		goto out;
+
+	match = check_rule(source, target, class, perm, &policydb);
+	if (match < 0) {
+		fprintf(stderr, "Error checking rules!\n");
+		goto out;
+	} else if (match > 0) {
+		printf("Match found!\n");
+		goto out;
+	}
+
+	match = 0;
+
+out:
+	policydb_destroy(&policydb);
+	return match;
+}
diff --git a/sepolicy/tzdatacheck.te b/sepolicy/tzdatacheck.te
new file mode 100644
index 0000000..f61cb47
--- /dev/null
+++ b/sepolicy/tzdatacheck.te
@@ -0,0 +1,8 @@
+# The tzdatacheck command run by init.
+type tzdatacheck, domain, domain_deprecated;
+type tzdatacheck_exec, exec_type, file_type;
+
+init_daemon_domain(tzdatacheck)
+
+allow tzdatacheck zoneinfo_data_file:dir create_dir_perms;
+allow tzdatacheck zoneinfo_data_file:file unlink;
diff --git a/sepolicy/ueventd.te b/sepolicy/ueventd.te
new file mode 100644
index 0000000..f1576e7
--- /dev/null
+++ b/sepolicy/ueventd.te
@@ -0,0 +1,45 @@
+# ueventd seclabel is specified in init.rc since
+# it lives in the rootfs and has no unique file type.
+type ueventd, domain, domain_deprecated;
+tmpfs_domain(ueventd)
+
+# Write to /dev/kmsg.
+allow ueventd kmsg_device:chr_file rw_file_perms;
+
+allow ueventd self:capability { chown mknod net_admin setgid fsetid sys_rawio dac_override fowner };
+allow ueventd device:file create_file_perms;
+allow ueventd device:chr_file rw_file_perms;
+allow ueventd sysfs:file rw_file_perms;
+allow ueventd sysfs_hwrandom:file w_file_perms;
+allow ueventd sysfs_zram_uevent:file w_file_perms;
+allow ueventd sysfs_type:{ file lnk_file } { relabelfrom relabelto setattr getattr };
+allow ueventd sysfs_type:dir { relabelfrom relabelto setattr r_dir_perms };
+allow ueventd sysfs_devices_system_cpu:file rw_file_perms;
+allow ueventd tmpfs:chr_file rw_file_perms;
+allow ueventd dev_type:dir create_dir_perms;
+allow ueventd dev_type:lnk_file { create unlink };
+allow ueventd dev_type:chr_file { getattr create setattr unlink };
+allow ueventd dev_type:blk_file { getattr relabelfrom relabelto create setattr unlink };
+allow ueventd self:netlink_kobject_uevent_socket create_socket_perms;
+allow ueventd efs_file:dir search;
+allow ueventd efs_file:file r_file_perms;
+
+# Use setfscreatecon() to label /dev directories and files.
+allow ueventd self:process setfscreate;
+
+#####
+##### neverallow rules
+#####
+
+# ueventd must never set properties, otherwise deadlocks may occur.
+# https://android-review.googlesource.com/#/c/133120/6/init/devices.cpp@941
+# No writing to the property socket, connecting to init, or setting properties.
+neverallow ueventd property_socket:sock_file write;
+neverallow ueventd init:unix_stream_socket connectto;
+neverallow ueventd property_type:property_service set;
+
+# Restrict ueventd access on block devices to maintenence operations.
+neverallow ueventd dev_type:blk_file ~{ getattr relabelfrom relabelto create setattr unlink };
+
+# Only relabelto as we would never want to relabelfrom kmem_device
+neverallow ueventd kmem_device:chr_file ~{ getattr create setattr unlink relabelto };
diff --git a/sepolicy/uncrypt.te b/sepolicy/uncrypt.te
new file mode 100644
index 0000000..9231a4d
--- /dev/null
+++ b/sepolicy/uncrypt.te
@@ -0,0 +1,33 @@
+# uncrypt
+type uncrypt, domain, domain_deprecated, mlstrustedsubject;
+type uncrypt_exec, exec_type, file_type;
+
+init_daemon_domain(uncrypt)
+
+allow uncrypt self:capability dac_override;
+
+# Read OTA zip file from /data/data/com.google.android.gsf/app_download
+r_dir_file(uncrypt, app_data_file)
+
+userdebug_or_eng(`
+  # For debugging, allow /data/local/tmp access
+  r_dir_file(uncrypt, shell_data_file)
+')
+
+# Read /cache/recovery/command
+# Read /cache/recovery/uncrypt_file
+# Write to pipe file /cache/recovery/uncrypt_status
+allow uncrypt cache_recovery_file:dir rw_dir_perms;
+allow uncrypt cache_recovery_file:file create_file_perms;
+allow uncrypt cache_recovery_file:fifo_file w_file_perms;
+
+# Set a property to reboot the device.
+set_prop(uncrypt, powerctl_prop)
+
+# Raw writes to block device
+allow uncrypt self:capability sys_rawio;
+allow uncrypt misc_block_device:blk_file w_file_perms;
+allow uncrypt block_device:dir r_dir_perms;
+
+# Access userdata block device.
+allow uncrypt userdata_block_device:blk_file w_file_perms;
diff --git a/sepolicy/untrusted_app.te b/sepolicy/untrusted_app.te
new file mode 100644
index 0000000..3f2f9dd
--- /dev/null
+++ b/sepolicy/untrusted_app.te
@@ -0,0 +1,170 @@
+###
+### Untrusted apps.
+###
+### This file defines the rules for untrusted apps.
+### Apps are labeled based on mac_permissions.xml (maps signer and
+### optionally package name to seinfo value) and seapp_contexts (maps UID
+### and optionally seinfo value to domain for process and type for data
+### directory).  The untrusted_app domain is the default assignment in
+### seapp_contexts for any app with UID between APP_AID (10000)
+### and AID_ISOLATED_START (99000) if the app has no specific seinfo
+### value as determined from mac_permissions.xml.  In current AOSP, this
+### domain is assigned to all non-system apps as well as to any system apps
+### that are not signed by the platform key.  To move
+### a system app into a specific domain, add a signer entry for it to
+### mac_permissions.xml and assign it one of the pre-existing seinfo values
+### or define and use a new seinfo value in both mac_permissions.xml and
+### seapp_contexts.
+###
+### untrusted_app includes all the appdomain rules, plus the
+### additional following rules:
+###
+
+type untrusted_app, domain;
+app_domain(untrusted_app)
+net_domain(untrusted_app)
+bluetooth_domain(untrusted_app)
+
+# Some apps ship with shared libraries and binaries that they write out
+# to their sandbox directory and then execute.
+allow untrusted_app app_data_file:file { rx_file_perms execmod };
+
+# ASEC
+allow untrusted_app asec_apk_file:file r_file_perms;
+allow untrusted_app asec_apk_file:dir r_dir_perms;
+# Execute libs in asec containers.
+allow untrusted_app asec_public_file:file { execute execmod };
+
+# Allow the allocation and use of ptys
+# Used by: https://play.google.com/store/apps/details?id=jackpal.androidterm
+create_pty(untrusted_app)
+
+# Used by Finsky / Android "Verify Apps" functionality when
+# running "adb install foo.apk".
+# TODO: Long term, we don't want apps probing into shell data files.
+# Figure out a way to remove these rules.
+allow untrusted_app shell_data_file:file r_file_perms;
+allow untrusted_app shell_data_file:dir r_dir_perms;
+
+# Read and write system app data files passed over Binder.
+# Motivating case was /data/data/com.android.settings/cache/*.jpg for
+# cropping or taking user photos.
+allow untrusted_app system_app_data_file:file { read write getattr };
+
+#
+# Rules migrated from old app domains coalesced into untrusted_app.
+# This includes what used to be media_app, shared_app, and release_app.
+#
+
+# Access to /data/media.
+allow untrusted_app media_rw_data_file:dir create_dir_perms;
+allow untrusted_app media_rw_data_file:file create_file_perms;
+
+# Traverse into /mnt/media_rw for bypassing FUSE daemon
+# TODO: narrow this to just MediaProvider
+allow untrusted_app mnt_media_rw_file:dir search;
+
+# allow cts to query all services
+allow untrusted_app servicemanager:service_manager list;
+
+allow untrusted_app drmserver_service:service_manager find;
+allow untrusted_app mediaserver_service:service_manager find;
+allow untrusted_app nfc_service:service_manager find;
+allow untrusted_app radio_service:service_manager find;
+allow untrusted_app surfaceflinger_service:service_manager find;
+allow untrusted_app app_api_service:service_manager find;
+
+# Allow GMS core to access perfprofd output, which is stored
+# in /data/misc/perfprofd/. GMS core will need to list all
+# data stored in that directory to process them one by one.
+userdebug_or_eng(`
+  allow untrusted_app perfprofd_data_file:file r_file_perms;
+  allow untrusted_app perfprofd_data_file:dir r_dir_perms;
+')
+
+# gdbserver for ndk-gdb ptrace attaches to app process.
+allow untrusted_app self:process ptrace;
+
+# access /proc/net/xt_qtguid/stats
+r_dir_file(untrusted_app, proc_net)
+
+# Cts: HwRngTest
+allow untrusted_app sysfs_hwrandom:dir search;
+allow untrusted_app sysfs_hwrandom:file r_file_perms;
+
+###
+### neverallow rules
+###
+
+# Receive or send uevent messages.
+neverallow untrusted_app domain:netlink_kobject_uevent_socket *;
+
+# Receive or send generic netlink messages
+neverallow untrusted_app domain:netlink_socket *;
+
+# Too much leaky information in debugfs. It's a security
+# best practice to ensure these files aren't readable.
+neverallow untrusted_app debugfs_type:file read;
+
+# Do not allow untrusted apps to register services.
+# Only trusted components of Android should be registering
+# services.
+neverallow untrusted_app service_manager_type:service_manager add;
+
+# Do not allow untrusted_apps to connect to the property service
+# or set properties. b/10243159
+neverallow untrusted_app property_socket:sock_file write;
+neverallow untrusted_app init:unix_stream_socket connectto;
+neverallow untrusted_app property_type:property_service set;
+
+# 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;
+
+# Do not allow untrusted_app to hard link to any files.
+# In particular, if untrusted_app links to other app data
+# files, installd will not be able to guarantee the deletion
+# of the linked to file. Hard links also contribute to security
+# bugs, so we want to ensure untrusted_app never has this
+# capability.
+neverallow untrusted_app file_type:file link;
+
+# Do not allow untrusted_app to access network MAC address file
+neverallow untrusted_app sysfs_mac_address:file no_rw_file_perms;
+
+# Do not allow untrusted_app access to /cache
+neverallow untrusted_app { cache_file cache_recovery_file }:dir ~{ r_dir_perms };
+neverallow untrusted_app { cache_file cache_recovery_file }:file ~{ read getattr };
+
+# Do not allow untrusted_app to create/unlink files outside of its sandbox,
+# internal storage or sdcard.
+# World accessible data locations allow application to fill the device
+# with unaccounted for data. This data will not get removed during
+# application un-installation.
+neverallow untrusted_app {
+  fs_type
+  -fuse                     # sdcard
+  -sdcardfs                 # sdcard
+  -vfat
+  file_type
+  -app_data_file            # The apps sandbox itself
+  -media_rw_data_file       # Internal storage. Known that apps can
+                            # leave artfacts here after uninstall.
+  userdebug_or_eng(`
+    -method_trace_data_file # only on ro.debuggable=1
+  ')
+  -coredump_file
+}:dir_file_class_set { create unlink };
+
+# Do not allow untrusted_app to directly open tun_device
+neverallow untrusted_app tun_device:chr_file open;
+
+# Only allow appending to /data/anr/traces.txt (b/27853304, b/18340553)
+neverallow untrusted_app anr_data_file:file ~{ open append };
+neverallow untrusted_app anr_data_file:dir ~search;
diff --git a/sepolicy/update_engine.te b/sepolicy/update_engine.te
new file mode 100644
index 0000000..69e84cc
--- /dev/null
+++ b/sepolicy/update_engine.te
@@ -0,0 +1,32 @@
+# Domain for update_engine daemon.
+# update_engine uses the boot_control_hal.
+type update_engine, domain, domain_deprecated, update_engine_common, boot_control_hal;
+type update_engine_exec, exec_type, file_type;
+type update_engine_data_file, file_type, data_file_type;
+
+init_daemon_domain(update_engine);
+net_domain(update_engine);
+
+# Following permissions are needed for update_engine.
+allow update_engine self:process { setsched };
+allow update_engine self:capability { fowner sys_admin };
+allow update_engine kmsg_device:chr_file w_file_perms;
+allow update_engine update_engine_exec:file rx_file_perms;
+wakelock_use(update_engine);
+
+# Ignore these denials.
+dontaudit update_engine kernel:process setsched;
+
+# Allow using persistent storage in /data/misc/update_engine.
+allow update_engine update_engine_data_file:dir { create_dir_perms };
+allow update_engine update_engine_data_file:file { create_file_perms };
+
+# Don't allow kernel module loading, just silence the logs.
+dontaudit update_engine kernel:system module_request;
+
+# Register the service to perform Binder IPC.
+binder_use(update_engine)
+allow update_engine update_engine_service:service_manager { add };
+
+# Allow update_engine to call the callback function provided by priv_app.
+binder_call(update_engine, priv_app)
diff --git a/sepolicy/update_engine_common.te b/sepolicy/update_engine_common.te
new file mode 100644
index 0000000..e70e44d
--- /dev/null
+++ b/sepolicy/update_engine_common.te
@@ -0,0 +1,37 @@
+# update_engine payload application permissions. These are shared between the
+# background daemon and the recovery tool to sideload an update.
+
+# Allow update_engine to reach block devices in /dev/block.
+allow update_engine_common block_device:dir search;
+
+# Allow read/write on system and boot partitions.
+allow update_engine_common boot_block_device:blk_file rw_file_perms;
+allow update_engine_common system_block_device:blk_file rw_file_perms;
+
+# Allow to set recovery options in the BCB. Used to trigger factory reset when
+# the update to an older version (channel change) or incompatible version
+# requires it.
+allow update_engine_common misc_block_device:blk_file rw_file_perms;
+
+# Allow update_engine_common to mount on the /postinstall directory and reset the
+# labels on the mounted filesystem to postinstall_file.
+allow update_engine_common postinstall_mnt_dir:dir mounton;
+allow update_engine_common postinstall_file:filesystem { mount unmount relabelfrom relabelto };
+allow update_engine_common labeledfs:filesystem relabelfrom;
+
+# Allow update_engine_common to read and execute postinstall_file.
+allow update_engine_common postinstall_file:file rx_file_perms;
+allow update_engine_common postinstall_file:lnk_file r_file_perms;
+allow update_engine_common postinstall_file:dir r_dir_perms;
+
+# The postinstall program is run by update_engine_common and will always be tagged as a
+# postinstall_file regardless of its attributes in the new system.
+domain_auto_trans(update_engine_common, postinstall_file, postinstall)
+
+# A postinstall program is typically a shell script (with a #!), so we allow
+# to execute those.
+allow update_engine_common shell_exec:file rx_file_perms;
+
+# Allow update_engine_common to suspend, resume and kill the postinstall program.
+allow update_engine_common postinstall:process { signal sigstop };
+
diff --git a/sepolicy/update_verifier.te b/sepolicy/update_verifier.te
new file mode 100644
index 0000000..65438d3
--- /dev/null
+++ b/sepolicy/update_verifier.te
@@ -0,0 +1,8 @@
+# update_verifier
+# update_verifier uses the boot_control_hal.
+type update_verifier, domain, boot_control_hal;
+type update_verifier_exec, exec_type, file_type;
+
+init_daemon_domain(update_verifier)
+
+# TODO: Add rules to allow update_verifier to read system_block_device.
diff --git a/sepolicy/users b/sepolicy/users
new file mode 100644
index 0000000..51b7b57
--- /dev/null
+++ b/sepolicy/users
@@ -0,0 +1 @@
+user u roles { r } level s0 range s0 - mls_systemhigh;
diff --git a/sepolicy/vdc.te b/sepolicy/vdc.te
new file mode 100644
index 0000000..5478965
--- /dev/null
+++ b/sepolicy/vdc.te
@@ -0,0 +1,23 @@
+# vdc spawned from init for the following services:
+#  defaultcrypto
+#  encrypt
+#
+# We also transition into this domain from dumpstate, when
+# collecting bug reports.
+
+type vdc, domain, domain_deprecated;
+type vdc_exec, exec_type, file_type;
+
+init_daemon_domain(vdc)
+
+unix_socket_connect(vdc, vold, vold)
+
+# vdc sends information back to dumpstate when "adb bugreport" is used
+allow vdc dumpstate:fd use;
+allow vdc dumpstate:unix_stream_socket { read write getattr };
+
+# vdc information is written to shell owned bugreport files
+allow vdc shell_data_file:file { write getattr };
+
+# Why?
+allow vdc dumpstate:unix_dgram_socket { read write };
diff --git a/sepolicy/vold.te b/sepolicy/vold.te
new file mode 100644
index 0000000..737037d
--- /dev/null
+++ b/sepolicy/vold.te
@@ -0,0 +1,193 @@
+# volume manager
+type vold, domain, domain_deprecated;
+type vold_exec, exec_type, file_type;
+
+init_daemon_domain(vold)
+
+# Switch to more restrictive domains when executing common tools
+domain_auto_trans(vold, sgdisk_exec, sgdisk);
+domain_auto_trans(vold, sdcardd_exec, sdcardd);
+
+# Read already opened /cache files.
+allow vold cache_file:dir r_dir_perms;
+allow vold cache_file:file { getattr read };
+allow vold cache_file:lnk_file r_file_perms;
+
+# Read access to pseudo filesystems.
+r_dir_file(vold, proc)
+r_dir_file(vold, proc_net)
+r_dir_file(vold, sysfs)
+r_dir_file(vold, rootfs)
+
+# For a handful of probing tools, we choose an even more restrictive
+# domain when working with untrusted block devices
+domain_trans(vold, shell_exec, blkid);
+domain_trans(vold, shell_exec, blkid_untrusted);
+domain_trans(vold, fsck_exec, fsck);
+domain_trans(vold, fsck_exec, fsck_untrusted);
+
+# Allow us to jump into execution domains of above tools
+allow vold self:process setexec;
+
+# For sgdisk launched through popen()
+allow vold shell_exec:file rx_file_perms;
+
+typeattribute vold mlstrustedsubject;
+allow vold self:process setfscreate;
+allow vold system_file:file x_file_perms;
+allow vold block_device:dir create_dir_perms;
+allow vold device:dir write;
+allow vold devpts:chr_file rw_file_perms;
+allow vold rootfs:dir mounton;
+allow vold sdcard_type:dir mounton; # TODO: deprecated in M
+allow vold sdcard_type:filesystem { mount remount unmount }; # TODO: deprecated in M
+allow vold sdcard_type:dir create_dir_perms; # TODO: deprecated in M
+allow vold sdcard_type:file create_file_perms; # TODO: deprecated in M
+
+# Manage locations where storage is mounted
+allow vold { mnt_media_rw_file storage_file sdcard_type }:dir create_dir_perms;
+allow vold { mnt_media_rw_file storage_file sdcard_type }:file create_file_perms;
+
+# Access to storage that backs emulated FUSE daemons for migration optimization
+allow vold media_rw_data_file:dir create_dir_perms;
+allow vold media_rw_data_file:file create_file_perms;
+
+# Newly created storage dirs are always treated as mount stubs to prevent us
+# from accidentally writing when the mount point isn't present.
+type_transition vold storage_file:dir storage_stub_file;
+type_transition vold mnt_media_rw_file:dir mnt_media_rw_stub_file;
+
+# Allow mounting of storage devices
+allow vold { mnt_media_rw_stub_file storage_stub_file }:dir { mounton create rmdir getattr setattr };
+allow vold sdcard_type:filesystem { mount unmount remount };
+
+# Manage per-user primary symlinks
+allow vold mnt_user_file:dir create_dir_perms;
+allow vold mnt_user_file:lnk_file create_file_perms;
+
+# Allow to create and mount expanded storage
+allow vold mnt_expand_file:dir { create_dir_perms mounton };
+allow vold apk_data_file:dir { create getattr setattr };
+allow vold shell_data_file:dir { create getattr setattr };
+
+allow vold tmpfs:filesystem { mount unmount };
+allow vold tmpfs:dir create_dir_perms;
+allow vold tmpfs:dir mounton;
+allow vold self:capability { net_admin dac_override mknod sys_admin chown fowner fsetid };
+allow vold self:netlink_kobject_uevent_socket create_socket_perms;
+allow vold app_data_file:dir search;
+allow vold app_data_file:file rw_file_perms;
+allow vold loop_device:blk_file create_file_perms;
+allow vold vold_device:blk_file create_file_perms;
+allow vold dm_device:chr_file rw_file_perms;
+allow vold dm_device:blk_file rw_file_perms;
+# For vold Process::killProcessesWithOpenFiles function.
+allow vold domain:dir r_dir_perms;
+allow vold domain:{ file lnk_file } r_file_perms;
+allow vold domain:process { signal sigkill };
+allow vold self:capability { sys_ptrace kill };
+
+# XXX Label sysfs files with a specific type?
+allow vold sysfs:file rw_file_perms;
+
+allow vold kmsg_device:chr_file rw_file_perms;
+
+# Run fsck in the fsck domain.
+allow vold fsck_exec:file { r_file_perms execute };
+
+# Log fsck results
+allow vold fscklogs:dir rw_dir_perms;
+allow vold fscklogs:file create_file_perms;
+
+#
+# Rules to support encrypted fs support.
+#
+
+# Unmount and mount the fs.
+allow vold labeledfs:filesystem { mount unmount remount };
+
+# Access /efs/userdata_footer.
+# XXX Split into a separate type?
+allow vold efs_file:file rw_file_perms;
+
+# Create and mount on /data/tmp_mnt and management of expansion mounts
+allow vold system_data_file:dir { create rw_dir_perms mounton setattr rmdir };
+
+# Set scheduling policy of kernel processes
+allow vold kernel:process setsched;
+
+# Property Service
+set_prop(vold, vold_prop)
+set_prop(vold, powerctl_prop)
+set_prop(vold, ctl_fuse_prop)
+set_prop(vold, restorecon_prop)
+
+# ASEC
+allow vold asec_image_file:file create_file_perms;
+allow vold asec_image_file:dir rw_dir_perms;
+allow vold asec_apk_file:dir { create_dir_perms mounton relabelfrom relabelto };
+allow vold asec_public_file:dir { relabelto setattr };
+allow vold asec_apk_file:file { r_file_perms setattr relabelfrom relabelto };
+allow vold asec_public_file:file { relabelto setattr };
+# restorecon files in asec containers created on 4.2 or earlier.
+allow vold unlabeled:dir { r_dir_perms setattr relabelfrom };
+allow vold unlabeled:file { r_file_perms setattr relabelfrom };
+
+# Handle wake locks (used for device encryption)
+wakelock_use(vold)
+
+# talk to batteryservice
+binder_use(vold)
+binder_call(vold, healthd)
+
+# talk to keymaster
+allow vold tee_device:chr_file rw_file_perms;
+
+# Access userdata block device.
+allow vold userdata_block_device:blk_file rw_file_perms;
+
+# Access metadata block device used for encryption meta-data.
+allow vold metadata_block_device:blk_file rw_file_perms;
+
+# Allow vold to manipulate /data/unencrypted
+allow vold unencrypted_data_file:{ file } create_file_perms;
+allow vold unencrypted_data_file:dir create_dir_perms;
+
+# Write to /proc/sys/vm/drop_caches
+allow vold proc_drop_caches:file w_file_perms;
+
+# Give vold a place where only vold can store files; everyone else is off limits
+allow vold vold_data_file:dir create_dir_perms;
+allow vold vold_data_file:file create_file_perms;
+
+# linux keyring configuration
+allow vold init:key { write search setattr };
+allow vold vold:key { write search setattr };
+
+# vold temporarily changes its priority when running benchmarks
+allow vold self:capability sys_nice;
+
+# vold needs to chroot into app namespaces to remount when runtime permissions change
+allow vold self:capability sys_chroot;
+allow vold storage_file:dir mounton;
+
+# For AppFuse.
+allow vold fuse_device:chr_file rw_file_perms;
+allow vold fuse:filesystem { relabelfrom };
+allow vold app_fusefs:filesystem { relabelfrom relabelto };
+allow vold app_fusefs:filesystem { mount unmount };
+
+# coldboot of /sys/block
+allow vold sysfs_zram:dir r_dir_perms;
+allow vold sysfs_zram_uevent:file rw_file_perms;
+
+# MoveTask.cpp executes cp and rm
+allow vold toolbox_exec:file rx_file_perms;
+
+neverallow { domain -vold } vold_data_file:dir ~{ open create read getattr setattr search relabelto ioctl };
+neverallow { domain -vold } vold_data_file:notdevfile_class_set ~{ relabelto getattr };
+neverallow { domain -vold -init } vold_data_file:dir *;
+neverallow { domain -vold -init } vold_data_file:notdevfile_class_set *;
+neverallow { domain -vold -init } restorecon_prop:property_service set;
+
+neverallow vold fsck_exec:file execute_no_trans;
diff --git a/sepolicy/watchdogd.te b/sepolicy/watchdogd.te
new file mode 100644
index 0000000..00292a9
--- /dev/null
+++ b/sepolicy/watchdogd.te
@@ -0,0 +1,4 @@
+# watchdogd seclabel is specified in init.<board>.rc
+type watchdogd, domain;
+allow watchdogd watchdog_device:chr_file rw_file_perms;
+allow watchdogd kmsg_device:chr_file rw_file_perms;
diff --git a/sepolicy/wpa.te b/sepolicy/wpa.te
new file mode 100644
index 0000000..46d975b
--- /dev/null
+++ b/sepolicy/wpa.te
@@ -0,0 +1,48 @@
+# wpa - wpa supplicant or equivalent
+type wpa, domain, domain_deprecated;
+type wpa_exec, exec_type, file_type;
+
+init_daemon_domain(wpa)
+
+net_domain(wpa)
+
+allow wpa kernel:system module_request;
+allow wpa self:capability { setuid net_admin setgid net_raw };
+allow wpa cgroup:dir create_dir_perms;
+allow wpa self:netlink_route_socket nlmsg_write;
+allow wpa self:netlink_socket create_socket_perms;
+allow wpa self:netlink_generic_socket create_socket_perms;
+allow wpa self:packet_socket create_socket_perms;
+allow wpa wifi_data_file:dir create_dir_perms;
+allow wpa wifi_data_file:file create_file_perms;
+unix_socket_send(wpa, system_wpa, system_server)
+
+binder_use(wpa)
+
+# Create a socket for receiving info from wpa
+type_transition wpa wifi_data_file:dir wpa_socket "sockets";
+allow wpa wpa_socket:dir create_dir_perms;
+allow wpa wpa_socket:sock_file create_file_perms;
+
+use_keystore(wpa)
+
+# WPA (wifi) has a restricted set of permissions from the default.
+allow wpa keystore:keystore_key {
+	get
+	sign
+	verify
+};
+
+# Allow wpa_cli to work. wpa_cli creates a socket in
+# /data/misc/wifi/sockets which wpa supplicant communicates with.
+userdebug_or_eng(`
+  unix_socket_send(wpa, wpa, su)
+')
+
+###
+### neverallow rules
+###
+
+# wpa_supplicant should not trust any data from sdcards
+neverallow wpa sdcard_type:dir ~getattr;
+neverallow wpa sdcard_type:file *;
diff --git a/sepolicy/zygote.te b/sepolicy/zygote.te
new file mode 100644
index 0000000..83f2c76
--- /dev/null
+++ b/sepolicy/zygote.te
@@ -0,0 +1,98 @@
+# zygote
+type zygote, domain, domain_deprecated;
+type zygote_exec, exec_type, file_type;
+
+init_daemon_domain(zygote)
+typeattribute zygote mlstrustedsubject;
+# Override DAC on files and switch uid/gid.
+allow zygote self:capability { dac_override setgid setuid fowner chown };
+# Drop capabilities from bounding set.
+allow zygote self:capability setpcap;
+# Switch SELinux context to app domains.
+allow zygote self:process setcurrent;
+allow zygote system_server:process dyntransition;
+allow zygote appdomain:process dyntransition;
+# Allow zygote to read app /proc/pid dirs (b/10455872)
+allow zygote appdomain:dir { getattr search };
+allow zygote appdomain:file { r_file_perms };
+# Move children into the peer process group.
+allow zygote system_server:process { getpgid setpgid };
+allow zygote appdomain:process { getpgid setpgid };
+# Read system data.
+allow zygote system_data_file:dir r_dir_perms;
+allow zygote system_data_file:file r_file_perms;
+# Write to /data/dalvik-cache.
+allow zygote dalvikcache_data_file:dir create_dir_perms;
+allow zygote dalvikcache_data_file:file create_file_perms;
+# Create symlinks in /data/dalvik-cache
+allow zygote dalvikcache_data_file:lnk_file create_file_perms;
+# Write to /data/resource-cache
+allow zygote resourcecache_data_file:dir rw_dir_perms;
+allow zygote resourcecache_data_file:file create_file_perms;
+# For art.
+allow zygote dalvikcache_data_file:file execute;
+# Execute idmap and dex2oat within zygote's own domain.
+# TODO:  Should either of these be transitioned to the same domain
+# used by installd or stay in-domain for zygote?
+allow zygote idmap_exec:file rx_file_perms;
+allow zygote dex2oat_exec:file rx_file_perms;
+# Control cgroups.
+allow zygote cgroup:dir create_dir_perms;
+allow zygote self:capability sys_admin;
+# Check validity of SELinux context before use.
+selinux_check_context(zygote)
+# Check SELinux permissions.
+selinux_check_access(zygote)
+
+# Native bridge functionality requires that zygote replaces
+# /proc/cpuinfo with /system/lib/<ISA>/cpuinfo using a bind mount
+allow zygote proc_cpuinfo:file mounton;
+
+# Allow remounting rootfs as MS_SLAVE
+allow zygote rootfs:dir mounton;
+allow zygote tmpfs:filesystem { mount unmount };
+allow zygote fuse:filesystem { unmount };
+allow zygote sdcardfs:filesystem { unmount };
+
+# Allowed to create user-specific storage source if started before vold
+allow zygote mnt_user_file:dir create_dir_perms;
+allow zygote mnt_user_file:lnk_file create_file_perms;
+# Allowed to mount user-specific storage into place
+allow zygote storage_file:dir { search mounton };
+
+# Handle --invoke-with command when launching Zygote with a wrapper command.
+allow zygote zygote_exec:file rx_file_perms;
+
+# Read access to pseudo filesystems.
+r_dir_file(zygote, proc_net)
+
+# Root fs.
+allow zygote rootfs:file r_file_perms;
+
+# System file accesses.
+allow zygote system_file:dir r_dir_perms;
+allow zygote system_file:file r_file_perms;
+
+userdebug_or_eng(`
+  # Allow zygote to create and write method traces in /data/misc/trace.
+  allow zygote method_trace_data_file:dir w_dir_perms;
+  allow zygote method_trace_data_file:file { create w_file_perms };
+')
+
+###
+### neverallow rules
+###
+
+# Ensure that all types assigned to app processes are included
+# in the appdomain attribute, so that all allow and neverallow rules
+# written on appdomain are applied to all app processes.
+# This is achieved by ensuring that it is impossible for zygote to
+# setcon (dyntransition) to any types other than those associated
+# with appdomain plus system_server.
+neverallow zygote ~{ appdomain system_server }:process dyntransition;
+
+# Zygote should never execute anything from /data except for /data/dalvik-cache files.
+neverallow zygote {
+  data_file_type
+  -dalvikcache_data_file # map PROT_EXEC
+}:file no_x_file_perms;