diff options
| -rw-r--r-- | kernel/audit.c | 347 |
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); | |||
| 138 | static int audit_freelist_count; | 138 | static int audit_freelist_count; |
| 139 | static LIST_HEAD(audit_freelist); | 139 | static LIST_HEAD(audit_freelist); |
| 140 | 140 | ||
| 141 | /* queue msgs to send via kauditd_task */ | ||
| 141 | static struct sk_buff_head audit_queue; | 142 | static 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 */ |
| 144 | static struct sk_buff_head audit_retry_queue; | ||
| 145 | /* queue msgs waiting for new auditd connection */ | ||
| 143 | static struct sk_buff_head audit_hold_queue; | 146 | static struct sk_buff_head audit_hold_queue; |
| 147 | |||
| 148 | /* queue servicing thread */ | ||
| 144 | static struct task_struct *kauditd_task; | 149 | static struct task_struct *kauditd_task; |
| 145 | static DECLARE_WAIT_QUEUE_HEAD(kauditd_wait); | 150 | static DECLARE_WAIT_QUEUE_HEAD(kauditd_wait); |
| 151 | |||
| 152 | /* waitqueue for callers who are blocked on the audit backlog */ | ||
| 146 | static DECLARE_WAIT_QUEUE_HEAD(audit_backlog_wait); | 153 | static DECLARE_WAIT_QUEUE_HEAD(audit_backlog_wait); |
| 147 | 154 | ||
| 148 | static struct audit_features af = {.vers = AUDIT_FEATURE_VERSION, | 155 | static 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 | */ | ||
| 376 | static 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 | */ | ||
| 403 | static 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 | ||
| 405 | static 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 | */ | ||
| 436 | static 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 | */ | ||
| 451 | static 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 | */ | ||
| 468 | static int kauditd_send_unicast_skb(struct sk_buff *skb) | ||
| 469 | { | ||
| 470 | int rc; | ||
| 410 | 471 | ||
| 411 | restart: | 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 | */ |
| 448 | static void kauditd_send_multicast_skb(struct sk_buff *skb, gfp_t gfp_mask) | 491 | static 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 | */ |
| 489 | static void flush_hold_queue(void) | 527 | static 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 | ||
| 512 | static int kauditd_thread(void *dummy) | 541 | static 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 */ | ||
| 606 | quick_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; |
