Loading logd/LogAudit.cpp +47 −4 Original line number Diff line number Diff line Loading @@ -43,7 +43,7 @@ '>' LogAudit::LogAudit(LogBuffer *buf, LogReader *reader, int fdDmesg) : SocketListener(getLogSocket(), false), SocketListener(mSock = getLogSocket(), false), logbuf(buf), reader(reader), fdDmesg(fdDmesg), Loading @@ -51,19 +51,62 @@ LogAudit::LogAudit(LogBuffer *buf, LogReader *reader, int fdDmesg) : BOOL_DEFAULT_TRUE)), events(__android_logger_property_get_bool("ro.logd.auditd.events", BOOL_DEFAULT_TRUE)), initialized(false) { initialized(false), tooFast(false) { static const char auditd_message[] = { KMSG_PRIORITY(LOG_INFO), 'l', 'o', 'g', 'd', '.', 'a', 'u', 'd', 'i', 't', 'd', ':', ' ', 's', 't', 'a', 'r', 't', '\n' }; write(fdDmesg, auditd_message, sizeof(auditd_message)); } void LogAudit::checkRateLimit() { // trim list for AUDIT_RATE_LIMIT_BURST_DURATION of history log_time oldest(AUDIT_RATE_LIMIT_BURST_DURATION, 0); bucket.emplace(android_log_clockid()); oldest = bucket.back() - oldest; while (bucket.front() < oldest) bucket.pop(); static const size_t upperThreshold = ((AUDIT_RATE_LIMIT_BURST_DURATION * (AUDIT_RATE_LIMIT_DEFAULT + AUDIT_RATE_LIMIT_MAX)) + 1) / 2; if (bucket.size() >= upperThreshold) { // Hit peak, slow down source if (!tooFast) { tooFast = true; audit_rate_limit(mSock, AUDIT_RATE_LIMIT_MAX); } // We do not need to hold on to the full set of timing data history, // let's ensure it does not grow without bounds. This also ensures // that std::dequeue underneath behaves almost like a ring buffer. do { bucket.pop(); } while (bucket.size() >= upperThreshold); return; } if (!tooFast) return; static const size_t lowerThreshold = AUDIT_RATE_LIMIT_BURST_DURATION * AUDIT_RATE_LIMIT_MAX; if (bucket.size() >= lowerThreshold) return; tooFast = false; // Went below max sustained rate, allow source to speed up audit_rate_limit(mSock, AUDIT_RATE_LIMIT_DEFAULT); } bool LogAudit::onDataAvailable(SocketClient *cli) { if (!initialized) { prctl(PR_SET_NAME, "logd.auditd"); initialized = true; } checkRateLimit(); struct audit_message rep; rep.nlh.nlmsg_type = 0; Loading @@ -75,8 +118,7 @@ bool LogAudit::onDataAvailable(SocketClient *cli) { return false; } logPrint("type=%d %.*s", rep.nlh.nlmsg_type, rep.nlh.nlmsg_len, rep.data); logPrint("type=%d %.*s", rep.nlh.nlmsg_type, rep.nlh.nlmsg_len, rep.data); return true; } Loading Loading @@ -351,5 +393,6 @@ int LogAudit::getLogSocket() { audit_close(fd); fd = -1; } (void)audit_rate_limit(fd, AUDIT_RATE_LIMIT_DEFAULT); return fd; } logd/LogAudit.h +7 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,8 @@ #ifndef _LOGD_LOG_AUDIT_H__ #define _LOGD_LOG_AUDIT_H__ #include <queue> #include <sysutils/SocketListener.h> #include "LogBuffer.h" Loading @@ -31,6 +33,11 @@ class LogAudit : public SocketListener { bool events; bool initialized; bool tooFast; int mSock; std::queue<log_time> bucket; void checkRateLimit(); public: LogAudit(LogBuffer *buf, LogReader *reader, int fdDmesg); int log(char *buf, size_t len); Loading logd/libaudit.c +23 −3 Original line number Diff line number Diff line Loading @@ -149,7 +149,7 @@ out: return rc; } int audit_setup(int fd, uint32_t pid) int audit_setup(int fd, pid_t pid) { int rc; struct audit_message rep; Loading @@ -163,8 +163,7 @@ int audit_setup(int fd, uint32_t pid) * and the the mask set to AUDIT_STATUS_PID */ status.pid = pid; status.mask = AUDIT_STATUS_PID | AUDIT_STATUS_RATE_LIMIT; status.rate_limit = 20; // audit entries per second status.mask = AUDIT_STATUS_PID; /* Let the kernel know this pid will be registering for audit events */ rc = audit_send(fd, AUDIT_SET, &status, sizeof(status)); Loading @@ -187,6 +186,27 @@ int audit_setup(int fd, uint32_t pid) return 0; } int audit_rate_limit(int fd, unsigned rate_limit) { int rc; struct audit_message rep; struct audit_status status; memset(&status, 0, sizeof(status)); status.mask = AUDIT_STATUS_RATE_LIMIT; status.rate_limit = rate_limit; /* audit entries per second */ rc = audit_send(fd, AUDIT_SET, &status, sizeof(status)); if (rc < 0) { return rc; } audit_get_reply(fd, &rep, GET_REPLY_NONBLOCKING, 0); return 0; } int audit_open() { return socket(PF_NETLINK, SOCK_RAW | SOCK_CLOEXEC, NETLINK_AUDIT); Loading logd/libaudit.h +24 −7 Original line number Diff line number Diff line Loading @@ -82,15 +82,32 @@ extern int audit_get_reply(int fd, struct audit_message *rep, reply_t block, int peek); /** * Sets a pid to recieve audit netlink events from the kernel * Sets a pid to receive audit netlink events from the kernel * @param fd * The fd returned by a call to audit_open() * @param pid * The pid whom to set as the reciever of audit messages * The pid whom to set as the receiver of audit messages * @return * This function returns 0 on success, -errno on error. */ extern int audit_setup(int fd, uint32_t pid); extern int audit_setup(int fd, pid_t pid); /** * Sets the rate limit to receive audit netlink events from the kernel * @param fd * The fd returned by a call to audit_open() * @param max_rate * The cap of the maximum number of audit messages a second * @return * This function returns 0 on success, -errno on error. */ /* Guidelines to follow for dynamic rate_limit */ #define AUDIT_RATE_LIMIT_DEFAULT 20 /* acceptable burst rate */ #define AUDIT_RATE_LIMIT_BURST_DURATION 10 /* number of seconds of burst */ #define AUDIT_RATE_LIMIT_MAX 5 /* acceptable sustained rate */ extern int audit_rate_limit(int fd, unsigned rate_limit); __END_DECLS Loading logd/tests/Android.mk +4 −1 Original line number Diff line number Diff line Loading @@ -27,12 +27,15 @@ test_tags := tests # Unit tests. # ----------------------------------------------------------------------------- event_flag := -DAUDITD_LOG_TAG=1003 -DCHATTY_LOG_TAG=1004 test_c_flags := \ -fstack-protector-all \ -g \ -Wall -Wextra \ -Werror \ -fno-builtin \ $(event_flag) test_src_files := \ logd_test.cpp Loading @@ -43,6 +46,6 @@ include $(CLEAR_VARS) LOCAL_MODULE := $(test_module_prefix)unit-tests LOCAL_MODULE_TAGS := $(test_tags) LOCAL_CFLAGS += $(test_c_flags) LOCAL_SHARED_LIBRARIES := libbase libcutils liblog LOCAL_SHARED_LIBRARIES := libbase libcutils liblog libselinux LOCAL_SRC_FILES := $(test_src_files) include $(BUILD_NATIVE_TEST) Loading
logd/LogAudit.cpp +47 −4 Original line number Diff line number Diff line Loading @@ -43,7 +43,7 @@ '>' LogAudit::LogAudit(LogBuffer *buf, LogReader *reader, int fdDmesg) : SocketListener(getLogSocket(), false), SocketListener(mSock = getLogSocket(), false), logbuf(buf), reader(reader), fdDmesg(fdDmesg), Loading @@ -51,19 +51,62 @@ LogAudit::LogAudit(LogBuffer *buf, LogReader *reader, int fdDmesg) : BOOL_DEFAULT_TRUE)), events(__android_logger_property_get_bool("ro.logd.auditd.events", BOOL_DEFAULT_TRUE)), initialized(false) { initialized(false), tooFast(false) { static const char auditd_message[] = { KMSG_PRIORITY(LOG_INFO), 'l', 'o', 'g', 'd', '.', 'a', 'u', 'd', 'i', 't', 'd', ':', ' ', 's', 't', 'a', 'r', 't', '\n' }; write(fdDmesg, auditd_message, sizeof(auditd_message)); } void LogAudit::checkRateLimit() { // trim list for AUDIT_RATE_LIMIT_BURST_DURATION of history log_time oldest(AUDIT_RATE_LIMIT_BURST_DURATION, 0); bucket.emplace(android_log_clockid()); oldest = bucket.back() - oldest; while (bucket.front() < oldest) bucket.pop(); static const size_t upperThreshold = ((AUDIT_RATE_LIMIT_BURST_DURATION * (AUDIT_RATE_LIMIT_DEFAULT + AUDIT_RATE_LIMIT_MAX)) + 1) / 2; if (bucket.size() >= upperThreshold) { // Hit peak, slow down source if (!tooFast) { tooFast = true; audit_rate_limit(mSock, AUDIT_RATE_LIMIT_MAX); } // We do not need to hold on to the full set of timing data history, // let's ensure it does not grow without bounds. This also ensures // that std::dequeue underneath behaves almost like a ring buffer. do { bucket.pop(); } while (bucket.size() >= upperThreshold); return; } if (!tooFast) return; static const size_t lowerThreshold = AUDIT_RATE_LIMIT_BURST_DURATION * AUDIT_RATE_LIMIT_MAX; if (bucket.size() >= lowerThreshold) return; tooFast = false; // Went below max sustained rate, allow source to speed up audit_rate_limit(mSock, AUDIT_RATE_LIMIT_DEFAULT); } bool LogAudit::onDataAvailable(SocketClient *cli) { if (!initialized) { prctl(PR_SET_NAME, "logd.auditd"); initialized = true; } checkRateLimit(); struct audit_message rep; rep.nlh.nlmsg_type = 0; Loading @@ -75,8 +118,7 @@ bool LogAudit::onDataAvailable(SocketClient *cli) { return false; } logPrint("type=%d %.*s", rep.nlh.nlmsg_type, rep.nlh.nlmsg_len, rep.data); logPrint("type=%d %.*s", rep.nlh.nlmsg_type, rep.nlh.nlmsg_len, rep.data); return true; } Loading Loading @@ -351,5 +393,6 @@ int LogAudit::getLogSocket() { audit_close(fd); fd = -1; } (void)audit_rate_limit(fd, AUDIT_RATE_LIMIT_DEFAULT); return fd; }
logd/LogAudit.h +7 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,8 @@ #ifndef _LOGD_LOG_AUDIT_H__ #define _LOGD_LOG_AUDIT_H__ #include <queue> #include <sysutils/SocketListener.h> #include "LogBuffer.h" Loading @@ -31,6 +33,11 @@ class LogAudit : public SocketListener { bool events; bool initialized; bool tooFast; int mSock; std::queue<log_time> bucket; void checkRateLimit(); public: LogAudit(LogBuffer *buf, LogReader *reader, int fdDmesg); int log(char *buf, size_t len); Loading
logd/libaudit.c +23 −3 Original line number Diff line number Diff line Loading @@ -149,7 +149,7 @@ out: return rc; } int audit_setup(int fd, uint32_t pid) int audit_setup(int fd, pid_t pid) { int rc; struct audit_message rep; Loading @@ -163,8 +163,7 @@ int audit_setup(int fd, uint32_t pid) * and the the mask set to AUDIT_STATUS_PID */ status.pid = pid; status.mask = AUDIT_STATUS_PID | AUDIT_STATUS_RATE_LIMIT; status.rate_limit = 20; // audit entries per second status.mask = AUDIT_STATUS_PID; /* Let the kernel know this pid will be registering for audit events */ rc = audit_send(fd, AUDIT_SET, &status, sizeof(status)); Loading @@ -187,6 +186,27 @@ int audit_setup(int fd, uint32_t pid) return 0; } int audit_rate_limit(int fd, unsigned rate_limit) { int rc; struct audit_message rep; struct audit_status status; memset(&status, 0, sizeof(status)); status.mask = AUDIT_STATUS_RATE_LIMIT; status.rate_limit = rate_limit; /* audit entries per second */ rc = audit_send(fd, AUDIT_SET, &status, sizeof(status)); if (rc < 0) { return rc; } audit_get_reply(fd, &rep, GET_REPLY_NONBLOCKING, 0); return 0; } int audit_open() { return socket(PF_NETLINK, SOCK_RAW | SOCK_CLOEXEC, NETLINK_AUDIT); Loading
logd/libaudit.h +24 −7 Original line number Diff line number Diff line Loading @@ -82,15 +82,32 @@ extern int audit_get_reply(int fd, struct audit_message *rep, reply_t block, int peek); /** * Sets a pid to recieve audit netlink events from the kernel * Sets a pid to receive audit netlink events from the kernel * @param fd * The fd returned by a call to audit_open() * @param pid * The pid whom to set as the reciever of audit messages * The pid whom to set as the receiver of audit messages * @return * This function returns 0 on success, -errno on error. */ extern int audit_setup(int fd, uint32_t pid); extern int audit_setup(int fd, pid_t pid); /** * Sets the rate limit to receive audit netlink events from the kernel * @param fd * The fd returned by a call to audit_open() * @param max_rate * The cap of the maximum number of audit messages a second * @return * This function returns 0 on success, -errno on error. */ /* Guidelines to follow for dynamic rate_limit */ #define AUDIT_RATE_LIMIT_DEFAULT 20 /* acceptable burst rate */ #define AUDIT_RATE_LIMIT_BURST_DURATION 10 /* number of seconds of burst */ #define AUDIT_RATE_LIMIT_MAX 5 /* acceptable sustained rate */ extern int audit_rate_limit(int fd, unsigned rate_limit); __END_DECLS Loading
logd/tests/Android.mk +4 −1 Original line number Diff line number Diff line Loading @@ -27,12 +27,15 @@ test_tags := tests # Unit tests. # ----------------------------------------------------------------------------- event_flag := -DAUDITD_LOG_TAG=1003 -DCHATTY_LOG_TAG=1004 test_c_flags := \ -fstack-protector-all \ -g \ -Wall -Wextra \ -Werror \ -fno-builtin \ $(event_flag) test_src_files := \ logd_test.cpp Loading @@ -43,6 +46,6 @@ include $(CLEAR_VARS) LOCAL_MODULE := $(test_module_prefix)unit-tests LOCAL_MODULE_TAGS := $(test_tags) LOCAL_CFLAGS += $(test_c_flags) LOCAL_SHARED_LIBRARIES := libbase libcutils liblog LOCAL_SHARED_LIBRARIES := libbase libcutils liblog libselinux LOCAL_SRC_FILES := $(test_src_files) include $(BUILD_NATIVE_TEST)