aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Moore <paul@paul-moore.com>2016-11-29 16:53:25 -0500
committerPaul Moore <paul@paul-moore.com>2016-12-14 13:06:04 -0500
commitc6480207fdf7b61de216ee23e93eac0a6878fa74 (patch)
tree30f4f77634a5564c6a7adbd5d953ba9ffc207769
parentaf8b824f283de5acc9b9ae8dbb60e4adacff721b (diff)
audit: rework the audit queue handling
The audit record backlog queue has always been a bit of a mess, and the moving the multicast send into kauditd_thread() from audit_log_end() only makes things worse. This patch attempts to fix the backlog queue with a better design that should hold up better under load and have less of a performance impact at syscall invocation time. While it looks like there is a log going on in this patch, the main change is the move from a single backlog queue to three queues: * A queue for holding records generated from audit_log_end() that haven't been consumed by kauditd_thread() (audit_queue). * A queue for holding records that have been sent via multicast but had a temporary failure when sending via unicast and need a resend (audit_retry_queue). * A queue for holding records that haven't been sent via unicast because no one is listening (audit_hold_queue). Special care is taken in this patch to ensure that the proper record ordering is preserved, e.g. we send everything in the hold queue first, then the retry queue, and finally the main queue. Signed-off-by: Paul Moore <paul@paul-moore.com>
-rw-r--r--kernel/audit.c347
1 files changed, 226 insertions, 121 deletions
diff --git a/kernel/audit.c b/kernel/audit.c
index 6ac1df116c0b..f4056bc331fc 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -138,11 +138,18 @@ static DEFINE_SPINLOCK(audit_freelist_lock);
138static int audit_freelist_count; 138static int audit_freelist_count;
139static LIST_HEAD(audit_freelist); 139static LIST_HEAD(audit_freelist);
140 140
141/* queue msgs to send via kauditd_task */
141static struct sk_buff_head audit_queue; 142static struct sk_buff_head audit_queue;
142/* queue of skbs to send to auditd when/if it comes back */ 143/* queue msgs due to temporary unicast send problems */
144static struct sk_buff_head audit_retry_queue;
145/* queue msgs waiting for new auditd connection */
143static struct sk_buff_head audit_hold_queue; 146static struct sk_buff_head audit_hold_queue;
147
148/* queue servicing thread */
144static struct task_struct *kauditd_task; 149static struct task_struct *kauditd_task;
145static DECLARE_WAIT_QUEUE_HEAD(kauditd_wait); 150static DECLARE_WAIT_QUEUE_HEAD(kauditd_wait);
151
152/* waitqueue for callers who are blocked on the audit backlog */
146static DECLARE_WAIT_QUEUE_HEAD(audit_backlog_wait); 153static DECLARE_WAIT_QUEUE_HEAD(audit_backlog_wait);
147 154
148static struct audit_features af = {.vers = AUDIT_FEATURE_VERSION, 155static struct audit_features af = {.vers = AUDIT_FEATURE_VERSION,
@@ -365,25 +372,6 @@ static int audit_set_failure(u32 state)
365} 372}
366 373
367/* 374/*
368 * Queue skbs to be sent to auditd when/if it comes back. These skbs should
369 * already have been sent via prink/syslog and so if these messages are dropped
370 * it is not a huge concern since we already passed the audit_log_lost()
371 * notification and stuff. This is just nice to get audit messages during
372 * boot before auditd is running or messages generated while auditd is stopped.
373 * This only holds messages is audit_default is set, aka booting with audit=1
374 * or building your kernel that way.
375 */
376static void audit_hold_skb(struct sk_buff *skb)
377{
378 if (audit_default &&
379 (!audit_backlog_limit ||
380 skb_queue_len(&audit_hold_queue) < audit_backlog_limit))
381 skb_queue_tail(&audit_hold_queue, skb);
382 else
383 kfree_skb(skb);
384}
385
386/*
387 * For one reason or another this nlh isn't getting delivered to the userspace 375 * For one reason or another this nlh isn't getting delivered to the userspace
388 * audit daemon, just send it to printk. 376 * audit daemon, just send it to printk.
389 */ 377 */
@@ -398,58 +386,114 @@ static void kauditd_printk_skb(struct sk_buff *skb)
398 else 386 else
399 audit_log_lost("printk limit exceeded"); 387 audit_log_lost("printk limit exceeded");
400 } 388 }
389}
390
391/**
392 * kauditd_hold_skb - Queue an audit record, waiting for auditd
393 * @skb: audit record
394 *
395 * Description:
396 * Queue the audit record, waiting for an instance of auditd. When this
397 * function is called we haven't given up yet on sending the record, but things
398 * are not looking good. The first thing we want to do is try to write the
399 * record via printk and then see if we want to try and hold on to the record
400 * and queue it, if we have room. If we want to hold on to the record, but we
401 * don't have room, record a record lost message.
402 */
403static void kauditd_hold_skb(struct sk_buff *skb)
404{
405 /* at this point it is uncertain if we will ever send this to auditd so
406 * try to send the message via printk before we go any further */
407 kauditd_printk_skb(skb);
408
409 /* can we just silently drop the message? */
410 if (!audit_default) {
411 kfree_skb(skb);
412 return;
413 }
414
415 /* if we have room, queue the message */
416 if (!audit_backlog_limit ||
417 skb_queue_len(&audit_hold_queue) < audit_backlog_limit) {
418 skb_queue_tail(&audit_hold_queue, skb);
419 return;
420 }
401 421
402 audit_hold_skb(skb); 422 /* we have no other options - drop the message */
423 audit_log_lost("kauditd hold queue overflow");
424 kfree_skb(skb);
403} 425}
404 426
405static void kauditd_send_unicast_skb(struct sk_buff *skb) 427/**
428 * kauditd_retry_skb - Queue an audit record, attempt to send again to auditd
429 * @skb: audit record
430 *
431 * Description:
432 * Not as serious as kauditd_hold_skb() as we still have a connected auditd,
433 * but for some reason we are having problems sending it audit records so
434 * queue the given record and attempt to resend.
435 */
436static void kauditd_retry_skb(struct sk_buff *skb)
406{ 437{
407 int err; 438 /* NOTE: because records should only live in the retry queue for a
408 int attempts = 0; 439 * short period of time, before either being sent or moved to the hold
409#define AUDITD_RETRIES 5 440 * queue, we don't currently enforce a limit on this queue */
441 skb_queue_tail(&audit_retry_queue, skb);
442}
443
444/**
445 * auditd_reset - Disconnect the auditd connection
446 *
447 * Description:
448 * Break the auditd/kauditd connection and move all the records in the retry
449 * queue into the hold queue in case auditd reconnects.
450 */
451static void auditd_reset(void)
452{
453 struct sk_buff *skb;
454
455 /* break the connection */
456 audit_pid = 0;
457 audit_sock = NULL;
458
459 /* flush all of the retry queue to the hold queue */
460 while ((skb = skb_dequeue(&audit_retry_queue)))
461 kauditd_hold_skb(skb);
462}
463
464/**
465 * kauditd_send_unicast_skb - Send a record via unicast to auditd
466 * @skb: audit record
467 */
468static int kauditd_send_unicast_skb(struct sk_buff *skb)
469{
470 int rc;
410 471
411restart: 472 /* get an extra skb reference in case we fail to send */
412 /* take a reference in case we can't send it and we want to hold it */
413 skb_get(skb); 473 skb_get(skb);
414 err = netlink_unicast(audit_sock, skb, audit_nlk_portid, 0); 474 rc = netlink_unicast(audit_sock, skb, audit_nlk_portid, 0);
415 if (err < 0) { 475 if (rc >= 0) {
416 pr_err("netlink_unicast sending to audit_pid=%d returned error: %d\n",
417 audit_pid, err);
418 if (audit_pid) {
419 if (err == -ECONNREFUSED || err == -EPERM
420 || ++attempts >= AUDITD_RETRIES) {
421 char s[32];
422
423 snprintf(s, sizeof(s), "audit_pid=%d reset", audit_pid);
424 audit_log_lost(s);
425 audit_pid = 0;
426 audit_sock = NULL;
427 } else {
428 pr_warn("re-scheduling(#%d) write to audit_pid=%d\n",
429 attempts, audit_pid);
430 set_current_state(TASK_INTERRUPTIBLE);
431 schedule();
432 goto restart;
433 }
434 }
435 /* we might get lucky and get this in the next auditd */
436 audit_hold_skb(skb);
437 } else
438 /* drop the extra reference if sent ok */
439 consume_skb(skb); 476 consume_skb(skb);
477 rc = 0;
478 }
479
480 return rc;
440} 481}
441 482
442/* 483/*
443 * kauditd_send_multicast_skb - send the skb to multicast userspace listeners 484 * kauditd_send_multicast_skb - Send a record to any multicast listeners
485 * @skb: audit record
444 * 486 *
487 * Description:
445 * This function doesn't consume an skb as might be expected since it has to 488 * This function doesn't consume an skb as might be expected since it has to
446 * copy it anyways. 489 * copy it anyways.
447 */ 490 */
448static void kauditd_send_multicast_skb(struct sk_buff *skb, gfp_t gfp_mask) 491static void kauditd_send_multicast_skb(struct sk_buff *skb)
449{ 492{
450 struct sk_buff *copy; 493 struct sk_buff *copy;
451 struct audit_net *aunet = net_generic(&init_net, audit_net_id); 494 struct audit_net *aunet = net_generic(&init_net, audit_net_id);
452 struct sock *sock = aunet->nlsk; 495 struct sock *sock = aunet->nlsk;
496 struct nlmsghdr *nlh;
453 497
454 if (!netlink_has_listeners(sock, AUDIT_NLGRP_READLOG)) 498 if (!netlink_has_listeners(sock, AUDIT_NLGRP_READLOG))
455 return; 499 return;
@@ -464,94 +508,155 @@ static void kauditd_send_multicast_skb(struct sk_buff *skb, gfp_t gfp_mask)
464 * no reason for new multicast clients to continue with this 508 * no reason for new multicast clients to continue with this
465 * non-compliance. 509 * non-compliance.
466 */ 510 */
467 copy = skb_copy(skb, gfp_mask); 511 copy = skb_copy(skb, GFP_KERNEL);
468 if (!copy) 512 if (!copy)
469 return; 513 return;
514 nlh = nlmsg_hdr(copy);
515 nlh->nlmsg_len = skb->len;
470 516
471 nlmsg_multicast(sock, copy, 0, AUDIT_NLGRP_READLOG, gfp_mask); 517 nlmsg_multicast(sock, copy, 0, AUDIT_NLGRP_READLOG, GFP_KERNEL);
472} 518}
473 519
474/* 520/**
475 * flush_hold_queue - empty the hold queue if auditd appears 521 * kauditd_wake_condition - Return true when it is time to wake kauditd_thread
476 *
477 * If auditd just started, drain the queue of messages already
478 * sent to syslog/printk. Remember loss here is ok. We already
479 * called audit_log_lost() if it didn't go out normally. so the
480 * race between the skb_dequeue and the next check for audit_pid
481 * doesn't matter.
482 * 522 *
483 * If you ever find kauditd to be too slow we can get a perf win 523 * Description:
484 * by doing our own locking and keeping better track if there 524 * This function is for use by the wait_event_freezable() call in
485 * are messages in this queue. I don't see the need now, but 525 * kauditd_thread().
486 * in 5 years when I want to play with this again I'll see this
487 * note and still have no friggin idea what i'm thinking today.
488 */ 526 */
489static void flush_hold_queue(void) 527static int kauditd_wake_condition(void)
490{ 528{
491 struct sk_buff *skb; 529 static int pid_last = 0;
492 530 int rc;
493 if (!audit_default || !audit_pid) 531 int pid = audit_pid;
494 return;
495
496 skb = skb_dequeue(&audit_hold_queue);
497 if (likely(!skb))
498 return;
499 532
500 while (skb && audit_pid) { 533 /* wake on new messages or a change in the connected auditd */
501 kauditd_send_unicast_skb(skb); 534 rc = skb_queue_len(&audit_queue) || (pid && pid != pid_last);
502 skb = skb_dequeue(&audit_hold_queue); 535 if (rc)
503 } 536 pid_last = pid;
504 537
505 /* 538 return rc;
506 * if auditd just disappeared but we
507 * dequeued an skb we need to drop ref
508 */
509 consume_skb(skb);
510} 539}
511 540
512static int kauditd_thread(void *dummy) 541static int kauditd_thread(void *dummy)
513{ 542{
543 int rc;
544 int auditd = 0;
545 int reschedule = 0;
514 struct sk_buff *skb; 546 struct sk_buff *skb;
515 struct nlmsghdr *nlh; 547 struct nlmsghdr *nlh;
516 548
549#define UNICAST_RETRIES 5
550#define AUDITD_BAD(x,y) \
551 ((x) == -ECONNREFUSED || (x) == -EPERM || ++(y) >= UNICAST_RETRIES)
552
553 /* NOTE: we do invalidate the auditd connection flag on any sending
554 * errors, but we only "restore" the connection flag at specific places
555 * in the loop in order to help ensure proper ordering of audit
556 * records */
557
517 set_freezable(); 558 set_freezable();
518 while (!kthread_should_stop()) { 559 while (!kthread_should_stop()) {
519 flush_hold_queue(); 560 /* NOTE: possible area for future improvement is to look at
561 * the hold and retry queues, since only this thread
562 * has access to these queues we might be able to do
563 * our own queuing and skip some/all of the locking */
564
565 /* NOTE: it might be a fun experiment to split the hold and
566 * retry queue handling to another thread, but the
567 * synchronization issues and other overhead might kill
568 * any performance gains */
569
570 /* attempt to flush the hold queue */
571 while (auditd && (skb = skb_dequeue(&audit_hold_queue))) {
572 rc = kauditd_send_unicast_skb(skb);
573 if (rc) {
574 /* requeue to the same spot */
575 skb_queue_head(&audit_hold_queue, skb);
576
577 auditd = 0;
578 if (AUDITD_BAD(rc, reschedule)) {
579 auditd_reset();
580 reschedule = 0;
581 }
582 } else
583 /* we were able to send successfully */
584 reschedule = 0;
585 }
586
587 /* attempt to flush the retry queue */
588 while (auditd && (skb = skb_dequeue(&audit_retry_queue))) {
589 rc = kauditd_send_unicast_skb(skb);
590 if (rc) {
591 auditd = 0;
592 if (AUDITD_BAD(rc, reschedule)) {
593 kauditd_hold_skb(skb);
594 auditd_reset();
595 reschedule = 0;
596 } else
597 /* temporary problem (we hope), queue
598 * to the same spot and retry */
599 skb_queue_head(&audit_retry_queue, skb);
600 } else
601 /* we were able to send successfully */
602 reschedule = 0;
603 }
520 604
605 /* standard queue processing, try to be as quick as possible */
606quick_loop:
521 skb = skb_dequeue(&audit_queue); 607 skb = skb_dequeue(&audit_queue);
522 if (skb) { 608 if (skb) {
609 /* setup the netlink header, see the comments in
610 * kauditd_send_multicast_skb() for length quirks */
523 nlh = nlmsg_hdr(skb); 611 nlh = nlmsg_hdr(skb);
524 612 nlh->nlmsg_len = skb->len - NLMSG_HDRLEN;
525 /* if nlh->nlmsg_len is zero then we haven't attempted 613
526 * to send the message to userspace yet, if nlmsg_len 614 /* attempt to send to any multicast listeners */
527 * is non-zero then we have attempted to send it to 615 kauditd_send_multicast_skb(skb);
528 * the multicast listeners as well as auditd; keep 616
529 * trying to send to auditd but don't repeat the 617 /* attempt to send to auditd, queue on failure */
530 * multicast send */ 618 if (auditd) {
531 if (nlh->nlmsg_len == 0) { 619 rc = kauditd_send_unicast_skb(skb);
532 nlh->nlmsg_len = skb->len; 620 if (rc) {
533 kauditd_send_multicast_skb(skb, GFP_KERNEL); 621 auditd = 0;
534 622 if (AUDITD_BAD(rc, reschedule)) {
535 /* see the note in kauditd_send_multicast_skb 623 auditd_reset();
536 * regarding the nlh->nlmsg_len value and why 624 reschedule = 0;
537 * it differs between the multicast and unicast 625 }
538 * clients */ 626
539 nlh->nlmsg_len -= NLMSG_HDRLEN; 627 /* move to the retry queue */
540 } 628 kauditd_retry_skb(skb);
541 629 } else
542 if (audit_pid) 630 /* everything is working so go fast! */
543 kauditd_send_unicast_skb(skb); 631 goto quick_loop;
632 } else if (reschedule)
633 /* we are currently having problems, move to
634 * the retry queue */
635 kauditd_retry_skb(skb);
544 else 636 else
545 kauditd_printk_skb(skb); 637 /* dump the message via printk and hold it */
638 kauditd_hold_skb(skb);
546 } else { 639 } else {
547 /* we have flushed the backlog so wake everyone up who 640 /* we have flushed the backlog so wake everyone */
548 * is blocked and go to sleep until we have something
549 * in the backlog again */
550 wake_up(&audit_backlog_wait); 641 wake_up(&audit_backlog_wait);
551 wait_event_freezable(kauditd_wait, 642
552 skb_queue_len(&audit_queue)); 643 /* if everything is okay with auditd (if present), go
644 * to sleep until there is something new in the queue
645 * or we have a change in the connected auditd;
646 * otherwise simply reschedule to give things a chance
647 * to recover */
648 if (reschedule) {
649 set_current_state(TASK_INTERRUPTIBLE);
650 schedule();
651 } else
652 wait_event_freezable(kauditd_wait,
653 kauditd_wake_condition());
654
655 /* update the auditd connection status */
656 auditd = (audit_pid ? 1 : 0);
553 } 657 }
554 } 658 }
659
555 return 0; 660 return 0;
556} 661}
557 662
@@ -616,6 +721,7 @@ static int audit_send_reply_thread(void *arg)
616 kfree(reply); 721 kfree(reply);
617 return 0; 722 return 0;
618} 723}
724
619/** 725/**
620 * audit_send_reply - send an audit reply message via netlink 726 * audit_send_reply - send an audit reply message via netlink
621 * @request_skb: skb of request we are replying to (used to target the reply) 727 * @request_skb: skb of request we are replying to (used to target the reply)
@@ -1171,10 +1277,8 @@ static void __net_exit audit_net_exit(struct net *net)
1171{ 1277{
1172 struct audit_net *aunet = net_generic(net, audit_net_id); 1278 struct audit_net *aunet = net_generic(net, audit_net_id);
1173 struct sock *sock = aunet->nlsk; 1279 struct sock *sock = aunet->nlsk;
1174 if (sock == audit_sock) { 1280 if (sock == audit_sock)
1175 audit_pid = 0; 1281 auditd_reset();
1176 audit_sock = NULL;
1177 }
1178 1282
1179 RCU_INIT_POINTER(aunet->nlsk, NULL); 1283 RCU_INIT_POINTER(aunet->nlsk, NULL);
1180 synchronize_net(); 1284 synchronize_net();
@@ -1201,6 +1305,7 @@ static int __init audit_init(void)
1201 register_pernet_subsys(&audit_net_ops); 1305 register_pernet_subsys(&audit_net_ops);
1202 1306
1203 skb_queue_head_init(&audit_queue); 1307 skb_queue_head_init(&audit_queue);
1308 skb_queue_head_init(&audit_retry_queue);
1204 skb_queue_head_init(&audit_hold_queue); 1309 skb_queue_head_init(&audit_hold_queue);
1205 audit_initialized = AUDIT_INITIALIZED; 1310 audit_initialized = AUDIT_INITIALIZED;
1206 audit_enabled = audit_default; 1311 audit_enabled = audit_default;