]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blobdiff - kernel/audit.c
Merge branch 'stable-4.10' of git://git.infradead.org/users/pcmoore/audit
[mirror_ubuntu-bionic-kernel.git] / kernel / audit.c
index 67b9fbd871be8ec0d9e557f654fe7463a29f82b5..91bff3c0b368c4ac6584c8cbad6b5b40e9a338ed 100644 (file)
@@ -107,7 +107,6 @@ static u32  audit_rate_limit;
  * When set to zero, this means unlimited. */
 static u32     audit_backlog_limit = 64;
 #define AUDIT_BACKLOG_WAIT_TIME (60 * HZ)
-static u32     audit_backlog_wait_time_master = AUDIT_BACKLOG_WAIT_TIME;
 static u32     audit_backlog_wait_time = AUDIT_BACKLOG_WAIT_TIME;
 
 /* The identity of the user shutting down the audit system. */
@@ -138,11 +137,18 @@ static DEFINE_SPINLOCK(audit_freelist_lock);
 static int        audit_freelist_count;
 static LIST_HEAD(audit_freelist);
 
-static struct sk_buff_head audit_skb_queue;
-/* queue of skbs to send to auditd when/if it comes back */
-static struct sk_buff_head audit_skb_hold_queue;
+/* queue msgs to send via kauditd_task */
+static struct sk_buff_head audit_queue;
+/* queue msgs due to temporary unicast send problems */
+static struct sk_buff_head audit_retry_queue;
+/* queue msgs waiting for new auditd connection */
+static struct sk_buff_head audit_hold_queue;
+
+/* queue servicing thread */
 static struct task_struct *kauditd_task;
 static DECLARE_WAIT_QUEUE_HEAD(kauditd_wait);
+
+/* waitqueue for callers who are blocked on the audit backlog */
 static DECLARE_WAIT_QUEUE_HEAD(audit_backlog_wait);
 
 static struct audit_features af = {.vers = AUDIT_FEATURE_VERSION,
@@ -338,7 +344,7 @@ static int audit_set_backlog_limit(u32 limit)
 static int audit_set_backlog_wait_time(u32 timeout)
 {
        return audit_do_config_change("audit_backlog_wait_time",
-                                     &audit_backlog_wait_time_master, timeout);
+                                     &audit_backlog_wait_time, timeout);
 }
 
 static int audit_set_enabled(u32 state)
@@ -364,30 +370,11 @@ static int audit_set_failure(u32 state)
        return audit_do_config_change("audit_failure", &audit_failure, state);
 }
 
-/*
- * Queue skbs to be sent to auditd when/if it comes back.  These skbs should
- * already have been sent via prink/syslog and so if these messages are dropped
- * it is not a huge concern since we already passed the audit_log_lost()
- * notification and stuff.  This is just nice to get audit messages during
- * boot before auditd is running or messages generated while auditd is stopped.
- * This only holds messages is audit_default is set, aka booting with audit=1
- * or building your kernel that way.
- */
-static void audit_hold_skb(struct sk_buff *skb)
-{
-       if (audit_default &&
-           (!audit_backlog_limit ||
-            skb_queue_len(&audit_skb_hold_queue) < audit_backlog_limit))
-               skb_queue_tail(&audit_skb_hold_queue, skb);
-       else
-               kfree_skb(skb);
-}
-
 /*
  * For one reason or another this nlh isn't getting delivered to the userspace
  * audit daemon, just send it to printk.
  */
-static void audit_printk_skb(struct sk_buff *skb)
+static void kauditd_printk_skb(struct sk_buff *skb)
 {
        struct nlmsghdr *nlh = nlmsg_hdr(skb);
        char *data = nlmsg_data(nlh);
@@ -398,58 +385,123 @@ static void audit_printk_skb(struct sk_buff *skb)
                else
                        audit_log_lost("printk limit exceeded");
        }
