]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.15-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 23 Feb 2018 09:04:31 +0000 (10:04 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 23 Feb 2018 09:04:31 +0000 (10:04 +0100)
added patches:
dn_getsockoptdecnet-move-nf_-get-set-sockopt-outside-sock-lock.patch

queue-4.15/dn_getsockoptdecnet-move-nf_-get-set-sockopt-outside-sock-lock.patch [new file with mode: 0644]
queue-4.15/series

diff --git a/queue-4.15/dn_getsockoptdecnet-move-nf_-get-set-sockopt-outside-sock-lock.patch b/queue-4.15/dn_getsockoptdecnet-move-nf_-get-set-sockopt-outside-sock-lock.patch
new file mode 100644 (file)
index 0000000..7e6d6b4
--- /dev/null
@@ -0,0 +1,135 @@
+From dfec091439bb2acf763497cfc58f2bdfc67c56b7 Mon Sep 17 00:00:00 2001
+From: Paolo Abeni <pabeni@redhat.com>
+Date: Thu, 15 Feb 2018 16:59:49 +0100
+Subject: dn_getsockoptdecnet: move nf_{get/set}sockopt outside sock lock
+
+From: Paolo Abeni <pabeni@redhat.com>
+
+commit dfec091439bb2acf763497cfc58f2bdfc67c56b7 upstream.
+
+After commit 3f34cfae1238 ("netfilter: on sockopt() acquire sock lock
+only in the required scope"), the caller of nf_{get/set}sockopt() must
+not hold any lock, but, in such changeset, I forgot to cope with DECnet.
+
+This commit addresses the issue moving the nf call outside the lock,
+in the dn_{get,set}sockopt() with the same schema currently used by
+ipv4 and ipv6. Also moves the unhandled sockopts of the end of the main
+switch statements, to improve code readability.
+
+Reported-by: Petr Vandrovec <petr@vandrovec.name>
+BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=198791#c2
+Fixes: 3f34cfae1238 ("netfilter: on sockopt() acquire sock lock only in the required scope")
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/decnet/af_decnet.c |   62 ++++++++++++++++++++++++++-----------------------
+ 1 file changed, 33 insertions(+), 29 deletions(-)
+
+--- a/net/decnet/af_decnet.c
++++ b/net/decnet/af_decnet.c
+@@ -1338,6 +1338,12 @@ static int dn_setsockopt(struct socket *
+       lock_sock(sk);
+       err = __dn_setsockopt(sock, level, optname, optval, optlen, 0);
+       release_sock(sk);
++#ifdef CONFIG_NETFILTER
++      /* we need to exclude all possible ENOPROTOOPTs except default case */
++      if (err == -ENOPROTOOPT && optname != DSO_LINKINFO &&
++          optname != DSO_STREAM && optname != DSO_SEQPACKET)
++              err = nf_setsockopt(sk, PF_DECnet, optname, optval, optlen);
++#endif
+       return err;
+ }
+@@ -1445,15 +1451,6 @@ static int __dn_setsockopt(struct socket
+               dn_nsp_send_disc(sk, 0x38, 0, sk->sk_allocation);
+               break;
+-      default:
+-#ifdef CONFIG_NETFILTER
+-              return nf_setsockopt(sk, PF_DECnet, optname, optval, optlen);
+-#endif
+-      case DSO_LINKINFO:
+-      case DSO_STREAM:
+-      case DSO_SEQPACKET:
+-              return -ENOPROTOOPT;
+-
+       case DSO_MAXWINDOW:
+               if (optlen != sizeof(unsigned long))
+                       return -EINVAL;
+@@ -1501,6 +1498,12 @@ static int __dn_setsockopt(struct socket
+                       return -EINVAL;
+               scp->info_loc = u.info;
+               break;
++
++      case DSO_LINKINFO:
++      case DSO_STREAM:
++      case DSO_SEQPACKET:
++      default:
++              return -ENOPROTOOPT;
+       }
+       return 0;
+@@ -1514,6 +1517,20 @@ static int dn_getsockopt(struct socket *
+       lock_sock(sk);
+       err = __dn_getsockopt(sock, level, optname, optval, optlen, 0);
+       release_sock(sk);
++#ifdef CONFIG_NETFILTER
++      if (err == -ENOPROTOOPT && optname != DSO_STREAM &&
++          optname != DSO_SEQPACKET && optname != DSO_CONACCEPT &&
++          optname != DSO_CONREJECT) {
++              int len;
++
++              if (get_user(len, optlen))
++                      return -EFAULT;
++
++              err = nf_getsockopt(sk, PF_DECnet, optname, optval, &len);
++              if (err >= 0)
++                      err = put_user(len, optlen);
++      }
++#endif
+       return err;
+ }
+@@ -1579,26 +1596,6 @@ static int __dn_getsockopt(struct socket
+               r_data = &link;
+               break;
+-      default:
+-#ifdef CONFIG_NETFILTER
+-      {
+-              int ret, len;
+-
+-              if (get_user(len, optlen))
+-                      return -EFAULT;
+-
+-              ret = nf_getsockopt(sk, PF_DECnet, optname, optval, &len);
+-              if (ret >= 0)
+-                      ret = put_user(len, optlen);
+-              return ret;
+-      }
+-#endif
+-      case DSO_STREAM:
+-      case DSO_SEQPACKET:
+-      case DSO_CONACCEPT:
+-      case DSO_CONREJECT:
+-              return -ENOPROTOOPT;
+-
+       case DSO_MAXWINDOW:
+               if (r_len > sizeof(unsigned long))
+                       r_len = sizeof(unsigned long);
+@@ -1630,6 +1627,13 @@ static int __dn_getsockopt(struct socket
+                       r_len = sizeof(unsigned char);
+               r_data = &scp->info_rem;
+               break;
++
++      case DSO_STREAM:
++      case DSO_SEQPACKET:
++      case DSO_CONACCEPT:
++      case DSO_CONREJECT:
++      default:
++              return -ENOPROTOOPT;
+       }
+       if (r_data) {
index dc839f6f506ced3f313226784b3c8ee22938c65c..b49759a0c19f3479f89c672210188f28877adfdb 100644 (file)
@@ -25,3 +25,4 @@ asoc-ux500-add-module_license-tag.patch
 video-fbdev-mmp-add-module_license.patch
 arm-8743-1-bl_switcher-add-module_license-tag.patch
 arm64-dts-add-cooling-cells-to-cpu-nodes.patch
+dn_getsockoptdecnet-move-nf_-get-set-sockopt-outside-sock-lock.patch