From 4d205f8975dd0fa95f5c578ed9ad322ee579b988 Mon Sep 17 00:00:00 2001 From: Mark Salyzyn Date: Fri, 15 Jul 2016 15:45:58 -0700 Subject: [PATCH] logd: auditd: suppress multiple identical avc: messages to kmsg Sends first and last of a series of 3 or more indentical avc: messages to kmsg and adds 'duplicate messages suppressed' for the last one in the set. eg: [67.141658] type=1400 audit(1468852100.171:70): avc: ... tcontext=u:object_r:proc:s0 tclass=file [67.141678] type=1400 audit(1468852107.494:71): avc: ... tcontext=u:object_r:cache_file:s0 tclass=dir [67.535202] type=1400 audit(1468852107.498:74): avc: ... tcontext=u:object_r:cache_file:s0 tclass=dir duplicate messages suppressed [67.535227] type=1400 audit(1468852107.888:75): avc: ... tcontext=u:object_r:proc_net:s0 tclass=file One can look at the sequence numbers in the above example to see that four identical message were produced, two were dropped. ToDo: Evaluate multiple streams of duplicate messages. Bug: 30118730 Change-Id: I31dcda7c8c42edfc7a8f1bf4d9e46284c74b3d18 --- logd/LogAudit.cpp | 72 +++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 64 insertions(+), 8 deletions(-) diff --git a/logd/LogAudit.cpp b/logd/LogAudit.cpp index 4eb5e8310..8859d55da 100644 --- a/logd/LogAudit.cpp +++ b/logd/LogAudit.cpp @@ -181,16 +181,72 @@ int LogAudit::logPrint(const char *fmt, ...) { struct iovec iov[3]; static const char log_info[] = { KMSG_PRIORITY(LOG_INFO) }; static const char log_warning[] = { KMSG_PRIORITY(LOG_WARNING) }; + static const char newline[] = "\n"; - iov[0].iov_base = info ? const_cast(log_info) - : const_cast(log_warning); - iov[0].iov_len = info ? sizeof(log_info) : sizeof(log_warning); - iov[1].iov_base = str; - iov[1].iov_len = strlen(str); - iov[2].iov_base = const_cast("\n"); - iov[2].iov_len = 1; + // Dedupe messages, checking for identical messages starting with avc: + static unsigned count; + static char *last_str; + static bool last_info; - writev(fdDmesg, iov, sizeof(iov) / sizeof(iov[0])); + if (last_str != NULL) { + static const char avc[] = "): avc: "; + char *avcl = strstr(last_str, avc); + bool skip = false; + + if (avcl) { + char *avcr = strstr(str, avc); + + skip = avcr && !strcmp(avcl + strlen(avc), avcr + strlen(avc)); + if (skip) { + ++count; + free(last_str); + last_str = strdup(str); + last_info = info; + } + } + if (!skip) { + static const char resume[] = " duplicate messages suppressed\n"; + + iov[0].iov_base = last_info ? + const_cast(log_info) : + const_cast(log_warning); + iov[0].iov_len = last_info ? + sizeof(log_info) : + sizeof(log_warning); + iov[1].iov_base = last_str; + iov[1].iov_len = strlen(last_str); + if (count > 1) { + iov[2].iov_base = const_cast(resume); + iov[2].iov_len = strlen(resume); + } else { + iov[2].iov_base = const_cast(newline); + iov[2].iov_len = strlen(newline); + } + + writev(fdDmesg, iov, sizeof(iov) / sizeof(iov[0])); + free(last_str); + last_str = NULL; + } + } + if (last_str == NULL) { + count = 0; + last_str = strdup(str); + last_info = info; + } + if (count == 0) { + iov[0].iov_base = info ? + const_cast(log_info) : + const_cast(log_warning); + iov[0].iov_len = info ? + sizeof(log_info) : + sizeof(log_warning); + iov[1].iov_base = str; + iov[1].iov_len = strlen(str); + iov[2].iov_base = const_cast(newline); + iov[2].iov_len = strlen(newline); + + writev(fdDmesg, iov, sizeof(iov) / sizeof(iov[0])); + } } pid_t pid = getpid();