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
This commit is contained in:
parent
10a7b9bb8b
commit
8adb4d9d12
|
@ -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; \
|
||||
|
|
31
init/log.cpp
31
init/log.cpp
|
@ -19,6 +19,8 @@
|
|||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <linux/audit.h>
|
||||
#include <netlink/netlink.h>
|
||||
#include <selinux/selinux.h>
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue