Skip to content

Commit

Permalink
logd: throttle SELinux denials to 20/sec
Browse files Browse the repository at this point in the history
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
  • Loading branch information
nickkral committed Nov 19, 2014
1 parent 81906d4 commit c234a1b
Show file tree
Hide file tree
Showing 3 changed files with 13 additions and 22 deletions.
2 changes: 1 addition & 1 deletion logd/LogAudit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
24 changes: 11 additions & 13 deletions logd/libaudit.c
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ static int audit_send(int fd, int type, const void *data, size_t size)
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;
Expand All @@ -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));
Expand All @@ -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)
Expand Down
9 changes: 1 addition & 8 deletions logd/libaudit.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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

Expand Down

0 comments on commit c234a1b

Please sign in to comment.