+}
+
+/**
+ * kauditd_hold_skb - Queue an audit record, waiting for auditd
+ * @skb: audit record
+ *
+ * Description:
+ * Queue the audit record, waiting for an instance of auditd.  When this
+ * function is called we haven't given up yet on sending the record, but things
+ * are not looking good.  The first thing we want to do is try to write the
+ * record via printk and then see if we want to try and hold on to the record
+ * and queue it, if we have room.  If we want to hold on to the record, but we
+ * don't have room, record a record lost message.
+ */
+static void kauditd_hold_skb(struct sk_buff *skb)
+{
+       /* at this point it is uncertain if we will ever send this to auditd so
+        * try to send the message via printk before we go any further */
+       kauditd_printk_skb(skb);
+
+       /* can we just silently drop the message? */
+       if (!audit_default) {
+               kfree_skb(skb);
+               return;
+       }
+
+       /* if we have room, queue the message */
+       if (!audit_backlog_limit ||
+           skb_queue_len(&audit_hold_queue) < audit_backlog_limit) {
+               skb_queue_tail(&audit_hold_queue, skb);
+               return;
+       }
 
-       audit_hold_skb(skb);
+       /* we have no other options - drop the message */
+       audit_log_lost("kauditd hold queue overflow");
+       kfree_skb(skb);
 }
 
-static void kauditd_send_skb(struct sk_buff *skb)
+/**
+ * kauditd_retry_skb - Queue an audit record, attempt to send again to auditd
+ * @skb: audit record
+ *
+ * Description:
+ * Not as serious as kauditd_hold_skb() as we still have a connected auditd,
+ * but for some reason we are having problems sending it audit records so
+ * queue the given record and attempt to resend.
+ */
+static void kauditd_retry_skb(struct sk_buff *skb)
 {
-       int err;
-       int attempts = 0;
-#define AUDITD_RETRIES 5
+       /* NOTE: because records should only live in the retry queue for a
+        * short period of time, before either being sent or moved to the hold
+        * queue, we don't currently enforce a limit on this queue */
+       skb_queue_tail(&audit_retry_queue, skb);
+}
+
+/**
+ * auditd_reset - Disconnect the auditd connection
+ *
+ * Description:
+ * Break the auditd/kauditd connection and move all the records in the retry
+ * queue into the hold queue in case auditd reconnects.  The audit_cmd_mutex
+ * must be held when calling this function.
+ */
+static void auditd_reset(void)
+{
+       struct sk_buff *skb;
+
+       /* break the connection */
+       if (audit_sock) {
+               sock_put(audit_sock);
+               audit_sock = NULL;
+       }
+       audit_pid = 0;
+       audit_nlk_portid = 0;
+
+       /* flush all of the retry queue to the hold queue */
+       while ((skb = skb_dequeue(&audit_retry_queue)))
+               kauditd_hold_skb(skb);
+}
+
+/**
+ * kauditd_send_unicast_skb - Send a record via unicast to auditd
+ * @skb: audit record
+ */
+static int kauditd_send_unicast_skb(struct sk_buff *skb)
+{
+       int rc;
 
-restart:
-       /* take a reference in case we can't send it and we want to hold it */
+       /* if we know nothing is connected, don't even try the netlink call */
+       if (!audit_pid)
+               return -ECONNREFUSED;
+
+       /* get an extra skb reference in case we fail to send */
        skb_get(skb);
-       err = netlink_unicast(audit_sock, skb, audit_nlk_portid, 0);
-       if (err < 0) {
-               pr_err("netlink_unicast sending to audit_pid=%d returned error: %d\n",
-                      audit_pid, err);
-               if (audit_pid) {
-                       if (err == -ECONNREFUSED || err == -EPERM
-                           || ++attempts >= AUDITD_RETRIES) {
-                               char s[32];
-
-                               snprintf(s, sizeof(s), "audit_pid=%d reset", audit_pid);
-                               audit_log_lost(s);
-                               audit_pid = 0;
-                               audit_sock = NULL;
-                       } else {
-                               pr_warn("re-scheduling(#%d) write to audit_pid=%d\n",
-                                       attempts, audit_pid);
-                               set_current_state(TASK_INTERRUPTIBLE);
-                               schedule();
-                               goto restart;
-                       }
-               }
-               /* we might get lucky and get this in the next auditd */
-               audit_hold_skb(skb);
-       } else
-               /* drop the extra reference if sent ok */
+       rc = netlink_unicast(audit_sock, skb, audit_nlk_portid, 0);
+       if (rc >= 0) {
                consume_skb(skb);
+               rc = 0;
+       }
+
+       return rc;
 }
 
 /*
- * kauditd_send_multicast_skb - send the skb to multicast userspace listeners
+ * kauditd_send_multicast_skb - Send a record to any multicast listeners
+ * @skb: audit record
  *
+ * Description:
  * This function doesn't consume an skb as might be expected since it has to
  * copy it anyways.
  */
