aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/audit.c102
1 files changed, 81 insertions, 21 deletions
diff --git a/kernel/audit.c b/kernel/audit.c
index ad6d1abfa1d2..fee9052eb5cf 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -126,6 +126,8 @@ static int audit_freelist_count;
126static LIST_HEAD(audit_freelist); 126static LIST_HEAD(audit_freelist);
127 127
128static struct sk_buff_head audit_skb_queue; 128static struct sk_buff_head audit_skb_queue;
129/* queue of skbs to send to auditd when/if it comes back */
130static struct sk_buff_head audit_skb_hold_queue;
129static struct task_struct *kauditd_task; 131static struct task_struct *kauditd_task;
130static DECLARE_WAIT_QUEUE_HEAD(kauditd_wait); 132static DECLARE_WAIT_QUEUE_HEAD(kauditd_wait);
131static DECLARE_WAIT_QUEUE_HEAD(audit_backlog_wait); 133static DECLARE_WAIT_QUEUE_HEAD(audit_backlog_wait);
@@ -347,30 +349,83 @@ static int audit_set_failure(int state, uid_t loginuid, u32 sessionid, u32 sid)
347 loginuid, sessionid, sid); 349 loginuid, sessionid, sid);
348} 350}
349 351
352/*
353 * Queue skbs to be sent to auditd when/if it comes back. These skbs should
354 * already have been sent via prink/syslog and so if these messages are dropped
355 * it is not a huge concern since we already passed the audit_log_lost()
356 * notification and stuff. This is just nice to get audit messages during
357 * boot before auditd is running or messages generated while auditd is stopped.
358 * This only holds messages is audit_default is set, aka booting with audit=1
359 * or building your kernel that way.
360 */
361static void audit_hold_skb(struct sk_buff *skb)
362{
363 if (audit_default &&
364 skb_queue_len(&audit_skb_hold_queue) < audit_backlog_limit)
365 skb_queue_tail(&audit_skb_hold_queue, skb);
366 else
367 kfree_skb(skb);
368}
369
370static void kauditd_send_skb(struct sk_buff *skb)
371{
372 int err;
373 /* take a reference in case we can't send it and we want to hold it */
374 skb_get(skb);
375 err = netlink_unicast(audit_sock, skb, audit_nlk_pid, 0);
376 if (err < 0) {
377 BUG_ON(err != -ECONNREFUSED); /* Shoudn't happen */
378 printk(KERN_ERR "audit: *NO* daemon at audit_pid=%d\n", audit_pid);
379 audit_log_lost("auditd dissapeared\n");
380 audit_pid = 0;
381 /* we might get lucky and get this in the next auditd */
382 audit_hold_skb(skb);
383 } else
384 /* drop the extra reference if sent ok */
385 kfree_skb(skb);
386}
387
350static int kauditd_thread(void *dummy) 388static int kauditd_thread(void *dummy)
351{ 389{
352 struct sk_buff *skb; 390 struct sk_buff *skb;
353 391
354 set_freezable(); 392 set_freezable();
355 while (!kthread_should_stop()) { 393 while (!kthread_should_stop()) {
394 /*
395 * if auditd just started drain the queue of messages already
396 * sent to syslog/printk. remember loss here is ok. we already
397 * called audit_log_lost() if it didn't go out normally. so the
398 * race between the skb_dequeue and the next check for audit_pid
399 * doesn't matter.
400 *
401 * if you ever find kauditd to be too slow we can get a perf win
402 * by doing our own locking and keeping better track if there
403 * are messages in this queue. I don't see the need now, but
404 * in 5 years when I want to play with this again I'll see this
405 * note and still have no friggin idea what i'm thinking today.
406 */
407 if (audit_default && audit_pid) {
408 skb = skb_dequeue(&audit_skb_hold_queue);
409 if (unlikely(skb)) {
410 while (skb && audit_pid) {
411 kauditd_send_skb(skb);
412 skb = skb_dequeue(&audit_skb_hold_queue);
413 }
414 }
415 }
416
356 skb = skb_dequeue(&audit_skb_queue); 417 skb = skb_dequeue(&audit_skb_queue);
357 wake_up(&audit_backlog_wait); 418 wake_up(&audit_backlog_wait);
358 if (skb) { 419 if (skb) {
359 if (audit_pid) { 420 if (audit_pid)
360 int err = netlink_unicast(audit_sock, skb, audit_nlk_pid, 0); 421 kauditd_send_skb(skb);
361 if (err < 0) { 422 else {
362 BUG_ON(err != -ECONNREFUSED); /* Shoudn't happen */
363 printk(KERN_ERR "audit: *NO* daemon at audit_pid=%d\n", audit_pid);
364 audit_log_lost("auditd dissapeared\n");
365 audit_pid = 0;
366 }
367 } else {
368 if (printk_ratelimit()) 423 if (printk_ratelimit())
369 printk(KERN_NOTICE "%s\n", skb->data + 424 printk(KERN_NOTICE "%s\n", skb->data + NLMSG_SPACE(0));
370 NLMSG_SPACE(0));
371 else 425 else
372 audit_log_lost("printk limit exceeded\n"); 426 audit_log_lost("printk limit exceeded\n");
373 kfree_skb(skb); 427
428 audit_hold_skb(skb);
374 } 429 }
375 } else { 430 } else {
376 DECLARE_WAITQUEUE(wait, current); 431 DECLARE_WAITQUEUE(wait, current);
@@ -885,6 +940,7 @@ static int __init audit_init(void)
885 audit_sock->sk_sndtimeo = MAX_SCHEDULE_TIMEOUT; 940 audit_sock->sk_sndtimeo = MAX_SCHEDULE_TIMEOUT;
886 941
887 skb_queue_head_init(&audit_skb_queue); 942 skb_queue_head_init(&audit_skb_queue);
943 skb_queue_head_init(&audit_skb_hold_queue);
888 audit_initialized = 1; 944 audit_initialized = 1;
889 audit_enabled = audit_default; 945 audit_enabled = audit_default;
890 audit_ever_enabled |= !!audit_default; 946 audit_ever_enabled |= !!audit_default;
@@ -1363,19 +1419,23 @@ void audit_log_end(struct audit_buffer *ab)
1363 audit_log_lost("rate limit exceeded"); 1419 audit_log_lost("rate limit exceeded");
1364 } else { 1420 } else {
1365 struct nlmsghdr *nlh = nlmsg_hdr(ab->skb); 1421 struct nlmsghdr *nlh = nlmsg_hdr(ab->skb);
1422 nlh->nlmsg_len = ab->skb->len - NLMSG_SPACE(0);
1423
1366 if (audit_pid) { 1424 if (audit_pid) {
1367 nlh->nlmsg_len = ab->skb->len - NLMSG_SPACE(0);
1368 skb_queue_tail(&audit_skb_queue, ab->skb); 1425 skb_queue_tail(&audit_skb_queue, ab->skb);
1369 ab->skb = NULL;
1370 wake_up_interruptible(&kauditd_wait); 1426 wake_up_interruptible(&kauditd_wait);
1371 } else if (nlh->nlmsg_type != AUDIT_EOE) { 1427 } else {
1372 if (printk_ratelimit()) { 1428 if (nlh->nlmsg_type != AUDIT_EOE) {
1373 printk(KERN_NOTICE "type=%d %s\n", 1429 if (printk_ratelimit()) {
1374 nlh->nlmsg_type, 1430 printk(KERN_NOTICE "type=%d %s\n",
1375 ab->skb->data + NLMSG_SPACE(0)); 1431 nlh->nlmsg_type,
1376 } else 1432 ab->skb->data + NLMSG_SPACE(0));
1377 audit_log_lost("printk limit exceeded\n"); 1433 } else
1434 audit_log_lost("printk limit exceeded\n");
1435 }
1436 audit_hold_skb(ab->skb);
1378 } 1437 }
1438 ab->skb = NULL;
1379 } 1439 }
1380 audit_buffer_free(ab); 1440 audit_buffer_free(ab);
1381} 1441}