Prefer property_contexts from /system & /vendor

This changes selinux_android_prop_context_handle to prefer loading
property_contexts from /system/etc/selinux & /vendor/etc/selinux,
while falling back to the pre-existing behavior of loading from /.

Test: Device with *_property_contexts in / boots up fine, no denials
      to do with properties, getprop -Z lists correct labels.
Test: Device with *_property_contexts in /system & /vendor, but not
      in /, boots up fine, no denials to do with properties,
      getprop -Z lists correct labels.
Test: Device with *_property_contexts in /system & vendor and in /
      boots up fine, no denials to do with properties, getprop -Z
      lists correct labels, dmesg says properties were loaded from
      /system & /vendor.
Bug: 36002573

Change-Id: I1d1362b5f75aa864e798c07b1e8073c669e0aee6
diff --git a/libselinux/src/android/android.c b/libselinux/src/android/android.c
index 15e15cb..4af64e9 100644
--- a/libselinux/src/android/android.c
+++ b/libselinux/src/android/android.c
@@ -57,10 +57,12 @@
 
 static const char *const sepolicy_file = "/sepolicy";
 
-/* TODO: Change file paths to /system/property_contexts
- * and /vendor/property_contexts after b/27805372
- */
-static const struct selinux_opt seopts_prop[] = {
+static const struct selinux_opt seopts_prop_split[] = {
+    { SELABEL_OPT_PATH, "/system/etc/selinux/plat_property_contexts" },
+    { SELABEL_OPT_PATH, "/vendor/etc/selinux/nonplat_property_contexts"}
+};
+
+static const struct selinux_opt seopts_prop_rootfs[] = {
     { SELABEL_OPT_PATH, "/plat_property_contexts" },
     { SELABEL_OPT_PATH, "/nonplat_property_contexts"}
 };
@@ -1587,6 +1589,14 @@
 struct selabel_handle* selinux_android_prop_context_handle(void)
 {
     struct selabel_handle* sehandle;
+    const struct selinux_opt* seopts_prop;
+
+    // Prefer files from /system & /vendor, fall back to files from /
+    if (access(seopts_prop_split[0].value, R_OK) != -1) {
+        seopts_prop = seopts_prop_split;
+    } else {
+        seopts_prop = seopts_prop_rootfs;
+    }
 
     sehandle = selabel_open(SELABEL_CTX_ANDROID_PROP,
             seopts_prop, 2);