-static void kauditd_send_multicast_skb(struct sk_buff *skb, gfp_t gfp_mask)
+static void kauditd_send_multicast_skb(struct sk_buff *skb)
 {
-       struct sk_buff          *copy;
-       struct audit_net        *aunet = net_generic(&init_net, audit_net_id);
-       struct sock             *sock = aunet->nlsk;
+       struct sk_buff *copy;
+       struct audit_net *aunet = net_generic(&init_net, audit_net_id);
+       struct sock *sock = aunet->nlsk;
+       struct nlmsghdr *nlh;
 
        if (!netlink_has_listeners(sock, AUDIT_NLGRP_READLOG))
                return;
@@ -464,74 +516,161 @@ static void kauditd_send_multicast_skb(struct sk_buff *skb, gfp_t gfp_mask)
         * no reason for new multicast clients to continue with this
         * non-compliance.
         */
-       copy = skb_copy(skb, gfp_mask);
+       copy = skb_copy(skb, GFP_KERNEL);
        if (!copy)
                return;
+       nlh = nlmsg_hdr(copy);
+       nlh->nlmsg_len = skb->len;
 
-       nlmsg_multicast(sock, copy, 0, AUDIT_NLGRP_READLOG, gfp_mask);
+       nlmsg_multicast(sock, copy, 0, AUDIT_NLGRP_READLOG, GFP_KERNEL);
 }
 
-/*
- * flush_hold_queue - empty the hold queue if auditd appears
- *
- * If auditd just started, drain the queue of messages already
- * sent to syslog/printk.  Remember loss here is ok.  We already
- * called audit_log_lost() if it didn't go out normally.  so the
- * race between the skb_dequeue and the next check for audit_pid
- * doesn't matter.
+/**
+ * kauditd_wake_condition - Return true when it is time to wake kauditd_thread
  *
- * If you ever find kauditd to be too slow we can get a perf win
- * by doing our own locking and keeping better track if there
- * are messages in this queue.  I don't see the need now, but
- * in 5 years when I want to play with this again I'll see this
- * note and still have no friggin idea what i'm thinking today.
+ * Description:
+ * This function is for use by the wait_event_freezable() call in
+ * kauditd_thread().
  */
