--- /dev/null
+From f1ebdeffc6f325e30e0ddb9f7a70f1370fa4b851 Mon Sep 17 00:00:00 2001
+From: Miklos Szeredi <mszeredi@redhat.com>
+Date: Mon, 25 Nov 2019 20:48:46 +0100
+Subject: fuse: fix leak of fuse_io_priv
+
+From: Miklos Szeredi <mszeredi@redhat.com>
+
+commit f1ebdeffc6f325e30e0ddb9f7a70f1370fa4b851 upstream.
+
+exit_aio() is sometimes stuck in wait_for_completion() after aio is issued
+with direct IO and the task receives a signal.
+
+The reason is failure to call ->ki_complete() due to a leaked reference to
+fuse_io_priv. This happens in fuse_async_req_send() if
+fuse_simple_background() returns an error (e.g. -EINTR).
+
+In this case the error value is propagated via io->err, so return success
+to not confuse callers.
+
+This issue is tracked as a virtio-fs issue:
+https://gitlab.com/virtio-fs/qemu/issues/14
+
+Reported-by: Masayoshi Mizuma <m.mizuma@jp.fujitsu.com>
+Fixes: 45ac96ed7c36 ("fuse: convert direct_io to simple api")
+Cc: <stable@vger.kernel.org> # v5.4
+Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/fuse/file.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/fs/fuse/file.c
++++ b/fs/fuse/file.c
+@@ -713,8 +713,10 @@ static ssize_t fuse_async_req_send(struc
+
+ ia->ap.args.end = fuse_aio_complete_req;
+ err = fuse_simple_background(fc, &ia->ap.args, GFP_KERNEL);
++ if (err)
++ fuse_aio_complete_req(fc, &ia->ap.args, err);
+
+- return err ?: num_bytes;
++ return num_bytes;
+ }
+
+ static ssize_t fuse_send_read(struct fuse_io_args *ia, loff_t pos, size_t count,
--- /dev/null
+From eb59bd17d2fa6e5e84fba61a5ebdea984222e6d5 Mon Sep 17 00:00:00 2001
+From: Miklos Szeredi <mszeredi@redhat.com>
+Date: Tue, 12 Nov 2019 11:49:04 +0100
+Subject: fuse: verify attributes
+
+From: Miklos Szeredi <mszeredi@redhat.com>
+
+commit eb59bd17d2fa6e5e84fba61a5ebdea984222e6d5 upstream.
+
+If a filesystem returns negative inode sizes, future reads on the file were
+causing the cpu to spin on truncate_pagecache.
+
+Create a helper to validate the attributes. This now does two things:
+
+ - check the file mode
+ - check if the file size fits in i_size without overflowing
+
+Reported-by: Arijit Banerjee <arijit@rubrik.com>
+Fixes: d8a5ba45457e ("[PATCH] FUSE - core")
+Cc: <stable@vger.kernel.org> # v2.6.14
+Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/fuse/dir.c | 22 ++++++++++++++++------
+ fs/fuse/fuse_i.h | 2 ++
+ fs/fuse/readdir.c | 2 +-
+ 3 files changed, 19 insertions(+), 7 deletions(-)
+
+--- a/fs/fuse/dir.c
++++ b/fs/fuse/dir.c
+@@ -248,7 +248,8 @@ static int fuse_dentry_revalidate(struct
+ kfree(forget);
+ if (ret == -ENOMEM)
+ goto out;
+- if (ret || (outarg.attr.mode ^ inode->i_mode) & S_IFMT)
++ if (ret || fuse_invalid_attr(&outarg.attr) ||
++ (outarg.attr.mode ^ inode->i_mode) & S_IFMT)
+ goto invalid;
+
+ forget_all_cached_acls(inode);
+@@ -319,6 +320,12 @@ int fuse_valid_type(int m)
+ S_ISBLK(m) || S_ISFIFO(m) || S_ISSOCK(m);
+ }
+
++bool fuse_invalid_attr(struct fuse_attr *attr)
++{
++ return !fuse_valid_type(attr->mode) ||
++ attr->size > LLONG_MAX;
++}
++
+ int fuse_lookup_name(struct super_block *sb, u64 nodeid, const struct qstr *name,
+ struct fuse_entry_out *outarg, struct inode **inode)
+ {
+@@ -350,7 +357,7 @@ int fuse_lookup_name(struct super_block
+ err = -EIO;
+ if (!outarg->nodeid)
+ goto out_put_forget;
+- if (!fuse_valid_type(outarg->attr.mode))
++ if (fuse_invalid_attr(&outarg->attr))
+ goto out_put_forget;
+
+ *inode = fuse_iget(sb, outarg->nodeid, outarg->generation,
+@@ -475,7 +482,8 @@ static int fuse_create_open(struct inode
+ goto out_free_ff;
+
+ err = -EIO;
+- if (!S_ISREG(outentry.attr.mode) || invalid_nodeid(outentry.nodeid))
++ if (!S_ISREG(outentry.attr.mode) || invalid_nodeid(outentry.nodeid) ||
++ fuse_invalid_attr(&outentry.attr))
+ goto out_free_ff;
+
+ ff->fh = outopen.fh;
+@@ -583,7 +591,7 @@ static int create_new_entry(struct fuse_
+ goto out_put_forget_req;
+
+ err = -EIO;
+- if (invalid_nodeid(outarg.nodeid))
++ if (invalid_nodeid(outarg.nodeid) || fuse_invalid_attr(&outarg.attr))
+ goto out_put_forget_req;
+
+ if ((outarg.attr.mode ^ mode) & S_IFMT)
+@@ -943,7 +951,8 @@ static int fuse_do_getattr(struct inode
+ args.out_args[0].value = &outarg;
+ err = fuse_simple_request(fc, &args);
+ if (!err) {
+- if ((inode->i_mode ^ outarg.attr.mode) & S_IFMT) {
++ if (fuse_invalid_attr(&outarg.attr) ||
++ (inode->i_mode ^ outarg.attr.mode) & S_IFMT) {
+ make_bad_inode(inode);
+ err = -EIO;
+ } else {
+@@ -1564,7 +1573,8 @@ int fuse_do_setattr(struct dentry *dentr
+ goto error;
+ }
+
+- if ((inode->i_mode ^ outarg.attr.mode) & S_IFMT) {
++ if (fuse_invalid_attr(&outarg.attr) ||
++ (inode->i_mode ^ outarg.attr.mode) & S_IFMT) {
+ make_bad_inode(inode);
+ err = -EIO;
+ goto error;
+--- a/fs/fuse/fuse_i.h
++++ b/fs/fuse/fuse_i.h
+@@ -989,6 +989,8 @@ void fuse_ctl_remove_conn(struct fuse_co
+ */
+ int fuse_valid_type(int m);
+
++bool fuse_invalid_attr(struct fuse_attr *attr);
++
+ /**
+ * Is current process allowed to perform filesystem operation?
+ */
+--- a/fs/fuse/readdir.c
++++ b/fs/fuse/readdir.c
+@@ -184,7 +184,7 @@ static int fuse_direntplus_link(struct f
+
+ if (invalid_nodeid(o->nodeid))
+ return -EIO;
+- if (!fuse_valid_type(o->attr.mode))
++ if (fuse_invalid_attr(&o->attr))
+ return -EIO;
+
+ fc = get_fuse_conn(dir);
--- /dev/null
+From c634da718db9b2fac201df2ae1b1b095344ce5eb Mon Sep 17 00:00:00 2001
+From: Miklos Szeredi <mszeredi@redhat.com>
+Date: Tue, 12 Nov 2019 11:49:04 +0100
+Subject: fuse: verify nlink
+
+From: Miklos Szeredi <mszeredi@redhat.com>
+
+commit c634da718db9b2fac201df2ae1b1b095344ce5eb upstream.
+
+When adding a new hard link, make sure that i_nlink doesn't overflow.
+
+Fixes: ac45d61357e8 ("fuse: fix nlink after unlink")
+Cc: <stable@vger.kernel.org> # v3.4
+Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/fuse/dir.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/fs/fuse/dir.c
++++ b/fs/fuse/dir.c
+@@ -862,7 +862,8 @@ static int fuse_link(struct dentry *entr
+
+ spin_lock(&fi->lock);
+ fi->attr_version = atomic64_inc_return(&fc->attr_version);
+- inc_nlink(inode);
++ if (likely(inode->i_nlink < UINT_MAX))
++ inc_nlink(inode);
+ spin_unlock(&fi->lock);
+ fuse_invalidate_attr(inode);
+ fuse_update_ctime(inode);
--- /dev/null
+From 8aab336b14c115c6bf1d4baeb9247e41ed9ce6de Mon Sep 17 00:00:00 2001
+From: Miklos Szeredi <mszeredi@redhat.com>
+Date: Tue, 12 Nov 2019 11:49:04 +0100
+Subject: fuse: verify write return
+
+From: Miklos Szeredi <mszeredi@redhat.com>
+
+commit 8aab336b14c115c6bf1d4baeb9247e41ed9ce6de upstream.
+
+Make sure filesystem is not returning a bogus number of bytes written.
+
+Fixes: ea9b9907b82a ("fuse: implement perform_write")
+Cc: <stable@vger.kernel.org> # v2.6.26
+Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/fuse/file.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/fs/fuse/file.c
++++ b/fs/fuse/file.c
+@@ -1098,6 +1098,8 @@ static ssize_t fuse_send_write_pages(str
+ ia->write.in.flags = fuse_write_flags(iocb);
+
+ err = fuse_simple_request(fc, &ap->args);
++ if (!err && ia->write.out.size > count)
++ err = -EIO;
+
+ offset = ap->descs[0].offset;
+ count = ia->write.out.size;
--- /dev/null
+From 311ae9e159d81a1ec1cf645daf40b39ae5a0bd84 Mon Sep 17 00:00:00 2001
+From: Pavel Begunkov <asml.silence@gmail.com>
+Date: Sun, 24 Nov 2019 11:58:24 +0300
+Subject: io_uring: fix dead-hung for non-iter fixed rw
+
+From: Pavel Begunkov <asml.silence@gmail.com>
+
+commit 311ae9e159d81a1ec1cf645daf40b39ae5a0bd84 upstream.
+
+Read/write requests to devices without implemented read/write_iter
+using fixed buffers can cause general protection fault, which totally
+hangs a machine.
+
+io_import_fixed() initialises iov_iter with bvec, but loop_rw_iter()
+accesses it as iovec, dereferencing random address.
+
+kmap() page by page in this case
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Pavel Begunkov <asml.silence@gmail.com>
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/io_uring.c | 15 ++++++++++++++-
+ 1 file changed, 14 insertions(+), 1 deletion(-)
+
+--- a/fs/io_uring.c
++++ b/fs/io_uring.c
+@@ -1351,9 +1351,19 @@ static ssize_t loop_rw_iter(int rw, stru
+ return -EAGAIN;
+
+ while (iov_iter_count(iter)) {
+- struct iovec iovec = iov_iter_iovec(iter);
++ struct iovec iovec;
+ ssize_t nr;
+
++ if (!iov_iter_is_bvec(iter)) {
++ iovec = iov_iter_iovec(iter);
++ } else {
++ /* fixed buffers import bvec */
++ iovec.iov_base = kmap(iter->bvec->bv_page)
++ + iter->iov_offset;
++ iovec.iov_len = min(iter->count,
++ iter->bvec->bv_len - iter->iov_offset);
++ }
++
+ if (rw == READ) {
+ nr = file->f_op->read(file, iovec.iov_base,
+ iovec.iov_len, &kiocb->ki_pos);
+@@ -1362,6 +1372,9 @@ static ssize_t loop_rw_iter(int rw, stru
+ iovec.iov_len, &kiocb->ki_pos);
+ }
+
++ if (iov_iter_is_bvec(iter))
++ kunmap(iter->bvec->bv_page);
++
+ if (nr < 0) {
+ if (!ret)
+ ret = nr;
--- /dev/null
+From 441cdbd5449b4923cd413d3ba748124f91388be9 Mon Sep 17 00:00:00 2001
+From: Jens Axboe <axboe@kernel.dk>
+Date: Mon, 2 Dec 2019 18:49:10 -0700
+Subject: io_uring: transform send/recvmsg() -ERESTARTSYS to -EINTR
+
+From: Jens Axboe <axboe@kernel.dk>
+
+commit 441cdbd5449b4923cd413d3ba748124f91388be9 upstream.
+
+We should never return -ERESTARTSYS to userspace, transform it into
+-EINTR.
+
+Cc: stable@vger.kernel.org # v5.3+
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/io_uring.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/fs/io_uring.c
++++ b/fs/io_uring.c
+@@ -1667,6 +1667,8 @@ static int io_send_recvmsg(struct io_kio
+ ret = fn(sock, msg, flags);
+ if (force_nonblock && ret == -EAGAIN)
+ return ret;
++ if (ret == -ERESTARTSYS)
++ ret = -EINTR;
+ }
+
+ io_cqring_add_event(req->ctx, sqe->user_data, ret);
--- /dev/null
+From cdb2256f795e8e78cc43f32d091695b127dfb4df Mon Sep 17 00:00:00 2001
+From: Ulf Hansson <ulf.hansson@linaro.org>
+Date: Fri, 25 Oct 2019 09:28:17 +0200
+Subject: mwifiex: Re-work support for SDIO HW reset
+
+From: Ulf Hansson <ulf.hansson@linaro.org>
+
+commit cdb2256f795e8e78cc43f32d091695b127dfb4df upstream.
+
+The SDIO HW reset procedure in mwifiex_sdio_card_reset_work() is broken,
+when the SDIO card is shared with another SDIO func driver. This is the
+case when the Bluetooth btmrvl driver is being used in combination with
+mwifiex. More precisely, when mwifiex_sdio_card_reset_work() runs to resets
+the SDIO card, the btmrvl driver doesn't get notified about it. Beyond that
+point, the btmrvl driver will fail to communicate with the SDIO card.
+
+This is a generic problem for SDIO func drivers sharing an SDIO card, which
+are about to be addressed in subsequent changes to the mmc core and the
+mmc_hw_reset() interface. In principle, these changes means the
+mmc_hw_reset() interface starts to return 1 if the are multiple drivers for
+the SDIO card, as to indicate to the caller that the reset needed to be
+scheduled asynchronously through a hotplug mechanism of the SDIO card.
+
+Let's prepare the mwifiex driver to support the upcoming new behaviour of
+mmc_hw_reset(), which means extending the mwifiex_sdio_card_reset_work() to
+support the asynchronous SDIO HW reset path. This also means, we need to
+allow the ->remove() callback to run, without waiting for the FW to be
+loaded. Additionally, during system suspend, mwifiex_sdio_suspend() may be
+called when a reset has been scheduled, but waiting to be executed. In this
+scenario let's simply return -EBUSY to abort the suspend process, as to
+allow the reset to be completed first.
+
+Reviewed-by: Douglas Anderson <dianders@chromium.org>
+Tested-by: Douglas Anderson <dianders@chromium.org>
+Cc: stable@vger.kernel.org # v5.4+
+Acked-by: Kalle Valo <kvalo@codeaurora.org>
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/wireless/marvell/mwifiex/main.c | 5 +++-
+ drivers/net/wireless/marvell/mwifiex/main.h | 1
+ drivers/net/wireless/marvell/mwifiex/sdio.c | 33 ++++++++++++++++++----------
+ 3 files changed, 27 insertions(+), 12 deletions(-)
+
+--- a/drivers/net/wireless/marvell/mwifiex/main.c
++++ b/drivers/net/wireless/marvell/mwifiex/main.c
+@@ -631,6 +631,7 @@ static int _mwifiex_fw_dpc(const struct
+
+ mwifiex_drv_get_driver_version(adapter, fmt, sizeof(fmt) - 1);
+ mwifiex_dbg(adapter, MSG, "driver_version = %s\n", fmt);
++ adapter->is_up = true;
+ goto done;
+
+ err_add_intf:
+@@ -1469,6 +1470,7 @@ int mwifiex_shutdown_sw(struct mwifiex_a
+ mwifiex_deauthenticate(priv, NULL);
+
+ mwifiex_uninit_sw(adapter);
++ adapter->is_up = false;
+
+ if (adapter->if_ops.down_dev)
+ adapter->if_ops.down_dev(adapter);
+@@ -1730,7 +1732,8 @@ int mwifiex_remove_card(struct mwifiex_a
+ if (!adapter)
+ return 0;
+
+- mwifiex_uninit_sw(adapter);
++ if (adapter->is_up)
++ mwifiex_uninit_sw(adapter);
+
+ if (adapter->irq_wakeup >= 0)
+ device_init_wakeup(adapter->dev, false);
+--- a/drivers/net/wireless/marvell/mwifiex/main.h
++++ b/drivers/net/wireless/marvell/mwifiex/main.h
+@@ -1017,6 +1017,7 @@ struct mwifiex_adapter {
+
+ /* For synchronizing FW initialization with device lifecycle. */
+ struct completion *fw_done;
++ bool is_up;
+
+ bool ext_scan;
+ u8 fw_api_ver;
+--- a/drivers/net/wireless/marvell/mwifiex/sdio.c
++++ b/drivers/net/wireless/marvell/mwifiex/sdio.c
+@@ -444,6 +444,9 @@ static int mwifiex_sdio_suspend(struct d
+ return 0;
+ }
+
++ if (!adapter->is_up)
++ return -EBUSY;
++
+ mwifiex_enable_wake(adapter);
+
+ /* Enable the Host Sleep */
+@@ -2220,22 +2223,30 @@ static void mwifiex_sdio_card_reset_work
+ struct sdio_func *func = card->func;
+ int ret;
+
++ /* Prepare the adapter for the reset. */
+ mwifiex_shutdown_sw(adapter);
++ clear_bit(MWIFIEX_IFACE_WORK_DEVICE_DUMP, &card->work_flags);
++ clear_bit(MWIFIEX_IFACE_WORK_CARD_RESET, &card->work_flags);
+
+- /* power cycle the adapter */
++ /* Run a HW reset of the SDIO interface. */
+ sdio_claim_host(func);
+- mmc_hw_reset(func->card->host);
++ ret = mmc_hw_reset(func->card->host);
+ sdio_release_host(func);
+
+- /* Previous save_adapter won't be valid after this. We will cancel
+- * pending work requests.
+- */
+- clear_bit(MWIFIEX_IFACE_WORK_DEVICE_DUMP, &card->work_flags);
+- clear_bit(MWIFIEX_IFACE_WORK_CARD_RESET, &card->work_flags);
+-
+- ret = mwifiex_reinit_sw(adapter);
+- if (ret)
+- dev_err(&func->dev, "reinit failed: %d\n", ret);
++ switch (ret) {
++ case 1:
++ dev_dbg(&func->dev, "SDIO HW reset asynchronous\n");
++ complete_all(adapter->fw_done);
++ break;
++ case 0:
++ ret = mwifiex_reinit_sw(adapter);
++ if (ret)
++ dev_err(&func->dev, "reinit failed: %d\n", ret);
++ break;
++ default:
++ dev_err(&func->dev, "SDIO HW reset failed: %d\n", ret);
++ break;
++ }
+ }
+
+ /* This function read/write firmware */
serial-stm32-fix-clearing-interrupt-error-flags.patch
serial-8250_dw-avoid-double-error-messaging-when-irq-absent.patch
serial-ifx6x60-add-missed-pm_runtime_disable.patch
+mwifiex-re-work-support-for-sdio-hw-reset.patch
+io_uring-fix-dead-hung-for-non-iter-fixed-rw.patch
+io_uring-transform-send-recvmsg-erestartsys-to-eintr.patch
+fuse-fix-leak-of-fuse_io_priv.patch
+fuse-verify-nlink.patch
+fuse-verify-write-return.patch
+fuse-verify-attributes.patch