On Wed, May 15, 2013 at 6:52 PM, William Roberts
<[email protected]>wrote:

> From eb7a0d5e711b555d38e3cd19c754e4a866bb07a4 Mon Sep 17 00:00:00 2001
> From: William Roberts <[email protected]>
> Date: Wed, 15 May 2013 18:12:31 -0700
> Subject: [PATCH] Enable splitting the logs to both auditd and kernel
>  simultaneously
>
> Allow the audit subsystem to send audit events to both the kernel
> message buffer and auditd at the same time.
>
> Change-Id: I3107322c845a4cfb001352e152c0866b8a73f02d
> Signed-off-by: William Roberts <[email protected]>
> ---
>  include/linux/audit.h |  5 +++++
>  kernel/audit.c        | 44 +++++++++++++++++++++++++++++++++++++++-----
>  2 files changed, 44 insertions(+), 5 deletions(-)
>
> diff --git a/include/linux/audit.h b/include/linux/audit.h
> index ed3ef19..ae8083e 100644
> --- a/include/linux/audit.h
> +++ b/include/linux/audit.h
> @@ -314,6 +314,10 @@ enum {
>  #define AUDIT_STATUS_PID        0x0004
>  #define AUDIT_STATUS_RATE_LIMIT        0x0008
>  #define AUDIT_STATUS_BACKLOG_LIMIT    0x0010
> +#define AUDIT_STATUS_LOGSPLIT        0x0020
> +                /* Split log actions */
> +#define AUDIT_LOGSPLIT_OFF    0
> +#define AUDIT_LOGSPLIT_ON    1
>                  /* Failure-to-log actions */
>  #define AUDIT_FAIL_SILENT    0
>  #define AUDIT_FAIL_PRINTK    1
> @@ -359,6 +363,7 @@ struct audit_status {
>      __u32        mask;        /* Bit mask for valid entries */
>      __u32        enabled;    /* 1 = enabled, 0 = disabled */
>      __u32        failure;    /* Failure-to-log action */
> +    __u32        logsplit;    /* Logsplit action */
>      __u32        pid;        /* pid of auditd process */
>      __u32        rate_limit;    /* messages rate limit (per second) */
>      __u32        backlog_limit;    /* waiting messages limit */
> diff --git a/kernel/audit.c b/kernel/audit.c
> index 4096bcc..10f0457 100644
> --- a/kernel/audit.c
> +++ b/kernel/audit.c
> @@ -74,6 +74,10 @@ static int    audit_initialized;
>  #define AUDIT_OFF    0
>  #define AUDIT_ON    1
>  #define AUDIT_LOCKED    2
> +
> +#define AUDIT_PRINTK_NOHOLD    0
> +#define AUDIT_PRINTK_HOLD    1
> +
>  int        audit_enabled;
>  int        audit_ever_enabled;
>
> @@ -85,6 +89,9 @@ static int    audit_default;
>  /* If auditing cannot proceed, audit_failure selects what happens. */
>  static int    audit_failure = AUDIT_FAIL_PRINTK;
>
> +/* If auditing should preserve logs in dmesg even if auditd is running. */
> +static int audit_logsplit = AUDIT_LOGSPLIT_OFF;
> +
>  /*
>   * If audit records are to be written to the netlink socket, audit_pid
>   * contains the pid of the auditd process and audit_nlk_pid contains
> @@ -357,6 +364,16 @@ static int audit_set_failure(int state, uid_t
> loginuid, u32 sessionid, u32 sid)
>                        loginuid, sessionid, sid);
>  }
>
> +static int audit_set_logsplit(int state, uid_t loginuid, u32 sessionid,
> u32 sid)
> +{
> +    if (state != AUDIT_LOGSPLIT_OFF
> +        && state != AUDIT_LOGSPLIT_ON)
> +        return -EINVAL;
> +
> +    return audit_do_config_change("audit_logsplit", &audit_logsplit,
> state,
> +                      loginuid, sessionid, sid);
> +}
> +
>  /*
>   * Queue skbs to be sent to auditd when/if it comes back.  These skbs
> should
>   * already have been sent via prink/syslog and so if these messages are
> dropped
> @@ -375,11 +392,8 @@ static void audit_hold_skb(struct sk_buff *skb)
>          kfree_skb(skb);
>  }
>
> -/*
> - * For one reason or another this nlh isn't getting delivered to the
> userspace
> - * audit daemon, just send it to printk.
> - */
> -static void audit_printk_skb(struct sk_buff *skb)
> +/* Just printks the skb, no audit_hold or free of any kind */
> +static void __audit_printk_skb(struct sk_buff *skb)
>  {
>      struct nlmsghdr *nlh = nlmsg_hdr(skb);
>      char *data = NLMSG_DATA(nlh);
> @@ -387,7 +401,15 @@ static void audit_printk_skb(struct sk_buff *skb)
>      if (nlh->nlmsg_type != AUDIT_EOE) {
>          printk(KERN_NOTICE "type=%d %s\n", nlh->nlmsg_type, data);
>      }
> +}
>
> +/*
> + * For one reason or another this nlh isn't getting delivered to the
> userspace
> + * audit daemon, just send it to printk.
> + */
> +static void audit_printk_skb(struct sk_buff *skb)
> +{
> +    __audit_printk_skb(skb);
>      audit_hold_skb(skb);
>  }
>
> @@ -681,6 +703,7 @@ static int audit_receive_msg(struct sk_buff *skb,
> struct nlmsghdr *nlh)
>      case AUDIT_GET:
>          status_set.enabled     = audit_enabled;
>          status_set.failure     = audit_failure;
> +        status_set.logsplit     = audit_logsplit;
>          status_set.pid         = audit_pid;
>          status_set.rate_limit     = audit_rate_limit;
>          status_set.backlog_limit = audit_backlog_limit;
> @@ -725,6 +748,15 @@ static int audit_receive_msg(struct sk_buff *skb,
> struct nlmsghdr *nlh)
>          if (status_get->mask & AUDIT_STATUS_BACKLOG_LIMIT)
>              err = audit_set_backlog_limit(status_get->backlog_limit,
>                                loginuid, sessionid, sid);
> +
> +        if (status_get->mask & AUDIT_STATUS_LOGSPLIT) {
> +            err = audit_set_logsplit(status_get->logsplit,
> +                        loginuid, sessionid, sid);
> +
> +            if (err < 0) {
> +                return err;
> +            }
> +        }
>          break;
>      case AUDIT_USER:
>      case AUDIT_FIRST_USER_MSG ... AUDIT_LAST_USER_MSG:
> @@ -1464,6 +1496,8 @@ void audit_log_end(struct audit_buffer *ab)
>          nlh->nlmsg_len = ab->skb->len - NLMSG_SPACE(0);
>
>          if (audit_pid) {
> +            if(audit_logsplit == AUDIT_LOGSPLIT_ON)
> +                __audit_printk_skb(ab->skb);
>              skb_queue_tail(&audit_skb_queue, ab->skb);
>              wake_up_interruptible(&kauditd_wait);
>          } else {
> --
> 1.8.2.2
>
>
>
I also applied these diffs to their respective projects (2 diffs below) I
also attached the patches as well. I can do a pull request via bitbucket if
desired.

seandroid system/core
diff --git a/auditd/auditd.c b/auditd/auditd.c
index 7291d34..852445d 100644
--- a/auditd/auditd.c
+++ b/auditd/auditd.c
@@ -178,6 +178,9 @@ int main(int argc, char *argv[])
         goto err;
     }

+    SLOGE("Bill Turning on logsplit");
+    c = audit_set_logsplit(audit_fd, AUDIT_LOGSPLIT_ON, WAIT_NO);
+    SLOGE("Bill Turning on logsplit error: %d", c);
     if (audit_set_pid(audit_fd, getpid(), WAIT_YES) < 0) {
         rc = errno;
         SLOGE("Failed on audit_set_pid with error: %s", strerror(errno));
diff --git a/auditd/libaudit.c b/auditd/libaudit.c
index 06e5557..461c592 100644
--- a/auditd/libaudit.c
+++ b/auditd/libaudit.c
@@ -329,3 +329,50 @@ void audit_close(int fd)
     }
     return;
 }
+
+extern int audit_set_logsplit(int fd, int flags,rep_wait_t wmode)
+{
+    int rc;
+    struct audit_reply rep;
+    struct audit_status status;
+
+    memset(&status, 0, sizeof(status));
+
+    if(flags != AUDIT_LOGSPLIT_OFF ||
+            flags != AUDIT_LOGSPLIT_ON) {
+        SLOGE("Invalid logsplit flag of: %x\n", flags);
+    }
+
+    /*
+     * In order to set the auditd PID we send an audit message over the
netlink socket
+     * with the pid field of the status struct set to our current pid, and
the
+     * the mask set to AUDIT_STATUS_PID
+     */
+    status.logsplit = flags;
+    status.mask = AUDIT_STATUS_LOGSPLIT;
+
+    /* Let the kernel know this pid will be registering for audit events */
+    rc = audit_send(fd, AUDIT_SET, &status, sizeof(status));
+    if (rc < 0) {
+        SLOGE("Could net set splitlog for audit events, error: %s",
strerror(-rc));
+        return rc;
+    }
+
+    /*
+     * 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
+     */
+    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);
+    }
+
+    return 0;
+}
+
diff --git a/auditd/libaudit.h b/auditd/libaudit.h
index fbaa7b9..d4624a9 100644
--- a/auditd/libaudit.h
+++ b/auditd/libaudit.h
@@ -108,4 +108,6 @@ extern int  audit_get_reply(int fd, struct audit_reply
*rep, reply_t block,
  */
 extern int  audit_set_pid(int fd, uint32_t pid, rep_wait_t wmode);

+extern int audit_set_logsplit(int fd, int flags, rep_wait_t wmode);
+
 #endif
-------------------------------------------------------------------------------------------

master bionic
diff --git a/libc/kernel/common/linux/audit.h
b/libc/kernel/common/linux/audit.h
index cbea684..f786b9c 100644
--- a/libc/kernel/common/linux/audit.h
+++ b/libc/kernel/common/linux/audit.h
@@ -273,6 +273,9 @@ enum {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define AUDIT_STATUS_RATE_LIMIT 0x0008
 #define AUDIT_STATUS_BACKLOG_LIMIT 0x0010
+#define AUDIT_STATUS_LOGSPLIT 0x0020
+#define AUDIT_LOGSPLIT_OFF 0
+#define AUDIT_LOGSPLIT_ON 1
 #define AUDIT_FAIL_SILENT 0
 #define AUDIT_FAIL_PRINTK 1
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
@@ -323,6 +326,7 @@ struct audit_status {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
  __u32 enabled;
  __u32 failure;
+ __u32 logsplit;
  __u32 pid;
  __u32 rate_limit;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */


-- 
Respectfully,

William C Roberts

Attachment: 0001-Enable-splitting-the-logs-to-both-auditd-and-kernel-.patch
Description: Binary data

Attachment: bionic_auditlogsplit.patch
Description: Binary data

Attachment: system_core_auditd_auditlogsplit.patch
Description: Binary data

Reply via email to