Commit f3d357b092956959563398b59ef2fdd10aea387d

Authored by Eric Paris
Committed by Al Viro
1 parent 2532386f48

Audit: save audit_backlog_limit audit messages in case auditd comes back

This patch causes the kernel audit subsystem to store up to
audit_backlog_limit messages for use by auditd if it ever appears
sometime in the future in userspace.  This is useful to collect audit
messages during bootup and even when auditd is stopped.  This is NOT a
reliable mechanism, it does not ever call audit_panic, nor should it.
audit_log_lost()/audit_panic() are called during the normal delivery
mechanism.  The messages are still sent to printk/syslog as usual and if
too many messages appear to be queued they will be silently discarded.

I liked doing it by default, but this patch only uses the queue in
question if it was booted with audit=1 or if the kernel was built
enabling audit by default.

Signed-off-by: Eric Paris <eparis@redhat.com>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

Showing 1 changed file with 81 additions and 21 deletions Side-by-side Diff

... ... @@ -126,6 +126,8 @@
126 126 static LIST_HEAD(audit_freelist);
127 127  
128 128 static struct sk_buff_head audit_skb_queue;
  129 +/* queue of skbs to send to auditd when/if it comes back */
  130 +static struct sk_buff_head audit_skb_hold_queue;
129 131 static struct task_struct *kauditd_task;
130 132 static DECLARE_WAIT_QUEUE_HEAD(kauditd_wait);
131 133 static DECLARE_WAIT_QUEUE_HEAD(audit_backlog_wait);
132 134  
133 135  
134 136  
135 137  
... ... @@ -347,30 +349,83 @@
347 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 + */
  361 +static 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 +
  370 +static 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 +
350 388 static int kauditd_thread(void *dummy)
351 389 {
352 390 struct sk_buff *skb;
353 391  
354 392 set_freezable();
355 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 417 skb = skb_dequeue(&audit_skb_queue);
357 418 wake_up(&audit_backlog_wait);
358 419 if (skb) {
359   - if (audit_pid) {
360   - int err = netlink_unicast(audit_sock, skb, audit_nlk_pid, 0);
361   - if (err < 0) {
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 {
  420 + if (audit_pid)
  421 + kauditd_send_skb(skb);
  422 + else {
368 423 if (printk_ratelimit())
369   - printk(KERN_NOTICE "%s\n", skb->data +
370   - NLMSG_SPACE(0));
  424 + printk(KERN_NOTICE "%s\n", skb->data + NLMSG_SPACE(0));
371 425 else
372 426 audit_log_lost("printk limit exceeded\n");
373   - kfree_skb(skb);
  427 +
  428 + audit_hold_skb(skb);
374 429 }
375 430 } else {
376 431 DECLARE_WAITQUEUE(wait, current);
... ... @@ -885,6 +940,7 @@
885 940 audit_sock->sk_sndtimeo = MAX_SCHEDULE_TIMEOUT;
886 941  
887 942 skb_queue_head_init(&audit_skb_queue);
  943 + skb_queue_head_init(&audit_skb_hold_queue);
888 944 audit_initialized = 1;
889 945 audit_enabled = audit_default;
890 946 audit_ever_enabled |= !!audit_default;
891 947  
892 948  
893 949  
894 950  
... ... @@ -1363,19 +1419,23 @@
1363 1419 audit_log_lost("rate limit exceeded");
1364 1420 } else {
1365 1421 struct nlmsghdr *nlh = nlmsg_hdr(ab->skb);
  1422 + nlh->nlmsg_len = ab->skb->len - NLMSG_SPACE(0);
  1423 +
1366 1424 if (audit_pid) {
1367   - nlh->nlmsg_len = ab->skb->len - NLMSG_SPACE(0);
1368 1425 skb_queue_tail(&audit_skb_queue, ab->skb);
1369   - ab->skb = NULL;
1370 1426 wake_up_interruptible(&kauditd_wait);
1371   - } else if (nlh->nlmsg_type != AUDIT_EOE) {
1372   - if (printk_ratelimit()) {
1373   - printk(KERN_NOTICE "type=%d %s\n",
1374   - nlh->nlmsg_type,
1375   - ab->skb->data + NLMSG_SPACE(0));
1376   - } else
1377   - audit_log_lost("printk limit exceeded\n");
  1427 + } else {
  1428 + if (nlh->nlmsg_type != AUDIT_EOE) {
  1429 + if (printk_ratelimit()) {
  1430 + printk(KERN_NOTICE "type=%d %s\n",
  1431 + nlh->nlmsg_type,
  1432 + ab->skb->data + NLMSG_SPACE(0));
  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 1440 audit_buffer_free(ab);
1381 1441 }