Patch "af_unix: move unix_mknod() out of bindlock" has been added to the 4.4-stable tree
Subsystems (3)
This is a note to let you know that I've just added the patch titled
af_unix: move unix_mknod() out of bindlock
to the 4.4-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:
af_unix-move-unix_mknod-out-of-bindlock.patch
and it can be found in the queue-4.4 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 foo@baz Wed Feb 1 08:49:51 CET 2017
From: WANG Cong <[email protected]>
Date: Mon, 23 Jan 2017 11:17:35 -0800
Subject: af_unix: move unix_mknod() out of bindlock
From: WANG Cong <[email protected]>
[ Upstream commit 0fb44559ffd67de8517098b81f675fa0210f13f0 ]
Dmitry reported a deadlock scenario:
unix_bind() path:u->bindlock ==> sb_writer
do_splice() path:sb_writer ==> pipe->mutex ==> u->bindlock
In the unix_bind() code path, unix_mknod() does not have to be done with u->bindlock held, since it is a pure fs operation, so we can just move unix_mknod() out.
--- net/unix/af_unix.c | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-)
net/unix/af_unix.c +16 -11
@@ -994,6 +994,7 @@ static int unix_bind(struct socket *sockunsigned int hash;struct unix_address *addr;struct hlist_head *list; +struct path path = {NULL ,NULL }; err = -EINVAL ;if (sunaddr->sun_family !=AF_UNIX )
@@ -1009,9 +1010,20 @@ static int unix_bind(struct socket *sock goto out; addr_len = err; +if (sun_path[0 ]) { +umode_t mode =S_IFSOCK | + (SOCK_INODE (sock)->i_mode & ~current_umask ()); + err =unix_mknod (sun_path, mode, &path); +if (err) { +if (err == -EEXIST ) + err = -EADDRINUSE ; + goto out; + } + } + err =mutex_lock_interruptible (&u->bindlock);if (err) - goto out; + goto out_put; err = -EINVAL ;if (u->addr)
@@ -1028,16 +1040,6 @@ static int unix_bind(struct socket *sockatomic_set (&addr->refcnt,1 );if (sun_path[0 ]) { -struct path path; -umode_t mode =S_IFSOCK | - (SOCK_INODE (sock)->i_mode & ~current_umask ()); - err =unix_mknod (sun_path, mode, &path); -if (err) { -if (err == -EEXIST ) - err = -EADDRINUSE ; -unix_release_addr (addr); - goto out_up; - } addr->hash =UNIX_HASH_SIZE ; hash =d_real_inode (path.dentry)->i_ino & (UNIX_HASH_SIZE -1 );spin_lock (&unix_table_lock);
@@ -1064,6 +1066,9 @@ out_unlock:spin_unlock (&unix_table_lock); out_up:mutex_unlock (&u->bindlock); +out_put: +if (err) +path_put (&path); out:return err; }
Patches currently in stable-queue which might be from [email protected] are
queue-4.4/af_unix-move-unix_mknod-out-of-bindlock.patch