From 8adb4d9d12d077ee87d1ce97742c6a5ba9aaaf9f Mon Sep 17 00:00:00 2001 From: Nick Kralevich Date: Tue, 3 Jan 2017 08:37:54 -0800 Subject: [PATCH] Send property_service AVC messages to the kernel audit system The property service uses an SELinux userspace check to determine if a process is allowed to set a property. If the security check fails, a userspace SELinux denial is generated. Currently, these denials are only sent to dmesg. Instead of sending these denials to dmesg, send it to the kernel audit system. This will cause these userspace denials to be treated similarly to kernel generated denials (eg, logd will pick them up and process them). This will ensure that denials generated by the property service will show up in logcat / dmesg / event log. After this patch, running "setprop asdf asdf" from the unprivileged adb shell user will result in the following audit message: type=1107 audit(39582851.013:48): pid=1 uid=0 auid=4294967295 ses=4294967295 subj=u:r:init:s0 msg='avc: denied { set } for property=asdf pid=5537 uid=2000 gid=2000 scontext=u:r:shell:s0 tcontext=u:object_r:default_prop:s0 tclass=property_service' Test: manual Bug: 27878170 Change-Id: I0b8994888653501f2f315eaa63d9e2ba32d851ef --- init/Android.mk | 5 +++-- init/log.cpp | 31 +++++++++++++++++++++++++++++-- 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/init/Android.mk b/init/Android.mk index ecdf5db70..111fe895f 100644 --- a/init/Android.mk +++ b/init/Android.mk @@ -54,7 +54,7 @@ LOCAL_SRC_FILES:= \ service.cpp \ util.cpp \ -LOCAL_STATIC_LIBRARIES := libbase libselinux liblog libprocessgroup +LOCAL_STATIC_LIBRARIES := libbase libselinux liblog libprocessgroup libnl LOCAL_WHOLE_STATIC_LIBRARIES := libcap LOCAL_MODULE := libinit LOCAL_SANITIZE := integer @@ -103,7 +103,8 @@ LOCAL_STATIC_LIBRARIES := \ libdl \ libsparse_static \ libz \ - libprocessgroup + libprocessgroup \ + libnl \ # Create symlinks. LOCAL_POST_INSTALL_CMD := $(hide) mkdir -p $(TARGET_ROOT_OUT)/sbin; \ diff --git a/init/log.cpp b/init/log.cpp index 861834011..6b32526df 100644 --- a/init/log.cpp +++ b/init/log.cpp @@ -19,6 +19,8 @@ #include #include +#include +#include #include void InitKernelLogging(char* argv[]) { @@ -38,6 +40,24 @@ void InitKernelLogging(char* argv[]) { android::base::InitLogging(argv, &android::base::KernelLogger); } +static void selinux_avc_log(char* buf, size_t buf_len) { + size_t str_len = strnlen(buf, buf_len); + + // trim newline at end of string + buf[str_len - 1] = '\0'; + + struct nl_sock* sk = nl_socket_alloc(); + if (sk == NULL) { + return; + } + nl_connect(sk, NETLINK_AUDIT); + int result; + do { + result = nl_send_simple(sk, AUDIT_USER_AVC, 0, buf, str_len); + } while (result == -NLE_INTR); + nl_socket_free(sk); +} + int selinux_klog_callback(int type, const char *fmt, ...) { android::base::LogSeverity severity = android::base::ERROR; if (type == SELINUX_WARNING) { @@ -48,8 +68,15 @@ int selinux_klog_callback(int type, const char *fmt, ...) { char buf[1024]; va_list ap; va_start(ap, fmt); - vsnprintf(buf, sizeof(buf), fmt, ap); + int res = vsnprintf(buf, sizeof(buf), fmt, ap); va_end(ap); - android::base::KernelLogger(android::base::MAIN, severity, "selinux", nullptr, 0, buf); + if (res <= 0) { + return 0; + } + if (type == SELINUX_AVC) { + selinux_avc_log(buf, sizeof(buf)); + } else { + android::base::KernelLogger(android::base::MAIN, severity, "selinux", nullptr, 0, buf); + } return 0; }