On Wed, May 15, 2013 at 6:55 PM, William Roberts <[email protected]>wrote:
> > > > 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 > > Bitbucket: https://bitbucket.org/seandroid/kernel-msm/pull-request/1/enable-splitting-the-logs-to-both-auditd -- Respectfully, William C Roberts
