blob: 391fc1b8afb178fb1b09b2cb463bb6297893c200 [file] [log] [blame]
#include "android_common.h"
#ifdef __ANDROID_VNDK__
#ifndef LOG_EVENT_STRING
#define LOG_EVENT_STRING(...)
#endif // LOG_EVENT_STRING
#endif // __ANDROID_VNDK__
static const struct selinux_opt seopts_service_split[] = {
{ SELABEL_OPT_PATH, "/system/etc/selinux/plat_service_contexts" },
{ SELABEL_OPT_PATH, "/vendor/etc/selinux/nonplat_service_contexts" }
};
static const struct selinux_opt seopts_service_rootfs[] = {
{ SELABEL_OPT_PATH, "/plat_service_contexts" },
{ SELABEL_OPT_PATH, "/nonplat_service_contexts" }
};
static const struct selinux_opt seopts_hwservice_split[] = {
{ SELABEL_OPT_PATH, "/system/etc/selinux/plat_hwservice_contexts" },
{ SELABEL_OPT_PATH, "/vendor/etc/selinux/nonplat_hwservice_contexts" }
};
static const struct selinux_opt seopts_hwservice_rootfs[] = {
{ SELABEL_OPT_PATH, "/plat_hwservice_contexts" },
{ SELABEL_OPT_PATH, "/nonplat_hwservice_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" };
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 /
if (access(seopts_service_split[0].value, R_OK) != -1) {
seopts_service = seopts_service_split;
} else {
seopts_service = seopts_service_rootfs;
}
// TODO(b/36866029) full treble devices can't load non-plat
return selinux_android_service_open_context_handle(seopts_service, 2);
}
struct selabel_handle* selinux_android_hw_service_context_handle(void)
{
const struct selinux_opt* seopts_service;
if (access(seopts_hwservice_split[0].value, R_OK) != -1) {
seopts_service = seopts_hwservice_split;
} else {
seopts_service = seopts_hwservice_rootfs;
}
return selinux_android_service_open_context_handle(seopts_service, 2);
}
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;
}
return selinux_android_service_open_context_handle(seopts_service, 1);
}
int selinux_log_callback(int type, const char *fmt, ...)
{
va_list ap;
int priority;
char *strp;
switch(type) {
case SELINUX_WARNING:
priority = ANDROID_LOG_WARN;
break;
case SELINUX_INFO:
priority = ANDROID_LOG_INFO;
break;
default:
priority = ANDROID_LOG_ERROR;
break;
}
va_start(ap, fmt);
if (vasprintf(&strp, fmt, ap) != -1) {
LOG_PRI(priority, "SELinux", "%s", strp);
LOG_EVENT_STRING(AUDITD_LOG_TAG, strp);
free(strp);
}
va_end(ap);
return 0;
}