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
0001-Enable-splitting-the-logs-to-both-auditd-and-kernel-.patch
Description: Binary data
bionic_auditlogsplit.patch
Description: Binary data
system_core_auditd_auditlogsplit.patch
Description: Binary data
