Add service_context management into libselinux.
Add functions to handle opening handles for MAC
on service_manager. Also add selinux_log_callback
into libselinux because identical code was spread
through three different files.
Bug: 12909011
Change-Id: I04eb855700f1d0c086542053d987b3a30cf1b0c0
diff --git a/Android.mk b/Android.mk
index baec088..7abb19c 100644
--- a/Android.mk
+++ b/Android.mk
@@ -72,4 +72,5 @@
LOCAL_COPY_HEADERS := $(common_COPY_HEADERS)
LOCAL_PRELINK_MODULE := false
LOCAL_STATIC_LIBRARIES := libmincrypt
+LOCAL_SHARED_LIBRARIES := liblog
include $(BUILD_SHARED_LIBRARY)
diff --git a/include/selinux/android.h b/include/selinux/android.h
index ae6c05d..00894f5 100644
--- a/include/selinux/android.h
+++ b/include/selinux/android.h
@@ -13,6 +13,8 @@
extern struct selabel_handle* selinux_android_file_context_handle(void);
+extern struct selabel_handle* selinux_android_service_context_handle(void);
+
extern void selinux_android_set_sehandle(const struct selabel_handle *hndl);
extern int selinux_android_load_policy(void);
@@ -29,6 +31,9 @@
const char *seinfo,
uid_t uid);
+extern int selinux_log_callback(int type, const char *fmt, ...)
+ __attribute__ ((format(printf, 2, 3)));
+
#define SELINUX_ANDROID_RESTORECON_NOCHANGE 1
#define SELINUX_ANDROID_RESTORECON_VERBOSE 2
#define SELINUX_ANDROID_RESTORECON_RECURSE 4
diff --git a/src/android.c b/src/android.c
index d0432d4..ffb2adb 100644
--- a/src/android.c
+++ b/src/android.c
@@ -22,6 +22,7 @@
#include <selinux/avc.h>
#include <mincrypt/sha.h>
#include <private/android_filesystem_config.h>
+#include <log/log.h>
#include "policy.h"
#include "callbacks.h"
#include "selinux_internal.h"
@@ -48,6 +49,12 @@
"/data/security/current/sepolicy",
NULL };
+static const struct selinux_opt seopts_service[] = {
+ { SELABEL_OPT_PATH, "/service_contexts" },
+ { SELABEL_OPT_PATH, "/data/security/current/service_contexts" },
+ { 0, NULL }
+};
+
enum levelFrom {
LEVELFROM_NONE,
LEVELFROM_APP,
@@ -859,6 +866,25 @@
sehandle = file_context_open();
}
+static struct selabel_handle *service_context_open(void)
+{
+ struct selabel_handle *handle = NULL;
+
+ set_policy_index();
+ handle = selabel_open(SELABEL_CTX_ANDROID_PROP,
+ &seopts_service[policy_index], 1);
+
+ if (!handle) {
+ selinux_log(SELINUX_ERROR, "%s: Error getting service context handle (%s)\n",
+ __FUNCTION__, strerror(errno));
+ } else {
+ selinux_log(SELINUX_INFO, "SELinux: Loaded service contexts from %s.\n",
+ seopts_service[policy_index].value);
+ }
+
+ return handle;
+}
+
static pthread_once_t fc_once = PTHREAD_ONCE_INIT;
struct pkgInfo {
@@ -1282,6 +1308,11 @@
return file_context_open();
}
+struct selabel_handle* selinux_android_service_context_handle(void)
+{
+ return service_context_open();
+}
+
void selinux_android_set_sehandle(const struct selabel_handle *hndl)
{
sehandle = (struct selabel_handle *) hndl;
@@ -1374,3 +1405,26 @@
return selinux_android_load_policy_helper(false);
}
+
+int selinux_log_callback(int type, const char *fmt, ...)
+{
+ va_list ap;
+ int priority;
+
+ 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);
+ LOG_PRI_VA(priority, "SELinux", fmt, ap);
+ va_end(ap);
+ return 0;
+}