Merge "sepolicy: add missing labels for same process HALs." into oc-dev
diff --git a/private/app.te b/private/app.te
index 81de403..73d7729 100644
--- a/private/app.te
+++ b/private/app.te
@@ -94,6 +94,13 @@
 allow appdomain system_file:dir r_dir_perms;
 allow appdomain system_file:lnk_file { getattr open read };
 
+# Allow apps access to /vendor/app except for privileged
+# apps which cannot be in /vendor.
+r_dir_file({ appdomain -ephemeral_app -untrusted_v2_app }, vendor_app_file)
+
+# Allow apps access to /vendor/overlay
+r_dir_file(appdomain, vendor_overlay_file)
+
 # Execute dex2oat when apps call dexclassloader
 allow appdomain dex2oat_exec:file rx_file_perms;
 
diff --git a/private/system_server.te b/private/system_server.te
index 4302343..90e8b10 100644
--- a/private/system_server.te
+++ b/private/system_server.te
@@ -297,6 +297,9 @@
 # Access /vendor/app
 r_dir_file(system_server, vendor_app_file)
 
+# Access /vendor/app
+r_dir_file(system_server, vendor_overlay_file)
+
 # 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;
diff --git a/private/zygote.te b/private/zygote.te
index 15fd951..52250f8 100644
--- a/private/zygote.te
+++ b/private/zygote.te
@@ -51,6 +51,10 @@
 allow zygote idmap_exec:file rx_file_perms;
 allow zygote dex2oat_exec:file rx_file_perms;
 
+# /vendor/overlay existence is checked before
+# passing it on as an argument to idmap in AssetManager
+allow zygote vendor_overlay_file:dir { getattr open read search };
+
 # Control cgroups.
 allow zygote cgroup:dir create_dir_perms;
 allow zygote cgroup:{ file lnk_file } r_file_perms;
diff --git a/public/dex2oat.te b/public/dex2oat.te
index 1d794e2..2fb2336 100644
--- a/public/dex2oat.te
+++ b/public/dex2oat.te
@@ -3,6 +3,11 @@
 type dex2oat_exec, exec_type, file_type;
 
 r_dir_file(dex2oat, apk_data_file)
+# Access to /vendor/app
+r_dir_file(dex2oat, vendor_app_file)
+# Access /vendor/framework
+allow dex2oat vendor_framework_file:dir { getattr search };
+allow dex2oat vendor_framework_file:file { getattr open read };
 
 allow dex2oat tmpfs:file { read getattr };
 
diff --git a/public/domain.te b/public/domain.te
index 4fc3bc0..f16d277 100644
--- a/public/domain.te
+++ b/public/domain.te
@@ -123,34 +123,11 @@
 allow domain vendor_configs_file:dir r_dir_perms;
 allow domain vendor_configs_file:file { read open getattr };
 
