Patch "fix kcm_clone()" has been added to the 4.14-stable tree
Subsystems (2)
This is a note to let you know that I've just added the patch titled
fix kcm_clone()
to the 4.14-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
fix-kcm_clone.patch
and it can be found in the queue-4.14 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
a5739435b5a3b8c449f8844ecd71a3b1e89f0a33Mon Sep 17 00:00:00 2001
From: Al Viro <[email protected]>
Date: Tue, 5 Dec 2017 23:27:57 +0000
Subject: fix kcm_clone()
From: Al Viro <[email protected]>
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.
--- net/kcm/kcmsock.c | 71 ++++++++++++++++++++---------------------------------- 1 file changed, 27 insertions(+), 44 deletions(-)
net/kcm/kcmsock.c +27 -44
@@ -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 :
Patches currently in stable-queue which might be from [email protected] are
queue-4.14/fix-kcm_clone.patch