Merge "LogAudit: remove dynamic rate limiter" am: 9e7cec22e0
am: cf7f19f4b9

Change-Id: I8567fe9b6e589408ec794c0ab846ea7726be364c
diff --git a/logd/LogAudit.cpp b/logd/LogAudit.cpp
index 1d0cc33..b76160d 100755
--- a/logd/LogAudit.cpp
+++ b/logd/LogAudit.cpp
@@ -45,7 +45,7 @@
         '0' + LOG_MAKEPRI(LOG_AUTH, LOG_PRI(PRI)) % 10, '>'
 
 LogAudit::LogAudit(LogBuffer* buf, LogReader* reader, int fdDmesg)
-    : SocketListener(mSock = getLogSocket(), false),
+    : SocketListener(getLogSocket(), false),
       logbuf(buf),
       reader(reader),
       fdDmesg(fdDmesg),
@@ -53,8 +53,7 @@
                                               BOOL_DEFAULT_TRUE)),
       events(__android_logger_property_get_bool("ro.logd.auditd.events",
                                                 BOOL_DEFAULT_TRUE)),
-      initialized(false),
-      tooFast(false) {
+      initialized(false) {
     static const char auditd_message[] = { KMSG_PRIORITY(LOG_INFO),
                                            'l',
                                            'o',
@@ -78,54 +77,12 @@
     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;
@@ -486,6 +443,5 @@
         audit_close(fd);
         fd = -1;
     }
-    (void)audit_rate_limit(fd, AUDIT_RATE_LIMIT_DEFAULT);
     return fd;
 }
diff --git a/logd/LogAudit.h b/logd/LogAudit.h
index 2bd02d4..5904966 100644
--- a/logd/LogAudit.h
+++ b/logd/LogAudit.h
@@ -18,7 +18,6 @@
 #define _LOGD_LOG_AUDIT_H__
 
 #include <map>
-#include <queue>
 
 #include <sysutils/SocketListener.h>
 
@@ -34,11 +33,6 @@
     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);
diff --git a/logd/libaudit.c b/logd/libaudit.c
index dfd56f2..9d9a857 100644
--- a/logd/libaudit.c
+++ b/logd/libaudit.c
@@ -160,7 +160,8 @@
      * and the the mask set to AUDIT_STATUS_PID
      */
     status.pid = pid;
-    status.mask = AUDIT_STATUS_PID;
+    status.mask = AUDIT_STATUS_PID | AUDIT_STATUS_RATE_LIMIT;
+    status.rate_limit = AUDIT_RATE_LIMIT; /* audit entries per second */
 
     /* Let the kernel know this pid will be registering for audit events */
     rc = audit_send(fd, AUDIT_SET, &status, sizeof(status));
@@ -183,26 +184,6 @@
     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);
 }
diff --git a/logd/libaudit.h b/logd/libaudit.h
index a2afe47..2a93ea3 100644
--- a/logd/libaudit.h
+++ b/logd/libaudit.h
@@ -89,22 +89,8 @@
  */
 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);
+/* Max audit messages per second  */
+#define AUDIT_RATE_LIMIT 5
 
 __END_DECLS
 
diff --git a/logd/tests/logd_test.cpp b/logd/tests/logd_test.cpp
index 9e1541b..7d7a22f 100644
--- a/logd/tests/logd_test.cpp
+++ b/logd/tests/logd_test.cpp
@@ -1195,51 +1195,14 @@
                           << "fail as this device is in a bad state, "
                           << "but is not strictly a unit test failure.";
     }
-    // sepolicy_rate_limiter_maximum
-    {  // maximum precharch test block.
-        static constexpr int rate = AUDIT_RATE_LIMIT_MAX;
-        static constexpr int duration = 2;
-        // Two seconds of a liveable sustained rate
-        EXPECT_EQ(rate * duration,
-                  count_avc(sepolicy_rate(rate, rate * duration)));
-    }
-    // sepolicy_rate_limiter_sub_burst
-    {  // maximum period below half way between sustainable and burst rate
-        static constexpr int threshold =
-            ((AUDIT_RATE_LIMIT_BURST_DURATION *
-              (AUDIT_RATE_LIMIT_DEFAULT + AUDIT_RATE_LIMIT_MAX)) +
-             1) /
-            2;
-        static constexpr int rate =
-            (threshold / AUDIT_RATE_LIMIT_BURST_DURATION) - 1;
-        static constexpr int duration = AUDIT_RATE_LIMIT_BURST_DURATION;
-        EXPECT_EQ(rate * duration,
-                  count_avc(sepolicy_rate(rate, rate * duration)));
-    }
-    // sepolicy_rate_limiter_spam
-    {  // hit avc: hard beyond reason block.
-        // maximum period of double the maximum burst rate
-        static constexpr int threshold =
-            ((AUDIT_RATE_LIMIT_BURST_DURATION *
-              (AUDIT_RATE_LIMIT_DEFAULT + AUDIT_RATE_LIMIT_MAX)) +
-             1) /
-            2;
-        static constexpr int rate = AUDIT_RATE_LIMIT_DEFAULT * 2;
-        static constexpr int duration = threshold / AUDIT_RATE_LIMIT_DEFAULT;
-        EXPECT_GE(
-            ((AUDIT_RATE_LIMIT_DEFAULT * duration) * 115) / 100,  // +15% margin
-            count_avc(sepolicy_rate(rate, rate * duration)));
-        // give logd another 3 seconds to react to the burst before checking
-        sepolicy_rate(rate, rate * 3);
-        // maximum period at double maximum burst rate (spam filter kicked in)
-        EXPECT_GE(threshold * 2,
-                  count_avc(sepolicy_rate(
-                      rate, rate * AUDIT_RATE_LIMIT_BURST_DURATION)));
-        // cool down, and check unspammy rate still works
-        sleep(2);
-        EXPECT_LE(AUDIT_RATE_LIMIT_BURST_DURATION - 1,  // allow _one_ lost
-                  count_avc(sepolicy_rate(1, AUDIT_RATE_LIMIT_BURST_DURATION)));
-    }
+
+    static const int rate = AUDIT_RATE_LIMIT;
+    static const int duration = 2;
+    // Two seconds of sustained denials. Depending on the overlap in the time
+    // window that the kernel is considering vs what this test is considering,
+    // allow some additional denials to prevent a flaky test.
+    EXPECT_LE(count_avc(sepolicy_rate(rate, rate * duration)),
+              rate * duration + rate);
 #else
     GTEST_LOG_(INFO) << "This test does nothing.\n";
 #endif