-static void flush_hold_queue(void)
+static int kauditd_wake_condition(void)
 {
-       struct sk_buff *skb;
-
-       if (!audit_default || !audit_pid)
-               return;
-
-       skb = skb_dequeue(&audit_skb_hold_queue);
-       if (likely(!skb))
-               return;
+       static int pid_last = 0;
+       int rc;
+       int pid = audit_pid;
 
-       while (skb && audit_pid) {
-               kauditd_send_skb(skb);
-               skb = skb_dequeue(&audit_skb_hold_queue);
-       }
+       /* wake on new messages or a change in the connected auditd */
+       rc = skb_queue_len(&audit_queue) || (pid && pid != pid_last);
+       if (rc)
+               pid_last = pid;
 
-       /*
-        * if auditd just disappeared but we
-        * dequeued an skb we need to drop ref
-        */
-       consume_skb(skb);
+       return rc;
 }
 
 static int kauditd_thread(void *dummy)
 {
+       int rc;
+       int auditd = 0;
+       int reschedule = 0;
+       struct sk_buff *skb;
+       struct nlmsghdr *nlh;
+
+#define UNICAST_RETRIES 5
+#define AUDITD_BAD(x,y) \
+       ((x) == -ECONNREFUSED || (x) == -EPERM || ++(y) >= UNICAST_RETRIES)
+
+       /* NOTE: we do invalidate the auditd connection flag on any sending
+        * errors, but we only "restore" the connection flag at specific places
+        * in the loop in order to help ensure proper ordering of audit
+        * records */
+
        set_freezable();
        while (!kthread_should_stop()) {
-               struct sk_buff *skb;
-
-               flush_hold_queue();
+               /* NOTE: possible area for future improvement is to look at
+                *       the hold and retry queues, since only this thread
+                *       has access to these queues we might be able to do
+                *       our own queuing and skip some/all of the locking */
+
+               /* NOTE: it might be a fun experiment to split the hold and
+                *       retry queue handling to another thread, but the
+                *       synchronization issues and other overhead might kill
+                *       any performance gains */
+
+               /* attempt to flush the hold queue */
+               while (auditd && (skb = skb_dequeue(&audit_hold_queue))) {
+                       rc = kauditd_send_unicast_skb(skb);
+                       if (rc) {
+                               /* requeue to the same spot */
+                               skb_queue_head(&audit_hold_queue, skb);
+
+                               auditd = 0;
+                               if (AUDITD_BAD(rc, reschedule)) {
+                                       mutex_lock(&audit_cmd_mutex);
+                                       auditd_reset();
+                                       mutex_unlock(&audit_cmd_mutex);
+                                       reschedule = 0;
+                               }
+                       } else
+                               /* we were able to send successfully */
+                               reschedule = 0;
+               }
 
-               skb = skb_dequeue(&audit_skb_queue);
+               /* attempt to flush the retry queue */
+               while (auditd && (skb = skb_dequeue(&audit_retry_queue))) {
+                       rc = kauditd_send_unicast_skb(skb);
+                       if (rc) {
+                               auditd = 0;
+                               if (AUDITD_BAD(rc, reschedule)) {
+                                       kauditd_hold_skb(skb);
+                                       mutex_lock(&audit_cmd_mutex);
+                                       auditd_reset();
+                                       mutex_unlock(&audit_cmd_mutex);
+                                       reschedule = 0;
+                               } else
+                                       /* temporary problem (we hope), queue
+                                        * to the same spot and retry */
+                                       skb_queue_head(&audit_retry_queue, skb);
+                       } else
+                               /* we were able to send successfully */
+                               reschedule = 0;
+               }
 
+               /* standard queue processing, try to be as quick as possible */
+quick_loop:
+               skb = skb_dequeue(&audit_queue);
                if (skb) {
-                       if (!audit_backlog_limit ||
-                           (skb_queue_len(&audit_skb_queue) <= audit_backlog_limit))
-                               wake_up(&audit_backlog_wait);
-                       if (audit_pid)
-                               kauditd_send_skb(skb);
+                       /* setup the netlink header, see the comments in
+                        * kauditd_send_multicast_skb() for length quirks */
+                       nlh = nlmsg_hdr(skb);
+                       nlh->nlmsg_len = skb->len - NLMSG_HDRLEN;
+
+                       /* attempt to send to any multicast listeners */
+                       kauditd_send_multicast_skb(skb);
+
+                       /* attempt to send to auditd, queue on failure */
+                       if (auditd) {
+                               rc = kauditd_send_unicast_skb(skb);
+                               if (rc) {
+                                       auditd = 0;
+                                       if (AUDITD_BAD(rc, reschedule)) {
+                                               mutex_lock(&audit_cmd_mutex);
+                                               auditd_reset();
+                                               mutex_unlock(&audit_cmd_mutex);
+                                               reschedule = 0;
+                                       }
+
+                                       /* move to the retry queue */
+                                       kauditd_retry_skb(skb);
+                               } else
+                                       /* everything is working so go fast! */
+                                       goto quick_loop;
+                       } else if (reschedule)
+                               /* we are currently having problems, move to
+                                * the retry queue */
+                               kauditd_retry_skb(skb);
                        else
-                               audit_printk_skb(skb);
-                       continue;
-               }
+                               /* dump the message via printk and hold it */
+                               kauditd_hold_skb(skb);
+               } else {
+                       /* we have flushed the backlog so wake everyone */
+                       wake_up(&audit_backlog_wait);
+
+                       /* if everything is okay with auditd (if present), go
+                        * to sleep until there is something new in the queue
+                        * or we have a change in the connected auditd;
+                        * otherwise simply reschedule to give things a chance
+                        * to recover */
+                       if (reschedule) {
+                               set_current_state(TASK_INTERRUPTIBLE);
+                               schedule();
+                       } else
+                               wait_event_freezable(kauditd_wait,
+                                                    kauditd_wake_condition());
 
-               wait_event_freezable(kauditd_wait, skb_queue_len(&audit_skb_queue));
+                       /* update the auditd connection status */
+                       auditd = (audit_pid ? 1 : 0);
+               }
        }
