aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/audit.h1
-rw-r--r--kernel/audit.c2
-rw-r--r--kernel/auditsc.c53
3 files changed, 47 insertions, 9 deletions
diff --git a/include/linux/audit.h b/include/linux/audit.h
index 5f812e4d01e4..5d1a9dda5acb 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -281,6 +281,7 @@ extern void audit_send_reply(int pid, int seq, int type,
281 int done, int multi, 281 int done, int multi,
282 void *payload, int size); 282 void *payload, int size);
283extern void audit_log_lost(const char *message); 283extern void audit_log_lost(const char *message);
284extern struct semaphore audit_netlink_sem;
284#else 285#else
285#define audit_log(c,t,f,...) do { ; } while (0) 286#define audit_log(c,t,f,...) do { ; } while (0)
286#define audit_log_start(c,t) ({ NULL; }) 287#define audit_log_start(c,t) ({ NULL; })
diff --git a/kernel/audit.c b/kernel/audit.c
index ab6ac560cfe5..c1ab8dbbb67b 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -110,7 +110,7 @@ static DECLARE_WAIT_QUEUE_HEAD(kauditd_wait);
110/* The netlink socket is only to be read by 1 CPU, which lets us assume 110/* The netlink socket is only to be read by 1 CPU, which lets us assume
111 * that list additions and deletions never happen simultaneously in 111 * that list additions and deletions never happen simultaneously in
112 * auditsc.c */ 112 * auditsc.c */
113static DECLARE_MUTEX(audit_netlink_sem); 113DECLARE_MUTEX(audit_netlink_sem);
114 114
115/* AUDIT_BUFSIZ is the size of the temporary buffer used for formatting 115/* AUDIT_BUFSIZ is the size of the temporary buffer used for formatting
116 * audit records. Since printk uses a 1024 byte buffer, this buffer 116 * audit records. Since printk uses a 1024 byte buffer, this buffer
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index 031f979019d1..cb8a44945157 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -39,6 +39,7 @@
39#include <linux/audit.h> 39#include <linux/audit.h>
40#include <linux/personality.h> 40#include <linux/personality.h>
41#include <linux/time.h> 41#include <linux/time.h>
42#include <linux/kthread.h>
42#include <asm/unistd.h> 43#include <asm/unistd.h>
43 44
44/* 0 = no checking 45/* 0 = no checking
@@ -281,24 +282,60 @@ static int audit_copy_rule(struct audit_rule *d, struct audit_rule *s)
281 return 0; 282 return 0;
282} 283}
283 284
285static int audit_list_rules(void *_dest)
286{
287 int pid, seq;
288 int *dest = _dest;
289 struct audit_entry *entry;
290 int i;
291
292 pid = dest[0];
293 seq = dest[1];
294 kfree(dest);
295
296 down(&audit_netlink_sem);
297
298 /* The *_rcu iterators not needed here because we are
299 always called with audit_netlink_sem held. */
300 for (i=0; i<AUDIT_NR_FILTERS; i++) {
301 list_for_each_entry(entry, &audit_filter_list[i], list)
302 audit_send_reply(pid, seq, AUDIT_LIST, 0, 1,
303 &entry->rule, sizeof(entry->rule));
304 }
305 audit_send_reply(pid, seq, AUDIT_LIST, 1, 1, NULL, 0);
306
307 up(&audit_netlink_sem);
308 return 0;
309}
310
284int audit_receive_filter(int type, int pid, int uid, int seq, void *data, 311int audit_receive_filter(int type, int pid, int uid, int seq, void *data,
285 uid_t loginuid) 312 uid_t loginuid)
286{ 313{
287 struct audit_entry *entry; 314 struct audit_entry *entry;
315 struct task_struct *tsk;
316 int *dest;
288 int err = 0; 317 int err = 0;
289 int i;
290 unsigned listnr; 318 unsigned listnr;
291 319
292 switch (type) { 320 switch (type) {
293 case AUDIT_LIST: 321 case AUDIT_LIST:
294 /* The *_rcu iterators not needed here because we are 322 /* We can't just spew out the rules here because we might fill
295 always called with audit_netlink_sem held. */ 323 * the available socket buffer space and deadlock waiting for
296 for (i=0; i<AUDIT_NR_FILTERS; i++) { 324 * auditctl to read from it... which isn't ever going to
297 list_for_each_entry(entry, &audit_filter_list[i], list) 325 * happen if we're actually running in the context of auditctl
298 audit_send_reply(pid, seq, AUDIT_LIST, 0, 1, 326 * trying to _send_ the stuff */
299 &entry->rule, sizeof(entry->rule)); 327
328 dest = kmalloc(2 * sizeof(int), GFP_KERNEL);
329 if (!dest)
330 return -ENOMEM;
331 dest[0] = pid;
332 dest[1] = seq;
333
334 tsk = kthread_run(audit_list_rules, dest, "audit_list_rules");
335 if (IS_ERR(tsk)) {
336 kfree(dest);
337 err = PTR_ERR(tsk);
300 } 338 }
301 audit_send_reply(pid, seq, AUDIT_LIST, 1, 1, NULL, 0);
302 break; 339 break;
303 case AUDIT_ADD: 340 case AUDIT_ADD:
304 if (!(entry = kmalloc(sizeof(*entry), GFP_KERNEL))) 341 if (!(entry = kmalloc(sizeof(*entry), GFP_KERNEL)))