-# TODO: (b/36681074) - Remove after this is resolved
-# TODO: (b/36680116, b/36656392, b/36681210) All need directory
-# lookup to find / open their libraries
 full_treble_only(`
-    # Everyone needs to lookup libraries in /vendor/lib(64)
-    # through linker/loader.
+    # This is required "most likely" for LD_LIBRARY_PATH
+    # (b/36681074)
     allow domain vendor_file:dir { getattr search };
 
-    # TODO: b/36681210, find out who needs access and only allow
-    # specific domains for Treble
-    allow domain vendor_app_file:dir r_dir_perms;
-    allow domain vendor_app_file:file { read open getattr };
-
-    # Some apps (com.android.phone) need to be able to open
-    # symlinked libraries
-    # TODO: b/36806861
-    allow domain vendor_app_file:lnk_file { open read };
-
-    # TODO: b/36656392, find out who needs access and only allow
-    # specific domains.
-    allow domain vendor_overlay_file:dir r_dir_perms;
-    allow domain vendor_overlay_file:file { read open getattr };
-
-    # TODO: b/36680116, find out who neeeds access and only allow
-    # specific domains
-    allow domain vendor_framework_file:dir r_dir_perms;
-    allow domain vendor_framework_file:file { read open getattr };
-
     # Allow reading and executing out of /vendor to all vendor domains
     allow { domain -coredomain } vendor_file_type:dir r_dir_perms;
     allow { domain -coredomain } vendor_file_type:file { read open getattr execute };
@@ -689,6 +666,50 @@
   }:sock_file ~{ append getattr ioctl read write };
 ')
 
+# On TREBLE devices, a limited set of files in /vendor are accessible to
+# only a few whitelisted coredomains to keep system/vendor separation.
+full_treble_only(`
+    # Limit access to /vendor/app
+    neverallow {
+        coredomain
+        -appdomain
+        -dex2oat
+        -idmap
+        -init
+        -installd
+        -system_server
+    } vendor_app_file:dir { open read getattr search };
+
+    neverallow {
+        coredomain
+        -appdomain
+        -dex2oat
+        -idmap
+        -init
+        -installd
+        -system_server
+    } vendor_app_file:{ file lnk_file } r_file_perms;
+
+    # Limit access to /vendor/overlay
+    neverallow {
+        coredomain
+        -appdomain
+        -idmap
+	-init
+        -system_server
+        -zygote
+    } vendor_overlay_file:dir { getattr open read search };
+
+    neverallow {
+        coredomain
+        -appdomain
+        -idmap
+	-init
+        -system_server
+        -zygote
+    } vendor_overlay_file:{ file lnk_file } r_file_perms;
+')
+
 # Only authorized processes should be writing to files in /data/dalvik-cache
 neverallow {
   domain
@@ -908,6 +929,7 @@
   userdebug_or_eng(`-uncrypt')
 } shell_data_file:file open;
 
+
 # servicemanager is the only process which handles list request
 neverallow * ~servicemanager:service_manager list;
 
diff --git a/public/idmap.te b/public/idmap.te
index 61f1e1c..1c32f8f 100644
--- a/public/idmap.te
+++ b/public/idmap.te
@@ -9,3 +9,9 @@
 # Open and read from target and overlay apk files passed by argument.
 allow idmap apk_data_file:file r_file_perms;
 allow idmap apk_data_file:dir search;
+
+# Allow apps access to /vendor/app
+r_dir_file(idmap, vendor_app_file)
+
+# Allow apps access to /vendor/overlay
+r_dir_file(idmap, vendor_overlay_file)
diff --git a/public/installd.te b/public/installd.te
index a85edff..774ba49 100644
--- a/public/installd.te
+++ b/public/installd.te
@@ -27,6 +27,8 @@
 r_dir_file(installd, rootfs)
 # Scan through APKs in /system/app and /system/priv-app
 r_dir_file(installd, system_file)
+# Scan through APKs in /vendor/app
+r_dir_file(installd, vendor_app_file)
 # Get file context
 allow installd file_contexts_file:file r_file_perms;
 # Get seapp_context
diff --git a/tools/sepolicy-analyze/README b/tools/sepolicy-analyze/README
index d18609a..fdee588 100644
--- a/tools/sepolicy-analyze/README
+++ b/tools/sepolicy-analyze/README
@@ -65,6 +65,10 @@
 
     Displays the types associated with the specified attribute name.
 
+    sepolicy-analyze out/target/product/<board>/root/sepolicy attribute -r <name>
+
+    Displays the attributes associated with the specified type 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
index 474bda2..ae98aa9 100644
--- a/tools/sepolicy-analyze/attribute.c
+++ b/tools/sepolicy-analyze/attribute.c
@@ -1,39 +1,81 @@
+#include <getopt.h>
+
 #include "attribute.h"
 
 void attribute_usage() {
-    fprintf(stderr, "\tattribute <attribute-name>\n");
+    fprintf(stderr, "\tattribute <name> [-r|--reverse]\n");
 }
 
-static int list_attribute(policydb_t * policydb, char *name)
-{
-    struct type_datum *attr;
+static void retrieve_mapping(policydb_t *policydb, struct type_datum *dat, char *name, int reverse) {
     struct ebitmap_node *n;
     unsigned int bit;
 
-    attr = hashtab_search(policydb->p_types.table, name);
-    if (!attr) {
+    if (reverse) {
+        ebitmap_for_each_bit(&policydb->type_attr_map[dat->s.value - 1], n, bit) {
+            if (!ebitmap_node_get_bit(n, bit))
+                continue;
+            if (!strcmp(policydb->p_type_val_to_name[bit], name))
+                continue;
+            printf("%s\n", policydb->p_type_val_to_name[bit]);
+        }
+    } else {
+        ebitmap_for_each_bit(&policydb->attr_type_map[dat->s.value - 1], n, bit) {
+            if (!ebitmap_node_get_bit(n, bit))
+                continue;
+            printf("%s\n", policydb->p_type_val_to_name[bit]);
+        }
+    }
+}
+
+static int list_attribute(policydb_t *policydb, char *name, int reverse)
+{
+    struct type_datum *dat;
+
+    dat = hashtab_search(policydb->p_types.table, name);
+    if (!dat) {
         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;
+    if (reverse) {
+        if (dat->flavor != TYPE_TYPE) {
+            fprintf(stderr, "%s is an attribute not a type in this policy.\n", name);
+            return -1;
+        }
+    } else {
+        if (dat->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]);
-    }
+    retrieve_mapping(policydb, dat, name, reverse);
 
     return 0;
 }
 
 int attribute_func (int argc, char **argv, policydb_t *policydb) {
-    if (argc != 2) {
+    int reverse = 0;
+    char ch;
+
+    struct option attribute_options[] = {
+        {"reverse", no_argument, NULL, 'r'},
+        {NULL, 0, NULL, 0}
+    };
+
+    while ((ch = getopt_long(argc, argv, "r", attribute_options, NULL)) != -1) {
+        switch (ch) {
+        case 'r':
+            reverse = 1;
+            break;
+        default:
+            USAGE_ERROR = true;
+            return -1;
+        }
+    }
+
+    if (argc != 2 && !(reverse && argc == 3)) {
         USAGE_ERROR = true;
         return -1;
     }
-    return list_attribute(policydb, argv[1]);
+    return list_attribute(policydb, argv[optind], reverse);
 }