]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
fixes for 4.4
authorSasha Levin <sashal@kernel.org>
Tue, 3 Mar 2020 21:02:40 +0000 (16:02 -0500)
committerSasha Levin <sashal@kernel.org>
Tue, 3 Mar 2020 21:04:24 +0000 (16:04 -0500)
Signed-off-by: Sasha Levin <sashal@kernel.org>
queue-4.4/audit-always-check-the-netlink-payload-length-in-aud.patch [new file with mode: 0644]
queue-4.4/series

diff --git a/queue-4.4/audit-always-check-the-netlink-payload-length-in-aud.patch b/queue-4.4/audit-always-check-the-netlink-payload-length-in-aud.patch
new file mode 100644 (file)
index 0000000..8e6babd
--- /dev/null
@@ -0,0 +1,153 @@
+From f7ce65fc7455ebd4aea3ffa1d1ed4a00f237f8e1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 Feb 2020 16:38:57 -0500
+Subject: audit: always check the netlink payload length in audit_receive_msg()
+
+From: Paul Moore <paul@paul-moore.com>
+
+[ Upstream commit 756125289285f6e55a03861bf4b6257aa3d19a93 ]
+
+This patch ensures that we always check the netlink payload length
+in audit_receive_msg() before we take any action on the payload
+itself.
+
+Cc: stable@vger.kernel.org
+Reported-by: syzbot+399c44bf1f43b8747403@syzkaller.appspotmail.com
+Reported-by: syzbot+e4b12d8d202701f08b6d@syzkaller.appspotmail.com
+Signed-off-by: Paul Moore <paul@paul-moore.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/audit.c | 40 +++++++++++++++++++++-------------------
+ 1 file changed, 21 insertions(+), 19 deletions(-)
+
+diff --git a/kernel/audit.c b/kernel/audit.c
+index bdf0cf463815e..84c445db5fe1e 100644
+--- a/kernel/audit.c
++++ b/kernel/audit.c
+@@ -753,13 +753,11 @@ static void audit_log_feature_change(int which, u32 old_feature, u32 new_feature
+       audit_log_end(ab);
+ }
+-static int audit_set_feature(struct sk_buff *skb)
++static int audit_set_feature(struct audit_features *uaf)
+ {
+-      struct audit_features *uaf;
+       int i;
+       BUILD_BUG_ON(AUDIT_LAST_FEATURE + 1 > ARRAY_SIZE(audit_feature_names));
+-      uaf = nlmsg_data(nlmsg_hdr(skb));
+       /* if there is ever a version 2 we should handle that here */
+@@ -815,6 +813,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
+ {
+       u32                     seq;
+       void                    *data;
++      int                     data_len;
+       int                     err;
+       struct audit_buffer     *ab;
+       u16                     msg_type = nlh->nlmsg_type;
+@@ -838,6 +837,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
+       }
+       seq  = nlh->nlmsg_seq;
+       data = nlmsg_data(nlh);
++      data_len = nlmsg_len(nlh);
+       switch (msg_type) {
+       case AUDIT_GET: {
+@@ -859,7 +859,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
+               struct audit_status     s;
+               memset(&s, 0, sizeof(s));
+               /* guard against past and future API changes */
+-              memcpy(&s, data, min_t(size_t, sizeof(s), nlmsg_len(nlh)));
++              memcpy(&s, data, min_t(size_t, sizeof(s), data_len));
+               if (s.mask & AUDIT_STATUS_ENABLED) {
+                       err = audit_set_enabled(s.enabled);
+                       if (err < 0)
+@@ -908,7 +908,9 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
+                       return err;
+               break;
+       case AUDIT_SET_FEATURE:
+-              err = audit_set_feature(skb);
++              if (data_len < sizeof(struct audit_features))
++                      return -EINVAL;
++              err = audit_set_feature(data);
+               if (err)
+                       return err;
+               break;
+@@ -920,6 +922,8 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
+               err = audit_filter_user(msg_type);
+               if (err == 1) { /* match or error */
++                      char *str = data;
++
+                       err = 0;
+                       if (msg_type == AUDIT_USER_TTY) {
+                               err = tty_audit_push_current();
+@@ -928,19 +932,17 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
+                       }
+                       mutex_unlock(&audit_cmd_mutex);
+                       audit_log_common_recv_msg(&ab, msg_type);
+-                      if (msg_type != AUDIT_USER_TTY)
++                      if (msg_type != AUDIT_USER_TTY) {
++                              /* ensure NULL termination */
++                              str[data_len - 1] = '\0';
+                               audit_log_format(ab, " msg='%.*s'",
+                                                AUDIT_MESSAGE_TEXT_MAX,
+-                                               (char *)data);
+-                      else {
+-                              int size;
+-
++                                               str);
++                      } else {
+                               audit_log_format(ab, " data=");
+-                              size = nlmsg_len(nlh);
+-                              if (size > 0 &&
+-                                  ((unsigned char *)data)[size - 1] == '\0')
+-                                      size--;
+-                              audit_log_n_untrustedstring(ab, data, size);
++                              if (data_len > 0 && str[data_len - 1] == '\0')
++                                      data_len--;
++                              audit_log_n_untrustedstring(ab, str, data_len);
+                       }
+                       audit_set_portid(ab, NETLINK_CB(skb).portid);
+                       audit_log_end(ab);
+@@ -949,7 +951,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
+               break;
+       case AUDIT_ADD_RULE:
+       case AUDIT_DEL_RULE:
+-              if (nlmsg_len(nlh) < sizeof(struct audit_rule_data))
++              if (data_len < sizeof(struct audit_rule_data))
+                       return -EINVAL;
+               if (audit_enabled == AUDIT_LOCKED) {
+                       audit_log_common_recv_msg(&ab, AUDIT_CONFIG_CHANGE);
+@@ -958,7 +960,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
+                       return -EPERM;
+               }
+               err = audit_rule_change(msg_type, NETLINK_CB(skb).portid,
+-                                         seq, data, nlmsg_len(nlh));
++                                         seq, data, data_len);
+               break;
+       case AUDIT_LIST_RULES:
+               err = audit_list_rules_send(skb, seq);
+@@ -972,7 +974,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
+       case AUDIT_MAKE_EQUIV: {
+               void *bufp = data;
+               u32 sizes[2];
+-              size_t msglen = nlmsg_len(nlh);
++              size_t msglen = data_len;
+               char *old, *new;
+               err = -EINVAL;
+@@ -1049,7 +1051,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
+               memset(&s, 0, sizeof(s));
+               /* guard against past and future API changes */
+-              memcpy(&s, data, min_t(size_t, sizeof(s), nlmsg_len(nlh)));
++              memcpy(&s, data, min_t(size_t, sizeof(s), data_len));
+               /* check if new data is valid */
+               if ((s.enabled != 0 && s.enabled != 1) ||
+                   (s.log_passwd != 0 && s.log_passwd != 1))
+-- 
+2.20.1
+
index bf0c18fb2eb2a54ab501e0c0b11cb543bbd469cd..b99975e8aa580edfdc2455b5649c7626914baf9e 100644 (file)
@@ -37,3 +37,4 @@ mm-gup-ensure-real-head-page-is-ref-counted-when-using-hugepages.patch
 mm-prevent-get_user_pages-from-overflowing-page-refcount.patch
 pipe-add-pipe_buf_get-helper.patch
 fs-prevent-page-refcount-overflow-in-pipe_buf_get.patch
+audit-always-check-the-netlink-payload-length-in-aud.patch