]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.19-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 4 May 2020 15:52:41 +0000 (17:52 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 4 May 2020 15:52:41 +0000 (17:52 +0200)
added patches:
selinux-properly-handle-multiple-messages-in-selinux_netlink_send.patch

queue-4.19/selinux-properly-handle-multiple-messages-in-selinux_netlink_send.patch [new file with mode: 0644]
queue-4.19/series

diff --git a/queue-4.19/selinux-properly-handle-multiple-messages-in-selinux_netlink_send.patch b/queue-4.19/selinux-properly-handle-multiple-messages-in-selinux_netlink_send.patch
new file mode 100644 (file)
index 0000000..03ec3b5
--- /dev/null
@@ -0,0 +1,112 @@
+From fb73974172ffaaf57a7c42f35424d9aece1a5af6 Mon Sep 17 00:00:00 2001
+From: Paul Moore <paul@paul-moore.com>
+Date: Tue, 28 Apr 2020 09:59:02 -0400
+Subject: selinux: properly handle multiple messages in selinux_netlink_send()
+
+From: Paul Moore <paul@paul-moore.com>
+
+commit fb73974172ffaaf57a7c42f35424d9aece1a5af6 upstream.
+
+Fix the SELinux netlink_send hook to properly handle multiple netlink
+messages in a single sk_buff; each message is parsed and subject to
+SELinux access control.  Prior to this patch, SELinux only inspected
+the first message in the sk_buff.
+
+Cc: stable@vger.kernel.org
+Reported-by: Dmitry Vyukov <dvyukov@google.com>
+Reviewed-by: Stephen Smalley <stephen.smalley.work@gmail.com>
+Signed-off-by: Paul Moore <paul@paul-moore.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ security/selinux/hooks.c |   70 ++++++++++++++++++++++++++++++-----------------
+ 1 file changed, 45 insertions(+), 25 deletions(-)
+
+--- a/security/selinux/hooks.c
++++ b/security/selinux/hooks.c
+@@ -5595,40 +5595,60 @@ static int selinux_tun_dev_open(void *se
+ static int selinux_nlmsg_perm(struct sock *sk, struct sk_buff *skb)
+ {
+-      int err = 0;
+-      u32 perm;
++      int rc = 0;
++      unsigned int msg_len;
++      unsigned int data_len = skb->len;
++      unsigned char *data = skb->data;
+       struct nlmsghdr *nlh;
+       struct sk_security_struct *sksec = sk->sk_security;
++      u16 sclass = sksec->sclass;
++      u32 perm;
+-      if (skb->len < NLMSG_HDRLEN) {
+-              err = -EINVAL;
+-              goto out;
+-      }
+-      nlh = nlmsg_hdr(skb);
++      while (data_len >= nlmsg_total_size(0)) {
++              nlh = (struct nlmsghdr *)data;
+-      err = selinux_nlmsg_lookup(sksec->sclass, nlh->nlmsg_type, &perm);
+-      if (err) {
+-              if (err == -EINVAL) {
++              /* NOTE: the nlmsg_len field isn't reliably set by some netlink
++               *       users which means we can't reject skb's with bogus
++               *       length fields; our solution is to follow what
++               *       netlink_rcv_skb() does and simply skip processing at
++               *       messages with length fields that are clearly junk
++               */
++              if (nlh->nlmsg_len < NLMSG_HDRLEN || nlh->nlmsg_len > data_len)
++                      return 0;
++
++              rc = selinux_nlmsg_lookup(sclass, nlh->nlmsg_type, &perm);
++              if (rc == 0) {
++                      rc = sock_has_perm(sk, perm);
++                      if (rc)
++                              return rc;
++              } else if (rc == -EINVAL) {
++                      /* -EINVAL is a missing msg/perm mapping */
+                       pr_warn_ratelimited("SELinux: unrecognized netlink"
+-                             " message: protocol=%hu nlmsg_type=%hu sclass=%s"
+-                             " pig=%d comm=%s\n",
+-                             sk->sk_protocol, nlh->nlmsg_type,
+-                             secclass_map[sksec->sclass - 1].name,
+-                             task_pid_nr(current), current->comm);
+-                      if (!enforcing_enabled(&selinux_state) ||
+-                          security_get_allow_unknown(&selinux_state))
+-                              err = 0;
++                              " message: protocol=%hu nlmsg_type=%hu sclass=%s"
++                              " pid=%d comm=%s\n",
++                              sk->sk_protocol, nlh->nlmsg_type,
++                              secclass_map[sclass - 1].name,
++                              task_pid_nr(current), current->comm);
++                      if (enforcing_enabled(&selinux_state) &&
++                          !security_get_allow_unknown(&selinux_state))
++                              return rc;
++                      rc = 0;
++              } else if (rc == -ENOENT) {
++                      /* -ENOENT is a missing socket/class mapping, ignore */
++                      rc = 0;
++              } else {
++                      return rc;
+               }
+-              /* Ignore */
+-              if (err == -ENOENT)
+-                      err = 0;
+-              goto out;
++              /* move to the next message after applying netlink padding */
++              msg_len = NLMSG_ALIGN(nlh->nlmsg_len);
++              if (msg_len >= data_len)
++                      return 0;
++              data_len -= msg_len;
++              data += msg_len;
+       }
+-      err = sock_has_perm(sk, perm);
+-out:
+-      return err;
++      return rc;
+ }
+ #ifdef CONFIG_NETFILTER
index f83bd5f5f09085c6136dd79910d2cd6cd2e6d01f..35894086930f3bf968919448a37947690767316d 100644 (file)
@@ -26,6 +26,7 @@ iommu-amd-fix-legacy-interrupt-remapping-for-x2apic-enabled-system.patch
 alsa-opti9xx-shut-up-gcc-10-range-warning.patch
 nfs-fix-potential-posix_acl-refcnt-leak-in-nfs3_set_acl.patch
 dmaengine-dmatest-fix-iteration-non-stop-logic.patch
+selinux-properly-handle-multiple-messages-in-selinux_netlink_send.patch
 btrfs-fix-partial-loss-of-prealloc-extent-past-i_size-after-fsync.patch
 btrfs-transaction-avoid-deadlock-due-to-bad-initialization-timing-of-fs_info-journal_info.patch
 mmc-cqhci-avoid-false-cqhci-cqe-stuck-on-by-not-open-coding-timeout-loop.patch