]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.14-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 14 Dec 2017 21:13:50 +0000 (22:13 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 14 Dec 2017 21:13:50 +0000 (22:13 +0100)
added patches:
fix-kcm_clone.patch

queue-4.14/fix-kcm_clone.patch [new file with mode: 0644]
queue-4.14/series

diff --git a/queue-4.14/fix-kcm_clone.patch b/queue-4.14/fix-kcm_clone.patch
new file mode 100644 (file)
index 0000000..4c0e70d
--- /dev/null
@@ -0,0 +1,134 @@
+From a5739435b5a3b8c449f8844ecd71a3b1e89f0a33 Mon Sep 17 00:00:00 2001
+From: Al Viro <viro@ZenIV.linux.org.uk>
+Date: Tue, 5 Dec 2017 23:27:57 +0000
+Subject: fix kcm_clone()
+
+From: Al Viro <viro@ZenIV.linux.org.uk>
+
+commit a5739435b5a3b8c449f8844ecd71a3b1e89f0a33 upstream.
+
+1) it's fput() or sock_release(), not both
+2) don't do fd_install() until the last failure exit.
+3) not a bug per se, but... don't attach socket to struct file
+   until it's set up.
+
+Take reserving descriptor into the caller, move fd_install() to the
+caller, sanitize failure exits and calling conventions.
+
+Acked-by: Tom Herbert <tom@herbertland.com>
+Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/kcm/kcmsock.c |   71 ++++++++++++++++++++----------------------------------
+ 1 file changed, 27 insertions(+), 44 deletions(-)
+
+--- a/net/kcm/kcmsock.c
++++ b/net/kcm/kcmsock.c
+@@ -1625,60 +1625,35 @@ static struct proto kcm_proto = {
+ };
+ /* Clone a kcm socket. */
+-static int kcm_clone(struct socket *osock, struct kcm_clone *info,
+-                   struct socket **newsockp)
++static struct file *kcm_clone(struct socket *osock)
+ {
+       struct socket *newsock;
+       struct sock *newsk;
+-      struct file *newfile;
+-      int err, newfd;
++      struct file *file;
+-      err = -ENFILE;
+       newsock = sock_alloc();
+       if (!newsock)
+-              goto out;
++              return ERR_PTR(-ENFILE);
+       newsock->type = osock->type;
+       newsock->ops = osock->ops;
+       __module_get(newsock->ops->owner);
+-      newfd = get_unused_fd_flags(0);
+-      if (unlikely(newfd < 0)) {
+-              err = newfd;
+-              goto out_fd_fail;
+-      }
+-
+-      newfile = sock_alloc_file(newsock, 0, osock->sk->sk_prot_creator->name);
+-      if (unlikely(IS_ERR(newfile))) {
+-              err = PTR_ERR(newfile);
+-              goto out_sock_alloc_fail;
+-      }
+-
+       newsk = sk_alloc(sock_net(osock->sk), PF_KCM, GFP_KERNEL,
+                        &kcm_proto, true);
+       if (!newsk) {
+-              err = -ENOMEM;
+-              goto out_sk_alloc_fail;
++              sock_release(newsock);
++              return ERR_PTR(-ENOMEM);
+       }
+-
+       sock_init_data(newsock, newsk);
+       init_kcm_sock(kcm_sk(newsk), kcm_sk(osock->sk)->mux);
+-      fd_install(newfd, newfile);
+-      *newsockp = newsock;
+-      info->fd = newfd;
+-
+-      return 0;
+-
+-out_sk_alloc_fail:
+-      fput(newfile);
+-out_sock_alloc_fail:
+-      put_unused_fd(newfd);
+-out_fd_fail:
+-      sock_release(newsock);
+-out:
+-      return err;
++      file = sock_alloc_file(newsock, 0, osock->sk->sk_prot_creator->name);
++      if (IS_ERR(file))
++              sock_release(newsock);
++
++      return file;
+ }
+ static int kcm_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
+@@ -1708,17 +1683,25 @@ static int kcm_ioctl(struct socket *sock
+       }
+       case SIOCKCMCLONE: {
+               struct kcm_clone info;
+-              struct socket *newsock = NULL;
++              struct file *file;
+-              err = kcm_clone(sock, &info, &newsock);
+-              if (!err) {
+-                      if (copy_to_user((void __user *)arg, &info,
+-                                       sizeof(info))) {
+-                              err = -EFAULT;
+-                              sys_close(info.fd);
+-                      }
++              info.fd = get_unused_fd_flags(0);
++              if (unlikely(info.fd < 0))
++                      return info.fd;
++
++              file = kcm_clone(sock);
++              if (IS_ERR(file)) {
++                      put_unused_fd(info.fd);
++                      return PTR_ERR(file);
+               }
+-
++              if (copy_to_user((void __user *)arg, &info,
++                               sizeof(info))) {
++                      put_unused_fd(info.fd);
++                      fput(file);
++                      return -EFAULT;
++              }
++              fd_install(info.fd, file);
++              err = 0;
+               break;
+       }
+       default:
index c370d6dd6ed74dcbc3185b45a09d348f9ee6edd5..3f3411ccf13aab9d4a59b26d8a15be96ab4939c9 100644 (file)
@@ -34,3 +34,4 @@ sctp-use-right-member-as-the-param-of-list_for_each_entry.patch
 ipmi-stop-timers-before-cleaning-up-the-module.patch
 usb-gadget-ffs-forbid-usb_ep_alloc_request-from-sleeping.patch
 fcntl-don-t-cap-l_start-and-l_end-values-for-f_getlk64-in-compat-syscall.patch
+fix-kcm_clone.patch