aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorDavid Woodhouse <dwmw2@shinybook.infradead.org>2005-05-19 05:56:58 -0400
committerDavid Woodhouse <dwmw2@shinybook.infradead.org>2005-05-19 05:56:58 -0400
commitb7d1125817c9a46cc46f57db89d9c195e7af22f8 (patch)
treec1096ff7ae35b77bf8108c3a60b856551c50a9d7 /kernel
parent168b7173959f80d20720dd1f7ec909a88ef2689d (diff)
AUDIT: Send netlink messages from a separate kernel thread
netlink_unicast() will attempt to reallocate and will free messages if the socket's rcvbuf limit is reached unless we give it an infinite timeout. So do that, from a kernel thread which is dedicated to spewing stuff up the netlink socket. Signed-off-by: David Woodhouse <dwmw2@infradead.org>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/audit.c191
1 files changed, 70 insertions, 121 deletions
diff --git a/kernel/audit.c b/kernel/audit.c
index dae3570b3a3b..bbc6f542c8f7 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -46,6 +46,8 @@
46#include <asm/types.h> 46#include <asm/types.h>
47#include <linux/mm.h> 47#include <linux/mm.h>
48#include <linux/module.h> 48#include <linux/module.h>
49#include <linux/err.h>
50#include <linux/kthread.h>
49 51
50#include <linux/audit.h> 52#include <linux/audit.h>
51 53
@@ -77,7 +79,6 @@ static int audit_rate_limit;
77 79
78/* Number of outstanding audit_buffers allowed. */ 80/* Number of outstanding audit_buffers allowed. */
79static int audit_backlog_limit = 64; 81static int audit_backlog_limit = 64;
80static atomic_t audit_backlog = ATOMIC_INIT(0);
81 82
82/* The identity of the user shutting down the audit system. */ 83/* The identity of the user shutting down the audit system. */
83uid_t audit_sig_uid = -1; 84uid_t audit_sig_uid = -1;
@@ -95,19 +96,17 @@ static atomic_t audit_lost = ATOMIC_INIT(0);
95/* The netlink socket. */ 96/* The netlink socket. */
96static struct sock *audit_sock; 97static struct sock *audit_sock;
97 98
98/* There are two lists of audit buffers. The txlist contains audit 99/* The audit_freelist is a list of pre-allocated audit buffers (if more
99 * buffers that cannot be sent immediately to the netlink device because
100 * we are in an irq context (these are sent later in a tasklet).
101 *
102 * The second list is a list of pre-allocated audit buffers (if more
103 * than AUDIT_MAXFREE are in use, the audit buffer is freed instead of 100 * than AUDIT_MAXFREE are in use, the audit buffer is freed instead of
104 * being placed on the freelist). */ 101 * being placed on the freelist). */
105static DEFINE_SPINLOCK(audit_txlist_lock);
106static DEFINE_SPINLOCK(audit_freelist_lock); 102static DEFINE_SPINLOCK(audit_freelist_lock);
107static int audit_freelist_count = 0; 103static int audit_freelist_count = 0;
108static LIST_HEAD(audit_txlist);
109static LIST_HEAD(audit_freelist); 104static LIST_HEAD(audit_freelist);
110 105
106static struct sk_buff_head audit_skb_queue;
107static struct task_struct *kauditd_task;
108static DECLARE_WAIT_QUEUE_HEAD(kauditd_wait);
109
111/* There are three lists of rules -- one to search at task creation 110/* There are three lists of rules -- one to search at task creation
112 * time, one to search at syscall entry time, and another to search at 111 * time, one to search at syscall entry time, and another to search at
113 * syscall exit time. */ 112 * syscall exit time. */
@@ -151,9 +150,6 @@ struct audit_entry {
151 struct audit_rule rule; 150 struct audit_rule rule;
152}; 151};
153 152
154static void audit_log_end_irq(struct audit_buffer *ab);
155static void audit_log_end_fast(struct audit_buffer *ab);
156
157static void audit_panic(const char *message) 153static void audit_panic(const char *message)
158{ 154{
159 switch (audit_failure) 155 switch (audit_failure)
@@ -224,10 +220,8 @@ void audit_log_lost(const char *message)
224 220
225 if (print) { 221 if (print) {
226 printk(KERN_WARNING 222 printk(KERN_WARNING
227 "audit: audit_lost=%d audit_backlog=%d" 223 "audit: audit_lost=%d audit_rate_limit=%d audit_backlog_limit=%d\n",
228 " audit_rate_limit=%d audit_backlog_limit=%d\n",
229 atomic_read(&audit_lost), 224 atomic_read(&audit_lost),
230 atomic_read(&audit_backlog),
231 audit_rate_limit, 225 audit_rate_limit,
232 audit_backlog_limit); 226 audit_backlog_limit);
233 audit_panic(message); 227 audit_panic(message);
@@ -281,6 +275,38 @@ static int audit_set_failure(int state, uid_t loginuid)
281 return old; 275 return old;
282} 276}
283 277
278int kauditd_thread(void *dummy)
279{
280 struct sk_buff *skb;
281
282 while (1) {
283 skb = skb_dequeue(&audit_skb_queue);
284 if (skb) {
285 if (audit_pid) {
286 int err = netlink_unicast(audit_sock, skb, audit_pid, 0);
287 if (err < 0) {
288 BUG_ON(err != -ECONNREFUSED); /* Shoudn't happen */
289 printk(KERN_ERR "audit: *NO* daemon at audit_pid=%d\n", audit_pid);
290 audit_pid = 0;
291 }
292 } else {
293 printk(KERN_ERR "%s\n", skb->data + NLMSG_SPACE(0));
294 kfree_skb(skb);
295 }
296 } else {
297 DECLARE_WAITQUEUE(wait, current);
298 set_current_state(TASK_INTERRUPTIBLE);
299 add_wait_queue(&kauditd_wait, &wait);
300
301 if (!skb_queue_len(&audit_skb_queue))
302 schedule();
303
304 __set_current_state(TASK_RUNNING);
305 remove_wait_queue(&kauditd_wait, &wait);
306 }
307 }
308}
309
284void audit_send_reply(int pid, int seq, int type, int done, int multi, 310void audit_send_reply(int pid, int seq, int type, int done, int multi,
285 void *payload, int size) 311 void *payload, int size)
286{ 312{
@@ -293,13 +319,16 @@ void audit_send_reply(int pid, int seq, int type, int done, int multi,
293 319
294 skb = alloc_skb(len, GFP_KERNEL); 320 skb = alloc_skb(len, GFP_KERNEL);
295 if (!skb) 321 if (!skb)
296 goto nlmsg_failure; 322 return;
297 323
298 nlh = NLMSG_PUT(skb, pid, seq, t, len - sizeof(*nlh)); 324 nlh = NLMSG_PUT(skb, pid, seq, t, size);
299 nlh->nlmsg_flags = flags; 325 nlh->nlmsg_flags = flags;
300 data = NLMSG_DATA(nlh); 326 data = NLMSG_DATA(nlh);
301 memcpy(data, payload, size); 327 memcpy(data, payload, size);
302 netlink_unicast(audit_sock, skb, pid, MSG_DONTWAIT); 328
329 /* Ignore failure. It'll only happen if the sender goes away,
330 because our timeout is set to infinite. */
331 netlink_unicast(audit_sock, skb, pid, 0);
303 return; 332 return;
304 333
305nlmsg_failure: /* Used by NLMSG_PUT */ 334nlmsg_failure: /* Used by NLMSG_PUT */
@@ -351,6 +380,15 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
351 if (err) 380 if (err)
352 return err; 381 return err;
353 382
383 /* As soon as there's any sign of userspace auditd, start kauditd to talk to it */
384 if (!kauditd_task)
385 kauditd_task = kthread_run(kauditd_thread, NULL, "kauditd");
386 if (IS_ERR(kauditd_task)) {
387 err = PTR_ERR(kauditd_task);
388 kauditd_task = NULL;
389 return err;
390 }
391
354 pid = NETLINK_CREDS(skb)->pid; 392 pid = NETLINK_CREDS(skb)->pid;
355 uid = NETLINK_CREDS(skb)->uid; 393 uid = NETLINK_CREDS(skb)->uid;
356 loginuid = NETLINK_CB(skb).loginuid; 394 loginuid = NETLINK_CB(skb).loginuid;
@@ -365,7 +403,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
365 status_set.rate_limit = audit_rate_limit; 403 status_set.rate_limit = audit_rate_limit;
366 status_set.backlog_limit = audit_backlog_limit; 404 status_set.backlog_limit = audit_backlog_limit;
367 status_set.lost = atomic_read(&audit_lost); 405 status_set.lost = atomic_read(&audit_lost);
368 status_set.backlog = atomic_read(&audit_backlog); 406 status_set.backlog = skb_queue_len(&audit_skb_queue);
369 audit_send_reply(NETLINK_CB(skb).pid, seq, AUDIT_GET, 0, 0, 407 audit_send_reply(NETLINK_CB(skb).pid, seq, AUDIT_GET, 0, 0,
370 &status_set, sizeof(status_set)); 408 &status_set, sizeof(status_set));
371 break; 409 break;
@@ -471,44 +509,6 @@ static void audit_receive(struct sock *sk, int length)
471 up(&audit_netlink_sem); 509 up(&audit_netlink_sem);
472} 510}
473 511
474/* Grab skbuff from the audit_buffer and send to user space. */
475static inline int audit_log_drain(struct audit_buffer *ab)
476{
477 struct sk_buff *skb = ab->skb;
478
479 if (skb) {
480 int retval = 0;
481
482 if (audit_pid) {
483 struct nlmsghdr *nlh = (struct nlmsghdr *)skb->data;
484 nlh->nlmsg_len = skb->len - NLMSG_SPACE(0);
485 skb_get(skb); /* because netlink_* frees */
486 retval = netlink_unicast(audit_sock, skb, audit_pid,
487 MSG_DONTWAIT);
488 }
489 if (retval == -EAGAIN &&
490 (atomic_read(&audit_backlog)) < audit_backlog_limit) {
491 audit_log_end_irq(ab);
492 return 1;
493 }
494 if (retval < 0) {
495 if (retval == -ECONNREFUSED) {
496 printk(KERN_ERR
497 "audit: *NO* daemon at audit_pid=%d\n",
498 audit_pid);
499 audit_pid = 0;
500 } else
501 audit_log_lost("netlink socket too busy");
502 }
503 if (!audit_pid) { /* No daemon */
504 int offset = NLMSG_SPACE(0);
505 int len = skb->len - offset;
506 skb->data[offset + len] = '\0';
507 printk(KERN_ERR "%s\n", skb->data + offset);
508 }
509 }
510 return 0;
511}
512 512
513/* Initialize audit support at boot time. */ 513/* Initialize audit support at boot time. */
514static int __init audit_init(void) 514static int __init audit_init(void)
@@ -519,6 +519,8 @@ static int __init audit_init(void)
519 if (!audit_sock) 519 if (!audit_sock)
520 audit_panic("cannot initialize netlink socket"); 520 audit_panic("cannot initialize netlink socket");
521 521
522 audit_sock->sk_sndtimeo = MAX_SCHEDULE_TIMEOUT;
523 skb_queue_head_init(&audit_skb_queue);
522 audit_initialized = 1; 524 audit_initialized = 1;
523 audit_enabled = audit_default; 525 audit_enabled = audit_default;
524 audit_log(NULL, AUDIT_KERNEL, "initialized"); 526 audit_log(NULL, AUDIT_KERNEL, "initialized");
@@ -549,7 +551,7 @@ static void audit_buffer_free(struct audit_buffer *ab)
549 551
550 if (ab->skb) 552 if (ab->skb)
551 kfree_skb(ab->skb); 553 kfree_skb(ab->skb);
552 atomic_dec(&audit_backlog); 554
553 spin_lock_irqsave(&audit_freelist_lock, flags); 555 spin_lock_irqsave(&audit_freelist_lock, flags);
554 if (++audit_freelist_count > AUDIT_MAXFREE) 556 if (++audit_freelist_count > AUDIT_MAXFREE)
555 kfree(ab); 557 kfree(ab);
@@ -579,13 +581,12 @@ static struct audit_buffer * audit_buffer_alloc(struct audit_context *ctx,
579 if (!ab) 581 if (!ab)
580 goto err; 582 goto err;
581 } 583 }
582 atomic_inc(&audit_backlog);
583 584
584 ab->skb = alloc_skb(AUDIT_BUFSIZ, gfp_mask); 585 ab->skb = alloc_skb(AUDIT_BUFSIZ, gfp_mask);
585 if (!ab->skb) 586 if (!ab->skb)
586 goto err; 587 goto err;
587 588
588 ab->ctx = ctx; 589 ab->ctx = ctx;
589 nlh = (struct nlmsghdr *)skb_put(ab->skb, NLMSG_SPACE(0)); 590 nlh = (struct nlmsghdr *)skb_put(ab->skb, NLMSG_SPACE(0));
590 nlh->nlmsg_type = type; 591 nlh->nlmsg_type = type;
591 nlh->nlmsg_flags = 0; 592 nlh->nlmsg_flags = 0;
@@ -612,18 +613,6 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx, int type)
612 if (!audit_initialized) 613 if (!audit_initialized)
613 return NULL; 614 return NULL;
614 615
615 if (audit_backlog_limit
616 && atomic_read(&audit_backlog) > audit_backlog_limit) {
617 if (audit_rate_check())
618 printk(KERN_WARNING
619 "audit: audit_backlog=%d > "
620 "audit_backlog_limit=%d\n",
621 atomic_read(&audit_backlog),
622 audit_backlog_limit);
623 audit_log_lost("backlog limit exceeded");
624 return NULL;
625 }
626
627 ab = audit_buffer_alloc(ctx, GFP_ATOMIC, type); 616 ab = audit_buffer_alloc(ctx, GFP_ATOMIC, type);
628 if (!ab) { 617 if (!ab) {
629 audit_log_lost("out of memory in audit_log_start"); 618 audit_log_lost("out of memory in audit_log_start");
@@ -784,70 +773,30 @@ void audit_log_d_path(struct audit_buffer *ab, const char *prefix,
784 kfree(path); 773 kfree(path);
785} 774}
786 775
787/* Remove queued messages from the audit_txlist and send them to user space. */
788static void audit_tasklet_handler(unsigned long arg)
789{
790 LIST_HEAD(list);
791 struct audit_buffer *ab;
792 unsigned long flags;
793
794 spin_lock_irqsave(&audit_txlist_lock, flags);
795 list_splice_init(&audit_txlist, &list);
796 spin_unlock_irqrestore(&audit_txlist_lock, flags);
797
798 while (!list_empty(&list)) {
799 ab = list_entry(list.next, struct audit_buffer, list);
800 list_del(&ab->list);
801 audit_log_end_fast(ab);
802 }
803}
804
805static DECLARE_TASKLET(audit_tasklet, audit_tasklet_handler, 0);
806
807/* The netlink_* functions cannot be called inside an irq context, so 776/* The netlink_* functions cannot be called inside an irq context, so
808 * the audit buffer is places on a queue and a tasklet is scheduled to 777 * the audit buffer is places on a queue and a tasklet is scheduled to
809 * remove them from the queue outside the irq context. May be called in 778 * remove them from the queue outside the irq context. May be called in
810 * any context. */ 779 * any context. */
811static void audit_log_end_irq(struct audit_buffer *ab) 780void audit_log_end(struct audit_buffer *ab)
812{
813 unsigned long flags;
814
815 if (!ab)
816 return;
817 spin_lock_irqsave(&audit_txlist_lock, flags);
818 list_add_tail(&ab->list, &audit_txlist);
819 spin_unlock_irqrestore(&audit_txlist_lock, flags);
820
821 tasklet_schedule(&audit_tasklet);
822}
823
824/* Send the message in the audit buffer directly to user space. May not
825 * be called in an irq context. */
826static void audit_log_end_fast(struct audit_buffer *ab)
827{ 781{
828 BUG_ON(in_irq());
829 if (!ab) 782 if (!ab)
830 return; 783 return;
831 if (!audit_rate_check()) { 784 if (!audit_rate_check()) {
832 audit_log_lost("rate limit exceeded"); 785 audit_log_lost("rate limit exceeded");
833 } else { 786 } else {
834 if (audit_log_drain(ab)) 787 if (audit_pid) {
835 return; 788 struct nlmsghdr *nlh = (struct nlmsghdr *)ab->skb->data;
789 nlh->nlmsg_len = ab->skb->len - NLMSG_SPACE(0);
790 skb_queue_tail(&audit_skb_queue, ab->skb);
791 ab->skb = NULL;
792 wake_up_interruptible(&kauditd_wait);
793 } else {
794 printk("%s\n", ab->skb->data + NLMSG_SPACE(0));
795 }
836 } 796 }
837 audit_buffer_free(ab); 797 audit_buffer_free(ab);
838} 798}
839 799
840/* Send or queue the message in the audit buffer, depending on the
841 * current context. (A convenience function that may be called in any
842 * context.) */
843void audit_log_end(struct audit_buffer *ab)
844{
845 if (in_irq())
846 audit_log_end_irq(ab);
847 else
848 audit_log_end_fast(ab);
849}
850
851/* Log an audit record. This is a convenience function that calls 800/* Log an audit record. This is a convenience function that calls
852 * audit_log_start, audit_log_vformat, and audit_log_end. It may be 801 * audit_log_start, audit_log_vformat, and audit_log_end. It may be
853 * called in any context. */ 802 * called in any context. */