Merge "sepolicy:  Drop BOARD_SEPOLICY_IGNORE/REPLACE support."
diff --git a/app.te b/app.te
index 40ec610..27ec14b 100644
--- a/app.te
+++ b/app.te
@@ -155,6 +155,16 @@
 allow appdomain resourcecache_data_file:file r_file_perms;
 allow appdomain resourcecache_data_file:dir r_dir_perms;
 
+# logd access
+read_logd(appdomain)
+control_logd(appdomain)
+# application inherit logd write socket (urge is to deprecate this long term)
+allow appdomain zygote:unix_dgram_socket write;
+
+allow { appdomain -isolated_app } keystore:keystore_key { test get insert delete exist saw sign verify };
+
+use_keystore({ appdomain -isolated_app })
+
 ###
 ### CTS-specific rules
 ###
@@ -168,18 +178,6 @@
 # Check SELinux policy and contexts.
 selinux_check_access(appdomain)
 selinux_check_context(appdomain)
-# Validate that each process is running in the correct security context.
-allow appdomain domain:process getattr;
-
-# logd access
-read_logd(appdomain)
-control_logd(appdomain)
-# application inherit logd write socket (urge is to deprecate this long term)
-allow appdomain zygote:unix_dgram_socket write;
-
-allow { appdomain -isolated_app } keystore:keystore_key { test get insert delete exist saw sign verify };
-
-use_keystore({ appdomain -isolated_app })
 
 ###
 ### Neverallow rules
diff --git a/domain.te b/domain.te
index b2eaa79..733a095 100644
--- a/domain.te
+++ b/domain.te
@@ -369,3 +369,8 @@
 # Do not mount on top of symlinks, fifos, or sockets.
 # Feature parity with Chromium LSM.
 neverallow domain { file_type fs_type dev_type }:{ lnk_file fifo_file sock_file } mounton;
