]> exis.tech > repos - linux.git/blobdiff - kernel/audit.c
Merge tag 'hwmon-for-v7.2-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/groec...
[linux.git] / kernel / audit.c
index dcc657d35776d8462760d1cd29e4ed679ae7839a..562476937fa793def6c7b3e8893a46dc8966a81e 100644 (file)
@@ -62,6 +62,7 @@
 #include <net/ip.h>
 #include <net/ipv6.h>
 #include <linux/sctp.h>
+#include <linux/overflow.h>
 
 #include "audit.h"
 
@@ -950,7 +951,7 @@ main_queue:
                 *       do the multicast send and rotate records from the
                 *       main queue to the retry/hold queues */
                wait_event_freezable(kauditd_wait,
-                                    (skb_queue_len(&audit_queue) ? 1 : 0));
+                               (skb_queue_len_lockless(&audit_queue) ? 1 : 0));
        }
 
        return 0;
@@ -1283,7 +1284,7 @@ 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_queue);
+               s.backlog                  = skb_queue_len_lockless(&audit_queue);
                s.feature_bitmap           = AUDIT_FEATURE_BITMAP_ALL;
                s.backlog_wait_time        = audit_backlog_wait_time;
                s.backlog_wait_time_actual = atomic_read(&audit_backlog_wait_time_actual);
@@ -1627,7 +1628,7 @@ static void audit_receive(struct sk_buff *skb)
 
        /* can't block with the ctrl lock, so penalize the sender now */
        if (audit_backlog_limit &&
-           (skb_queue_len(&audit_queue) > audit_backlog_limit)) {
+           (skb_queue_len_lockless(&audit_queue) > audit_backlog_limit)) {
                DECLARE_WAITQUEUE(wait, current);
 
                /* wake kauditd to try and flush the queue */
@@ -1933,7 +1934,7 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask,
                long stime = audit_backlog_wait_time;
 
                while (audit_backlog_limit &&
-                      (skb_queue_len(&audit_queue) > audit_backlog_limit)) {
+                       (skb_queue_len_lockless(&audit_queue) > audit_backlog_limit)) {
                        /* wake kauditd to try and flush the queue */
                        wake_up_interruptible(&kauditd_wait);
 
@@ -1953,7 +1954,7 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask,
                        } else {
                                if (audit_rate_check() && printk_ratelimit())
                                        pr_warn("audit_backlog=%d > audit_backlog_limit=%d\n",
-                                               skb_queue_len(&audit_queue),
+                                               skb_queue_len_lockless(&audit_queue),
                                                audit_backlog_limit);
                                audit_log_lost("backlog limit exceeded");
                                return NULL;
@@ -2080,7 +2081,8 @@ void audit_log_format(struct audit_buffer *ab, const char *fmt, ...)
 void audit_log_n_hex(struct audit_buffer *ab, const unsigned char *buf,
                size_t len)
 {
-       int i, avail, new_len;
+       int avail;
+       size_t i, new_len;
        unsigned char *ptr;
        struct sk_buff *skb;
 
@@ -2090,7 +2092,12 @@ void audit_log_n_hex(struct audit_buffer *ab, const unsigned char *buf,
        BUG_ON(!ab->skb);
        skb = ab->skb;
        avail = skb_tailroom(skb);
-       new_len = len<<1;
+
+       if (check_shl_overflow(len, 1, &new_len)) {
+               audit_log_format(ab, "?");
+               return;
+       }
+
        if (new_len >= avail) {
                /* Round the buffer request up to the next multiple */
                new_len = AUDIT_BUFSIZ*(((new_len-avail)/AUDIT_BUFSIZ) + 1);