From 1fb9314d013dec71386c4cf8834a037fe6539213 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Tue, 21 Jun 2005 16:22:01 +0100 Subject: [PATCH] --- yaml --- r: 8863 b: refs/heads/master c: f6a789d19858a951e7ff9e297a44b377c21b6c33 h: refs/heads/master i: 8861: e75d213e3fc4e9cf13805208060e3566b6d48b25 8859: 9c6c985eaaa671db4692d504accd470faffd4cae 8855: e8dcd595841feeed0a641494e91951335cae2b62 8847: 0b05324953ef95afb7c9e427986d874872836731 8831: 31da5f02e04af640010609ebbb7718a640c126f3 v: v3 --- [refs] | 2 +- trunk/include/linux/audit.h | 1 + trunk/kernel/audit.c | 2 +- trunk/kernel/auditsc.c | 53 +++++++++++++++++++++++++++++++------ 4 files changed, 48 insertions(+), 10 deletions(-) diff --git a/[refs] b/[refs] index cff49d888ba4..b2c4107a88df 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: ae7b961b1c943367dfe179411f120d7bf8eaba89 +refs/heads/master: f6a789d19858a951e7ff9e297a44b377c21b6c33 diff --git a/trunk/include/linux/audit.h b/trunk/include/linux/audit.h index 5f812e4d01e4..5d1a9dda5acb 100644 --- a/trunk/include/linux/audit.h +++ b/trunk/include/linux/audit.h @@ -281,6 +281,7 @@ extern void audit_send_reply(int pid, int seq, int type, int done, int multi, void *payload, int size); extern void audit_log_lost(const char *message); +extern struct semaphore audit_netlink_sem; #else #define audit_log(c,t,f,...) do { ; } while (0) #define audit_log_start(c,t) ({ NULL; }) diff --git a/trunk/kernel/audit.c b/trunk/kernel/audit.c index ab6ac560cfe5..c1ab8dbbb67b 100644 --- a/trunk/kernel/audit.c +++ b/trunk/kernel/audit.c @@ -110,7 +110,7 @@ static DECLARE_WAIT_QUEUE_HEAD(kauditd_wait); /* The netlink socket is only to be read by 1 CPU, which lets us assume * that list additions and deletions never happen simultaneously in * auditsc.c */ -static DECLARE_MUTEX(audit_netlink_sem); +DECLARE_MUTEX(audit_netlink_sem); /* AUDIT_BUFSIZ is the size of the temporary buffer used for formatting * audit records. Since printk uses a 1024 byte buffer, this buffer diff --git a/trunk/kernel/auditsc.c b/trunk/kernel/auditsc.c index 031f979019d1..cb8a44945157 100644 --- a/trunk/kernel/auditsc.c +++ b/trunk/kernel/auditsc.c @@ -39,6 +39,7 @@ #include #include #include +#include #include /* 0 = no checking @@ -281,24 +282,60 @@ static int audit_copy_rule(struct audit_rule *d, struct audit_rule *s) return 0; } +static int audit_list_rules(void *_dest) +{ + int pid, seq; + int *dest = _dest; + struct audit_entry *entry; + int i; + + pid = dest[0]; + seq = dest[1]; + kfree(dest); + + down(&audit_netlink_sem); + + /* The *_rcu iterators not needed here because we are + always called with audit_netlink_sem held. */ + for (i=0; irule, sizeof(entry->rule)); + } + audit_send_reply(pid, seq, AUDIT_LIST, 1, 1, NULL, 0); + + up(&audit_netlink_sem); + return 0; +} + int audit_receive_filter(int type, int pid, int uid, int seq, void *data, uid_t loginuid) { struct audit_entry *entry; + struct task_struct *tsk; + int *dest; int err = 0; - int i; unsigned listnr; switch (type) { case AUDIT_LIST: - /* The *_rcu iterators not needed here because we are - always called with audit_netlink_sem held. */ - for (i=0; irule, sizeof(entry->rule)); + /* We can't just spew out the rules here because we might fill + * the available socket buffer space and deadlock waiting for + * auditctl to read from it... which isn't ever going to + * happen if we're actually running in the context of auditctl + * trying to _send_ the stuff */ + + dest = kmalloc(2 * sizeof(int), GFP_KERNEL); + if (!dest) + return -ENOMEM; + dest[0] = pid; + dest[1] = seq; + + tsk = kthread_run(audit_list_rules, dest, "audit_list_rules"); + if (IS_ERR(tsk)) { + kfree(dest); + err = PTR_ERR(tsk); } - audit_send_reply(pid, seq, AUDIT_LIST, 1, 1, NULL, 0); break; case AUDIT_ADD: if (!(entry = kmalloc(sizeof(*entry), GFP_KERNEL)))