Add a method to load vendor_service_context only.
This is used by vndservicemanager, which will only
have access to the vndservice_contexts on the vendor
partition.
Bug: 36052864
Test: vndservicemanager can load the context
Change-Id: Ifd5caa4f74236184ef970ce39a8be227c50b48d4
diff --git a/libselinux/exported.map b/libselinux/exported.map
index 94087cb..35dfae1 100644
--- a/libselinux/exported.map
+++ b/libselinux/exported.map
@@ -20,6 +20,7 @@
selinux_android_setcontext;
selinux_android_set_sehandle;
selinux_android_service_context_handle;
+ selinux_android_vendor_service_context_handle;
selinux_check_access;
security_getenforce;
security_setenforce;
diff --git a/libselinux/include/selinux/android.h b/libselinux/include/selinux/android.h
index 78bb7db..93e7574 100644
--- a/libselinux/include/selinux/android.h
+++ b/libselinux/include/selinux/android.h
@@ -17,6 +17,8 @@
extern struct selabel_handle* selinux_android_service_context_handle(void);
+extern struct selabel_handle* selinux_android_vendor_service_context_handle(void);
+
extern void selinux_android_set_sehandle(const struct selabel_handle *hndl);
extern int selinux_android_load_policy(void);
diff --git a/libselinux/src/android/android.c b/libselinux/src/android/android.c
index 2978490..4c61b71 100644
--- a/libselinux/src/android/android.c
+++ b/libselinux/src/android/android.c
@@ -86,6 +86,13 @@
{ SELABEL_OPT_PATH, "/nonplat_service_contexts" }
};
+static const struct selinux_opt seopts_vndservice =
+ { SELABEL_OPT_PATH, "/vendor/etc/selinux/vndservice_contexts" };
+
+static const struct selinux_opt seopts_vndservice_rootfs =
+ { SELABEL_OPT_PATH, "/vndservice_contexts" };
+
+
enum levelFrom {
LEVELFROM_NONE,
LEVELFROM_APP,
@@ -1647,9 +1654,28 @@
return sehandle;
}
-struct selabel_handle* selinux_android_service_context_handle(void)
+struct selabel_handle* selinux_android_service_open_context_handle(const struct selinux_opt* seopts_service,
+ unsigned nopts)
{
struct selabel_handle* sehandle;
+
+ sehandle = selabel_open(SELABEL_CTX_ANDROID_SERVICE,
+ seopts_service, nopts);
+
+ if (!sehandle) {
+ selinux_log(SELINUX_ERROR, "%s: Error getting service context handle (%s)\n",
+ __FUNCTION__, strerror(errno));
+ return NULL;
+ }
+ selinux_log(SELINUX_INFO, "SELinux: Loaded service_contexts from:\n");
+ for (unsigned i = 0; i < nopts; i++) {
+ selinux_log(SELINUX_INFO, " %s\n", seopts_service[i].value);
+ }
+ return sehandle;
+}
+
+struct selabel_handle* selinux_android_service_context_handle(void)
+{
const struct selinux_opt* seopts_service;
// Prefer files from /system & /vendor, fall back to files from /
@@ -1659,18 +1685,20 @@
seopts_service = seopts_service_rootfs;
}
- sehandle = selabel_open(SELABEL_CTX_ANDROID_SERVICE,
- seopts_service, 2);
+ // TODO(b/36866029) full treble devices can't load non-plat
+ return selinux_android_service_open_context_handle(seopts_service, 2);
+}
- if (!sehandle) {
- selinux_log(SELINUX_ERROR, "%s: Error getting service context handle (%s)\n",
- __FUNCTION__, strerror(errno));
- return NULL;
+struct selabel_handle* selinux_android_vendor_service_context_handle(void)
+{
+ const struct selinux_opt* seopts_service;
+ if (access(seopts_vndservice.value, R_OK) != -1) {
+ seopts_service = &seopts_vndservice;
+ } else {
+ seopts_service = &seopts_vndservice_rootfs;
}
- selinux_log(SELINUX_INFO, "SELinux: Loaded service_contexts from %s & %s.\n",
- seopts_service[0].value, seopts_service[1].value);
- return sehandle;
+ return selinux_android_service_open_context_handle(seopts_service, 1);
}
void selinux_android_set_sehandle(const struct selabel_handle *hndl)