+
        return 0;
 }
 
@@ -596,6 +735,7 @@ static int audit_send_reply_thread(void *arg)
        kfree(reply);
        return 0;
 }
+
 /**
  * audit_send_reply - send an audit reply message via netlink
  * @request_skb: skb of request we are replying to (used to target the reply)
@@ -832,16 +972,6 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
        if (err)
                return err;
 
-       /* As soon as there's any sign of userspace auditd,
-        * start kauditd to talk to it */
-       if (!kauditd_task) {
-               kauditd_task = kthread_run(kauditd_thread, NULL, "kauditd");
-               if (IS_ERR(kauditd_task)) {
-                       err = PTR_ERR(kauditd_task);
-                       kauditd_task = NULL;
-                       return err;
-               }
-       }
        seq  = nlh->nlmsg_seq;
        data = nlmsg_data(nlh);
 
@@ -855,9 +985,9 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
                s.rate_limit            = audit_rate_limit;
                s.backlog_limit         = audit_backlog_limit;
                s.lost                  = atomic_read(&audit_lost);
-               s.backlog               = skb_queue_len(&audit_skb_queue);
+               s.backlog               = skb_queue_len(&audit_queue);
                s.feature_bitmap        = AUDIT_FEATURE_BITMAP_ALL;
-               s.backlog_wait_time     = audit_backlog_wait_time_master;
+               s.backlog_wait_time     = audit_backlog_wait_time;
                audit_send_reply(skb, seq, AUDIT_GET, 0, 0, &s, sizeof(s));
                break;
        }
@@ -897,9 +1027,17 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
                        }
                        if (audit_enabled != AUDIT_OFF)
                                audit_log_config_change("audit_pid", new_pid, audit_pid, 1);
-                       audit_pid = new_pid;
-                       audit_nlk_portid = NETLINK_CB(skb).portid;
-                       audit_sock = skb->sk;
+                       if (new_pid) {
+                               if (audit_sock)
+                                       sock_put(audit_sock);
+                               audit_pid = new_pid;
+                               audit_nlk_portid = NETLINK_CB(skb).portid;
+                               sock_hold(skb->sk);
+                               audit_sock = skb->sk;
+                       } else {
+                               auditd_reset();
+                       }
+                       wake_up_interruptible(&kauditd_wait);
                }
                if (s.mask & AUDIT_STATUS_RATE_LIMIT) {
                        err = audit_set_rate_limit(s.rate_limit);
@@ -1167,10 +1305,10 @@ static void __net_exit audit_net_exit(struct net *net)
 {
        struct audit_net *aunet = net_generic(net, audit_net_id);
        struct sock *sock = aunet->nlsk;
-       if (sock == audit_sock) {
-               audit_pid = 0;
-               audit_sock = NULL;
-       }
+       mutex_lock(&audit_cmd_mutex);
+       if (sock == audit_sock)
+               auditd_reset();
+       mutex_unlock(&audit_cmd_mutex);
 
        netlink_kernel_release(sock);
        aunet->nlsk = NULL;
@@ -1195,17 +1333,24 @@ static int __init audit_init(void)
                audit_default ? "enabled" : "disabled");
        register_pernet_subsys(&audit_net_ops);
 
-       skb_queue_head_init(&audit_skb_queue);
-       skb_queue_head_init(&audit_skb_hold_queue);
+       skb_queue_head_init(&audit_queue);
+       skb_queue_head_init(&audit_retry_queue);
+       skb_queue_head_init(&audit_hold_queue);
        audit_initialized = AUDIT_INITIALIZED;
        audit_enabled = audit_default;
        audit_ever_enabled |= !!audit_default;
 
-       audit_log(NULL, GFP_KERNEL, AUDIT_KERNEL, "initialized");
-
        for (i = 0; i < AUDIT_INODE_BUCKETS; i++)
                INIT_LIST_HEAD(&audit_inode_hash[i]);
 
+       kauditd_task = kthread_run(kauditd_thread, NULL, "kauditd");
+       if (IS_ERR(kauditd_task)) {
+               int err = PTR_ERR(kauditd_task);
+               panic("audit: failed to start the kauditd thread (%d)\n", err);
+       }
+
+       audit_log(NULL, GFP_KERNEL, AUDIT_KERNEL, "initialized");
+
        return 0;
 }
 __initcall(audit_init);
