]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 15 Nov 2021 13:59:31 +0000 (14:59 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 15 Nov 2021 13:59:31 +0000 (14:59 +0100)
added patches:
9p-net-fix-missing-error-check-in-p9_check_errors.patch
ovl-fix-deadlock-in-splice-write.patch

queue-5.4/9p-net-fix-missing-error-check-in-p9_check_errors.patch [new file with mode: 0644]
queue-5.4/ovl-fix-deadlock-in-splice-write.patch [new file with mode: 0644]
queue-5.4/series

diff --git a/queue-5.4/9p-net-fix-missing-error-check-in-p9_check_errors.patch b/queue-5.4/9p-net-fix-missing-error-check-in-p9_check_errors.patch
new file mode 100644 (file)
index 0000000..94061a4
--- /dev/null
@@ -0,0 +1,29 @@
+From 27eb4c3144f7a5ebef3c9a261d80cb3e1fa784dc Mon Sep 17 00:00:00 2001
+From: Dominique Martinet <asmadeus@codewreck.org>
+Date: Tue, 2 Nov 2021 19:47:47 +0900
+Subject: 9p/net: fix missing error check in p9_check_errors
+
+From: Dominique Martinet <asmadeus@codewreck.org>
+
+commit 27eb4c3144f7a5ebef3c9a261d80cb3e1fa784dc upstream.
+
+Link: https://lkml.kernel.org/r/99338965-d36c-886e-cd0e-1d8fff2b4746@gmail.com
+Reported-by: syzbot+06472778c97ed94af66d@syzkaller.appspotmail.com
+Cc: stable@vger.kernel.org
+Signed-off-by: Dominique Martinet <asmadeus@codewreck.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/9p/client.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/net/9p/client.c
++++ b/net/9p/client.c
+@@ -538,6 +538,8 @@ static int p9_check_errors(struct p9_cli
+               kfree(ename);
+       } else {
+               err = p9pdu_readf(&req->rc, c->proto_version, "d", &ecode);
++              if (err)
++                      goto out_err;
+               err = -ecode;
+               p9_debug(P9_DEBUG_9P, "<<< RLERROR (%d)\n", -ecode);
diff --git a/queue-5.4/ovl-fix-deadlock-in-splice-write.patch b/queue-5.4/ovl-fix-deadlock-in-splice-write.patch
new file mode 100644 (file)
index 0000000..7e62b82
--- /dev/null
@@ -0,0 +1,104 @@
+From 9b91b6b019fda817eb52f728eb9c79b3579760bc Mon Sep 17 00:00:00 2001
+From: Miklos Szeredi <mszeredi@redhat.com>
+Date: Wed, 28 Jul 2021 10:38:43 +0200
+Subject: ovl: fix deadlock in splice write
+
+From: Miklos Szeredi <mszeredi@redhat.com>
+
+commit 9b91b6b019fda817eb52f728eb9c79b3579760bc upstream.
+
+There's possibility of an ABBA deadlock in case of a splice write to an
+overlayfs file and a concurrent splice write to a corresponding real file.
+
+The call chain for splice to an overlay file:
+
+ -> do_splice                     [takes sb_writers on overlay file]
+   -> do_splice_from
+     -> iter_file_splice_write    [takes pipe->mutex]
+       -> vfs_iter_write
+         ...
+         -> ovl_write_iter        [takes sb_writers on real file]
+
+And the call chain for splice to a real file:
+
+ -> do_splice                     [takes sb_writers on real file]
+   -> do_splice_from
+     -> iter_file_splice_write    [takes pipe->mutex]
+
+Syzbot successfully bisected this to commit 82a763e61e2b ("ovl: simplify
+file splice").
+
+Fix by reverting the write part of the above commit and by adding missing
+bits from ovl_write_iter() into ovl_splice_write().
+
+Fixes: 82a763e61e2b ("ovl: simplify file splice")
+Reported-and-tested-by: syzbot+579885d1a9a833336209@syzkaller.appspotmail.com
+Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/overlayfs/file.c |   47 ++++++++++++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 46 insertions(+), 1 deletion(-)
+
+--- a/fs/overlayfs/file.c
++++ b/fs/overlayfs/file.c
+@@ -296,6 +296,51 @@ out_unlock:
+       return ret;
+ }
++/*
++ * Calling iter_file_splice_write() directly from overlay's f_op may deadlock
++ * due to lock order inversion between pipe->mutex in iter_file_splice_write()
++ * and file_start_write(real.file) in ovl_write_iter().
++ *
++ * So do everything ovl_write_iter() does and call iter_file_splice_write() on
++ * the real file.
++ */
++static ssize_t ovl_splice_write(struct pipe_inode_info *pipe, struct file *out,
++                              loff_t *ppos, size_t len, unsigned int flags)
++{
++      struct fd real;
++      const struct cred *old_cred;
++      struct inode *inode = file_inode(out);
++      struct inode *realinode = ovl_inode_real(inode);
++      ssize_t ret;
++
++      inode_lock(inode);
++      /* Update mode */
++      ovl_copyattr(realinode, inode);
++      ret = file_remove_privs(out);
++      if (ret)
++              goto out_unlock;
++
++      ret = ovl_real_fdget(out, &real);
++      if (ret)
++              goto out_unlock;
++
++      old_cred = ovl_override_creds(inode->i_sb);
++      file_start_write(real.file);
++
++      ret = iter_file_splice_write(pipe, real.file, ppos, len, flags);
++
++      file_end_write(real.file);
++      /* Update size */
++      ovl_copyattr(realinode, inode);
++      revert_creds(old_cred);
++      fdput(real);
++
++out_unlock:
++      inode_unlock(inode);
++
++      return ret;
++}
++
+ static int ovl_fsync(struct file *file, loff_t start, loff_t end, int datasync)
+ {
+       struct fd real;
+@@ -653,7 +698,7 @@ const struct file_operations ovl_file_op
+       .unlocked_ioctl = ovl_ioctl,
+       .compat_ioctl   = ovl_compat_ioctl,
+       .splice_read    = generic_file_splice_read,
+-      .splice_write   = iter_file_splice_write,
++      .splice_write   = ovl_splice_write,
+       .copy_file_range        = ovl_copy_file_range,
+       .remap_file_range       = ovl_remap_file_range,
index 6d0b2699b333f5b00209fd2ccefeff372a5734da..f0ab36b87e7154db443e0f07b6b80a8183ae73dc 100644 (file)
@@ -339,3 +339,5 @@ parisc-fix-set_fixmap-on-pa1.x-cpus.patch
 irqchip-sifive-plic-fixup-eoi-failed-when-masked.patch
 f2fs-should-use-gfp_nofs-for-directory-inodes.patch
 net-neigh-enable-state-migration-between-nud_permane.patch
+9p-net-fix-missing-error-check-in-p9_check_errors.patch
+ovl-fix-deadlock-in-splice-write.patch