From: Greg Kroah-Hartman Date: Sun, 2 Feb 2020 20:47:22 +0000 (+0000) Subject: 5.4-stable patches X-Git-Tag: v5.5.2~45 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=0d3dff7856a0bb34344e48276242e920d646ec38;p=thirdparty%2Fkernel%2Fstable-queue.git 5.4-stable patches added patches: cifs-fix-soft-mounts-hanging-in-the-reconnect-code.patch vfs-fix-do_last-regression.patch --- diff --git a/queue-5.4/cifs-fix-soft-mounts-hanging-in-the-reconnect-code.patch b/queue-5.4/cifs-fix-soft-mounts-hanging-in-the-reconnect-code.patch new file mode 100644 index 00000000000..5636f74d2d2 --- /dev/null +++ b/queue-5.4/cifs-fix-soft-mounts-hanging-in-the-reconnect-code.patch @@ -0,0 +1,52 @@ +From c54849ddd832ae0a45cab16bcd1ed2db7da090d7 Mon Sep 17 00:00:00 2001 +From: Ronnie Sahlberg +Date: Fri, 31 Jan 2020 05:52:51 +1000 +Subject: cifs: fix soft mounts hanging in the reconnect code + +From: Ronnie Sahlberg + +commit c54849ddd832ae0a45cab16bcd1ed2db7da090d7 upstream. + +RHBZ: 1795429 + +In recent DFS updates we have a new variable controlling how many times we will +retry to reconnect the share. +If DFS is not used, then this variable is initialized to 0 in: + +static inline int +dfs_cache_get_nr_tgts(const struct dfs_cache_tgt_list *tl) +{ + return tl ? tl->tl_numtgts : 0; +} + +This means that in the reconnect loop in smb2_reconnect() we will immediately wrap retries to -1 +and never actually get to pass this conditional: + + if (--retries) + continue; + +The effect is that we no longer reach the point where we fail the commands with -EHOSTDOWN +and basically the kernel threads are virtually hung and unkillable. + +Fixes: a3a53b7603798fd8 (cifs: Add support for failover in smb2_reconnect()) +Signed-off-by: Ronnie Sahlberg +Signed-off-by: Steve French +Reviewed-by: Paulo Alcantara (SUSE) +CC: Stable +Signed-off-by: Greg Kroah-Hartman + +--- + fs/cifs/smb2pdu.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/fs/cifs/smb2pdu.c ++++ b/fs/cifs/smb2pdu.c +@@ -312,7 +312,7 @@ smb2_reconnect(__le16 smb2_command, stru + if (server->tcpStatus != CifsNeedReconnect) + break; + +- if (--retries) ++ if (retries && --retries) + continue; + + /* diff --git a/queue-5.4/series b/queue-5.4/series new file mode 100644 index 00000000000..e3e14c386dd --- /dev/null +++ b/queue-5.4/series @@ -0,0 +1,2 @@ +vfs-fix-do_last-regression.patch +cifs-fix-soft-mounts-hanging-in-the-reconnect-code.patch diff --git a/queue-5.4/vfs-fix-do_last-regression.patch b/queue-5.4/vfs-fix-do_last-regression.patch new file mode 100644 index 00000000000..f0134debb61 --- /dev/null +++ b/queue-5.4/vfs-fix-do_last-regression.patch @@ -0,0 +1,63 @@ +From 6404674acd596de41fd3ad5f267b4525494a891a Mon Sep 17 00:00:00 2001 +From: Al Viro +Date: Sat, 1 Feb 2020 16:26:45 +0000 +Subject: vfs: fix do_last() regression + +From: Al Viro + +commit 6404674acd596de41fd3ad5f267b4525494a891a upstream. + +Brown paperbag time: fetching ->i_uid/->i_mode really should've been +done from nd->inode. I even suggested that, but the reason for that has +slipped through the cracks and I went for dir->d_inode instead - made +for more "obvious" patch. + +Analysis: + + - at the entry into do_last() and all the way to step_into(): dir (aka + nd->path.dentry) is known not to have been freed; so's nd->inode and + it's equal to dir->d_inode unless we are already doomed to -ECHILD. + inode of the file to get opened is not known. + + - after step_into(): inode of the file to get opened is known; dir + might be pointing to freed memory/be negative/etc. + + - at the call of may_create_in_sticky(): guaranteed to be out of RCU + mode; inode of the file to get opened is known and pinned; dir might + be garbage. + +The last was the reason for the original patch. Except that at the +do_last() entry we can be in RCU mode and it is possible that +nd->path.dentry->d_inode has already changed under us. + +In that case we are going to fail with -ECHILD, but we need to be +careful; nd->inode is pointing to valid struct inode and it's the same +as nd->path.dentry->d_inode in "won't fail with -ECHILD" case, so we +should use that. + +Reported-by: "Rantala, Tommi T. (Nokia - FI/Espoo)" +Reported-by: syzbot+190005201ced78a74ad6@syzkaller.appspotmail.com +Wearing-brown-paperbag: Al Viro +Cc: stable@kernel.org +Fixes: d0cb50185ae9 ("do_last(): fetch directory ->i_mode and ->i_uid before it's too late") +Signed-off-by: Al Viro +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + fs/namei.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/fs/namei.c ++++ b/fs/namei.c +@@ -3249,8 +3249,8 @@ static int do_last(struct nameidata *nd, + struct file *file, const struct open_flags *op) + { + struct dentry *dir = nd->path.dentry; +- kuid_t dir_uid = dir->d_inode->i_uid; +- umode_t dir_mode = dir->d_inode->i_mode; ++ kuid_t dir_uid = nd->inode->i_uid; ++ umode_t dir_mode = nd->inode->i_mode; + int open_flag = op->open_flag; + bool will_truncate = (open_flag & O_TRUNC) != 0; + bool got_write = false;