@@ -1338,24 +1483,6 @@ static inline void audit_get_stamp(struct audit_context *ctx,
        }
 }
 
-/*
- * Wait for auditd to drain the queue a little
- */
-static long wait_for_auditd(long sleep_time)
-{
-       DECLARE_WAITQUEUE(wait, current);
-
-       if (audit_backlog_limit &&
-           skb_queue_len(&audit_skb_queue) > audit_backlog_limit) {
-               add_wait_queue_exclusive(&audit_backlog_wait, &wait);
-               set_current_state(TASK_UNINTERRUPTIBLE);
-               sleep_time = schedule_timeout(sleep_time);
-               remove_wait_queue(&audit_backlog_wait, &wait);
-       }
-
-       return sleep_time;
-}
-
 /**
  * audit_log_start - obtain an audit buffer
  * @ctx: audit_context (may be NULL)
@@ -1374,12 +1501,9 @@ static long wait_for_auditd(long sleep_time)
 struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask,
                                     int type)
 {
-       struct audit_buffer     *ab     = NULL;
-       struct timespec         t;
-       unsigned int            uninitialized_var(serial);
-       int reserve = 5; /* Allow atomic callers to go up to five
-                           entries over the normal backlog limit */
-       unsigned long timeout_start = jiffies;
+       struct audit_buffer *ab;
+       struct timespec t;
+       unsigned int uninitialized_var(serial);
 
        if (audit_initialized != AUDIT_INITIALIZED)
                return NULL;
@@ -1387,38 +1511,48 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask,
        if (unlikely(!audit_filter(type, AUDIT_FILTER_TYPE)))
                return NULL;
 
