OSDN Git Service

logd: throttle SELinux denials to 20/sec
authorNick Kralevich <nnk@google.com>
Wed, 19 Nov 2014 21:33:22 +0000 (13:33 -0800)
committerNick Kralevich <nnk@google.com>
Wed, 19 Nov 2014 21:35:36 +0000 (13:35 -0800)
Impose a limit of 20 selinux denials per second. Denials beyond
that point don't add any value, and have the potential to cause
crashes or denial of service attacks.

Do some other misc cleanup while I'm here.

Bug: 18341932
Change-Id: I6125d629ae4d6ae131d2e53bfa41e1f50277d402

logd/LogAudit.cpp
logd/libaudit.c
logd/libaudit.h

index 51feff3..ee2f32d 100644 (file)
@@ -248,7 +248,7 @@ int LogAudit::getLogSocket() {
     if (fd < 0) {
         return fd;
     }
-    if (audit_set_pid(fd, getpid(), WAIT_YES) < 0) {
+    if (audit_setup(fd, getpid()) < 0) {
         audit_close(fd);
         fd = -1;
     }
index ca88d1b..d00d579 100644 (file)
@@ -162,7 +162,7 @@ out:
     return rc;
 }
 
-int audit_set_pid(int fd, uint32_t pid, rep_wait_t wmode)
+int audit_setup(int fd, uint32_t pid)
 {
     int rc;
     struct audit_message rep;
@@ -176,7 +176,8 @@ int audit_set_pid(int fd, uint32_t pid, rep_wait_t wmode)
      * 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 = 20; // 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));
@@ -188,24 +189,21 @@ int audit_set_pid(int fd, uint32_t pid, rep_wait_t wmode)
     /*
      * In a request where we need to wait for a response, wait for the message
      * and discard it. This message confirms and sync's us with the kernel.
-     * This daemon is now registered as the audit logger. Only wait if the
-     * wmode is != WAIT_NO
+     * This daemon is now registered as the audit logger.
+     *
+     * TODO
+     * If the daemon dies and restarts the message didn't come back,
+     * so I went to non-blocking and it seemed to fix the bug.
+     * Need to investigate further.
      */
-    if (wmode != WAIT_NO) {
-        /* TODO
-         * If the daemon dies and restarts the message didn't come back,
-         * so I went to non-blocking and it seemed to fix the bug.
-         * Need to investigate further.
-         */
-        audit_get_reply(fd, &rep, GET_REPLY_NONBLOCKING, 0);
-    }
+    audit_get_reply(fd, &rep, GET_REPLY_NONBLOCKING, 0);
 
     return 0;
 }
 
 int audit_open()
 {
-    return socket(PF_NETLINK, SOCK_RAW, NETLINK_AUDIT);
+    return socket(PF_NETLINK, SOCK_RAW | SOCK_CLOEXEC, NETLINK_AUDIT);
 }
 
 int audit_get_reply(int fd, struct audit_message *rep, reply_t block, int peek)
index cb114f9..b9e330d 100644 (file)
@@ -37,11 +37,6 @@ typedef enum {
     GET_REPLY_NONBLOCKING
 } reply_t;
 
-typedef enum {
-    WAIT_NO,
-    WAIT_YES
-} rep_wait_t;
-
 /* type == AUDIT_SIGNAL_INFO */
 struct audit_sig_info {
     uid_t uid;
@@ -92,12 +87,10 @@ extern int  audit_get_reply(int fd, struct audit_message *rep, reply_t block,
  *  The fd returned by a call to audit_open()
  * @param pid
  *  The pid whom to set as the reciever of audit messages
- * @param wmode
- *  Whether or not to block on the underlying socket io calls.
  * @return
  *  This function returns 0 on success, -errno on error.
  */
-extern int  audit_set_pid(int fd, uint32_t pid, rep_wait_t wmode);
+extern int  audit_setup(int fd, uint32_t pid);
 
 __END_DECLS