+
+# Nobody should be able to execute su on user builds.
+# On userdebug/eng builds, only dumpstate, shell, and
+# su itself execute su.
+neverallow { domain userdebug_or_eng(`-dumpstate -shell -su') } su_exec:file no_x_file_perms;
diff --git a/keystore.te b/keystore.te
index 6a89df3..3561fed 100644
--- a/keystore.te
+++ b/keystore.te
@@ -12,6 +12,11 @@
 allow keystore tee_device:chr_file rw_file_perms;
 allow keystore tee:unix_stream_socket connectto;
 
+allow keystore keystore_service:service_manager { add find };
+
+# Check SELinux permissions.
+selinux_check_access(keystore)
+
 ###
 ### Neverallow rules
 ###
@@ -25,8 +30,3 @@
 neverallow { domain -keystore -init } keystore_data_file:notdevfile_class_set *;
 
 neverallow domain keystore:process ptrace;
-
-allow keystore keystore_service:service_manager { add find };
-
-# Check SELinux permissions.
-selinux_check_access(keystore)
diff --git a/mls b/mls
index 474bd72..5589b4b 100644
--- a/mls
+++ b/mls
@@ -26,9 +26,9 @@
 mlsconstrain process { getsched getsession getpgid getcap getattr ptrace share }
 	     (l1 dom l2 or t1 == mlstrustedsubject);
 
-# Process write operations:  No write down unless trusted.
+# Process write operations:  Require equivalence unless trusted.
 mlsconstrain process { sigkill sigstop signal setsched setpgid setcap setrlimit ptrace share }
-	     (l1 domby l2 or t1 == mlstrustedsubject);
+	     (l1 eq l2 or t1 == mlstrustedsubject);
 
 #
 # Socket constraints
@@ -39,10 +39,10 @@
 mlsconstrain socket_class_set { create relabelfrom relabelto }
 	     ((h1 eq h2 and l1 eq l2) or t1 == mlstrustedsubject);
 
-# Datagram send: Sender must be dominated by receiver unless one of them is
-# trusted.
+# Datagram send: Sender must be equivalent to the receiver unless one of them
+# is trusted.
 mlsconstrain unix_dgram_socket { sendto }
-	     (l1 domby l2 or t1 == mlstrustedsubject or t2 == mlstrustedsubject);
+	     (l1 eq l2 or t1 == mlstrustedsubject or t2 == mlstrustedsubject);
 
 # Stream connect:  Client must be equivalent to server unless one of them
 # is trusted.
@@ -83,13 +83,13 @@
 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 dominated by the object unless the
+# 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 domby l2 or t1 == mlstrustedsubject or t2 == mlstrustedobject);
+	     (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 domby l2 or t1 == mlstrustedsubject or t2 == mlstrustedobject);
+	     (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
@@ -100,23 +100,7 @@
 	     (l1 dom l2 or t1 == mlstrustedsubject or t2 == mlstrustedobject or t2 == domain);
 
 mlsconstrain fifo_file { write setattr append unlink link rename }
-	     (l1 domby l2 or t1 == mlstrustedsubject or t2 == mlstrustedobject or t2 == domain);
-
-#
-# IPC constraints
-#
-
-# Create/destroy: equivalence or trusted.
-mlsconstrain ipc_class_set { create destroy }
-	     (l2 eq h2 and (l1 eq l2 or t1 == mlstrustedsubject));
-
-# Read ops: No read up unless trusted.
-mlsconstrain ipc_class_set r_ipc_perms
-	     (l1 dom l2 or t1 == mlstrustedsubject);
-
-# Write ops: No write down unless trusted.
-mlsconstrain ipc_class_set w_ipc_perms
-	     (l1 domby l2 or t1 == mlstrustedsubject);
+	     (l1 eq l2 or t1 == mlstrustedsubject or t2 == mlstrustedobject or t2 == domain);
 
 #
 # Binder IPC constraints
diff --git a/shell.te b/shell.te
index 8cfe9ac..cfadf77 100644
--- a/shell.te
+++ b/shell.te
@@ -66,6 +66,9 @@
 allow shell domain:dir { search open read getattr };
 allow shell domain:{ file lnk_file } { open read getattr };
 
+# allow shell to read /proc/pid/attr/current for ps -Z
+allow shell domain:process getattr;
+
 # 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
diff --git a/system_server.te b/system_server.te
index 6630615..9079acb 100644
--- a/system_server.te
+++ b/system_server.te
@@ -75,10 +75,6 @@
 # Kill apps.
 allow system_server appdomain:process { sigkill signal };
 
-# This line seems suspect, as it should not really need to
-# set scheduling parameters for a kernel domain task.
-allow system_server kernel:process setsched;
-
 # Set scheduling info for apps.
 allow system_server appdomain:process { getsched setsched };
 allow system_server mediaserver:process { getsched setsched };
diff --git a/tools/sepolicy-analyze/Android.mk b/tools/sepolicy-analyze/Android.mk
index 3f95702..e65efe9 100644
--- a/tools/sepolicy-analyze/Android.mk
+++ b/tools/sepolicy-analyze/Android.mk
@@ -7,7 +7,7 @@
 LOCAL_MODULE_TAGS := optional
 LOCAL_C_INCLUDES := external/libsepol/include
 LOCAL_CFLAGS := -Wall -Werror
-LOCAL_SRC_FILES := sepolicy-analyze.c dups.c neverallow.c perm.c typecmp.c booleans.c utils.c
+LOCAL_SRC_FILES := sepolicy-analyze.c dups.c neverallow.c perm.c typecmp.c booleans.c attribute.c utils.c
 LOCAL_STATIC_LIBRARIES := libsepol
 
 include $(BUILD_HOST_EXECUTABLE)
diff --git a/tools/sepolicy-analyze/README b/tools/sepolicy-analyze/README
index 0cb890b..d18609a 100644
--- a/tools/sepolicy-analyze/README
+++ b/tools/sepolicy-analyze/README
@@ -60,6 +60,11 @@
     Policy booleans are forbidden in Android policy, so if there is any
     output, the policy will fail CTS.
 
+    ATTRIBUTE (attribute)
+    sepolicy-analyze out/target/product/<board>/root/sepolicy attribute <name>
+
+    Displays the types associated with the specified attribute name.
+
     NEVERALLOW CHECKING (neverallow)
     sepolicy-analyze out/target/product/<board>/root/sepolicy neverallow \
     [-w] [-d] [-f neverallows.conf] | [-n "neverallow string"]
diff --git a/tools/sepolicy-analyze/attribute.c b/tools/sepolicy-analyze/attribute.c
new file mode 100644
index 0000000..474bda2
--- /dev/null
+++ b/tools/sepolicy-analyze/attribute.c
@@ -0,0 +1,39 @@
+#include "attribute.h"
+
+void attribute_usage() {
+    fprintf(stderr, "\tattribute <attribute-name>\n");
+}
+
+static int list_attribute(policydb_t * policydb, char *name)
+{
+    struct type_datum *attr;
+    struct ebitmap_node *n;
+    unsigned int bit;
+
+    attr = hashtab_search(policydb->p_types.table, name);
+    if (!attr) {
+        fprintf(stderr, "%s is not defined in this policy.\n", name);
+        return -1;
+    }
+
+    if (attr->flavor != TYPE_ATTRIB) {
+        fprintf(stderr, "%s is a type not an attribute in this policy.\n", name);
+        return -1;
+    }
+
+    ebitmap_for_each_bit(&policydb->attr_type_map[attr->s.value - 1], n, bit) {
+        if (!ebitmap_node_get_bit(n, bit))
+            continue;
+        printf("%s\n", policydb->p_type_val_to_name[bit]);
+    }
+
+    return 0;
+}
+
+int attribute_func (int argc, char **argv, policydb_t *policydb) {
+    if (argc != 2) {
+        USAGE_ERROR = true;
+        return -1;
+    }
+    return list_attribute(policydb, argv[1]);
+}
diff --git a/tools/sepolicy-analyze/attribute.h b/tools/sepolicy-analyze/attribute.h
new file mode 100644
index 0000000..05adcbd
--- /dev/null
+++ b/tools/sepolicy-analyze/attribute.h
@@ -0,0 +1,11 @@
+#ifndef ATTRIBUTE_H
+#define ATTRIBUTE_H
+
+#include <sepol/policydb/policydb.h>
+
+#include "utils.h"
+
+void attribute_usage(void);
+int attribute_func(int argc, char **argv, policydb_t *policydb);
+
+#endif /* ATTRIBUTE_H */
diff --git a/tools/sepolicy-analyze/sepolicy-analyze.c b/tools/sepolicy-analyze/sepolicy-analyze.c
index a6fa200..b70eaaa 100644
--- a/tools/sepolicy-analyze/sepolicy-analyze.c
+++ b/tools/sepolicy-analyze/sepolicy-analyze.c
@@ -7,6 +7,7 @@
 #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]))
@@ -22,7 +23,8 @@
     COMP(neverallow),
     COMP(permissive),
     COMP(typecmp),
-    COMP(booleans)
+    COMP(booleans),
+    COMP(attribute)
 };
 
 void usage(char *arg0)
diff --git a/untrusted_app.te b/untrusted_app.te
index e880571..d88414c 100644
--- a/untrusted_app.te
+++ b/untrusted_app.te
@@ -138,6 +138,10 @@
     -wifip2p_service
 }:service_manager find;
 
+# Allow verifier to access staged apks.
+allow untrusted_app { apk_tmp_file apk_private_tmp_file }:dir r_dir_perms;
+allow untrusted_app { apk_tmp_file apk_private_tmp_file }:file r_file_perms;
+
 ###
 ### neverallow rules
 ###
@@ -163,6 +167,12 @@
 neverallow untrusted_app init:unix_stream_socket connectto;
 neverallow untrusted_app property_type:property_service set;
 
-# Allow verifier to access staged apks.
-allow untrusted_app { apk_tmp_file apk_private_tmp_file }:dir r_dir_perms;
-allow untrusted_app { apk_tmp_file apk_private_tmp_file }:file r_file_perms;
+# Do not allow untrusted_app to be assigned mlstrustedsubject.
+# This would undermine the per-user isolation model being
+# enforced via levelFrom=user in seapp_contexts and the mls
+# constraints.  As there is no direct way to specify a neverallow
+# on attribute assignment, this relies on the fact that fork
+# permission only makes sense within a domain (hence should
+# never be granted to any other domain within mlstrustedsubject)
+# and untrusted_app is allowed fork permission to itself.
+neverallow untrusted_app mlstrustedsubject:process fork;