-       if (gfp_mask & __GFP_DIRECT_RECLAIM) {
-               if (audit_pid && audit_pid == current->tgid)
-                       gfp_mask &= ~__GFP_DIRECT_RECLAIM;
-               else
-                       reserve = 0;
-       }
-
-       while (audit_backlog_limit
-              && skb_queue_len(&audit_skb_queue) > audit_backlog_limit + reserve) {
-               if (gfp_mask & __GFP_DIRECT_RECLAIM && audit_backlog_wait_time) {
-                       long sleep_time;
+       /* don't ever fail/sleep on these two conditions:
+        * 1. auditd generated record - since we need auditd to drain the
+        *    queue; also, when we are checking for auditd, compare PIDs using
+        *    task_tgid_vnr() since auditd_pid is set in audit_receive_msg()
+        *    using a PID anchored in the caller's namespace
+        * 2. audit command message - record types 1000 through 1099 inclusive
+        *    are command messages/records used to manage the kernel subsystem
+        *    and the audit userspace, blocking on these messages could cause
+        *    problems under load so don't do it (note: not all of these
+        *    command types are valid as record types, but it is quicker to
+        *    just check two ints than a series of ints in a if/switch stmt) */
+       if (!((audit_pid && audit_pid == task_tgid_vnr(current)) ||
+             (type >= 1000 && type <= 1099))) {
+               long sleep_time = audit_backlog_wait_time;
+
+               while (audit_backlog_limit &&
+                      (skb_queue_len(&audit_queue) > audit_backlog_limit)) {
+                       /* wake kauditd to try and flush the queue */
+                       wake_up_interruptible(&kauditd_wait);
 
-                       sleep_time = timeout_start + audit_backlog_wait_time - jiffies;
-                       if (sleep_time > 0) {
-                               sleep_time = wait_for_auditd(sleep_time);
-                               if (sleep_time > 0)
-                                       continue;
+                       /* sleep if we are allowed and we haven't exhausted our
+                        * backlog wait limit */
+                       if ((gfp_mask & __GFP_DIRECT_RECLAIM) &&
+                           (sleep_time > 0)) {
+                               DECLARE_WAITQUEUE(wait, current);
+
+                               add_wait_queue_exclusive(&audit_backlog_wait,
+                                                        &wait);
+                               set_current_state(TASK_UNINTERRUPTIBLE);
+                               sleep_time = schedule_timeout(sleep_time);
+                               remove_wait_queue(&audit_backlog_wait, &wait);
+                       } else {
+                               if (audit_rate_check() && printk_ratelimit())
+                                       pr_warn("audit_backlog=%d > audit_backlog_limit=%d\n",
+                                               skb_queue_len(&audit_queue),
+                                               audit_backlog_limit);
+                               audit_log_lost("backlog limit exceeded");
+                               return NULL;
                        }
                }
-               if (audit_rate_check() && printk_ratelimit())
-                       pr_warn("audit_backlog=%d > audit_backlog_limit=%d\n",
-                               skb_queue_len(&audit_skb_queue),
-                               audit_backlog_limit);
-               audit_log_lost("backlog limit exceeded");
-               audit_backlog_wait_time = 0;
-               wake_up(&audit_backlog_wait);
-               return NULL;
        }
 
-       if (!reserve && !audit_backlog_wait_time)
-               audit_backlog_wait_time = audit_backlog_wait_time_master;
-
        ab = audit_buffer_alloc(ctx, gfp_mask, type);
        if (!ab) {
                audit_log_lost("out of memory in audit_log_start");
@@ -1426,9 +1560,9 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask,
        }
 
        audit_get_stamp(ab->ctx, &t, &serial);
-
        audit_log_format(ab, "audit(%lu.%03lu:%u): ",
                         t.tv_sec, t.tv_nsec/1000000, serial);
+
        return ab;
 }
 
@@ -1978,10 +2112,10 @@ out:
  * audit_log_end - end one audit record
  * @ab: the audit_buffer
  *
- * netlink_unicast() cannot be called inside an irq context because it blocks
- * (last arg, flags, is not set to MSG_DONTWAIT), so the audit buffer is placed
- * on a queue and a tasklet is scheduled to remove them from the queue outside
- * the irq context.  May be called in any context.
+ * We can not do a netlink send inside an irq context because it blocks (last
+ * arg, flags, is not set to MSG_DONTWAIT), so the audit buffer is placed on a
+ * queue and a tasklet is scheduled to remove them from the queue outside the
+ * irq context.  May be called in any context.
  */
 void audit_log_end(struct audit_buffer *ab)
 {
@@ -1990,28 +2124,8 @@ void audit_log_end(struct audit_buffer *ab)
        if (!audit_rate_check()) {
                audit_log_lost("rate limit exceeded");
        } else {
-               struct nlmsghdr *nlh = nlmsg_hdr(ab->skb);
-
-               nlh->nlmsg_len = ab->skb->len;
-               kauditd_send_multicast_skb(ab->skb, ab->gfp_mask);
-
-               /*
-                * The original kaudit unicast socket sends up messages with
-                * nlmsg_len set to the payload length rather than the entire
-                * message length.  This breaks the standard set by netlink.
-                * The existing auditd daemon assumes this breakage.  Fixing
-                * this would require co-ordinating a change in the established
-                * protocol between the kaudit kernel subsystem and the auditd
-                * userspace code.
-                */
-               nlh->nlmsg_len -= NLMSG_HDRLEN;
-
-               if (audit_pid) {
-                       skb_queue_tail(&audit_skb_queue, ab->skb);
-                       wake_up_interruptible(&kauditd_wait);
-               } else {
-                       audit_printk_skb(ab->skb);
-               }
+               skb_queue_tail(&audit_queue, ab->skb);
+               wake_up_interruptible(&kauditd_wait);
                ab->skb = NULL;
        }
        audit_buffer_free(ab);