]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 7 Dec 2019 12:25:27 +0000 (13:25 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 7 Dec 2019 12:25:27 +0000 (13:25 +0100)
added patches:
fuse-fix-leak-of-fuse_io_priv.patch
fuse-verify-attributes.patch
fuse-verify-nlink.patch
fuse-verify-write-return.patch
io_uring-fix-dead-hung-for-non-iter-fixed-rw.patch
io_uring-transform-send-recvmsg-erestartsys-to-eintr.patch
mwifiex-re-work-support-for-sdio-hw-reset.patch

queue-5.4/fuse-fix-leak-of-fuse_io_priv.patch [new file with mode: 0644]
queue-5.4/fuse-verify-attributes.patch [new file with mode: 0644]
queue-5.4/fuse-verify-nlink.patch [new file with mode: 0644]
queue-5.4/fuse-verify-write-return.patch [new file with mode: 0644]
queue-5.4/io_uring-fix-dead-hung-for-non-iter-fixed-rw.patch [new file with mode: 0644]
queue-5.4/io_uring-transform-send-recvmsg-erestartsys-to-eintr.patch [new file with mode: 0644]
queue-5.4/mwifiex-re-work-support-for-sdio-hw-reset.patch [new file with mode: 0644]
queue-5.4/series

diff --git a/queue-5.4/fuse-fix-leak-of-fuse_io_priv.patch b/queue-5.4/fuse-fix-leak-of-fuse_io_priv.patch
new file mode 100644 (file)
index 0000000..330a98d
--- /dev/null
@@ -0,0 +1,46 @@
+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,
diff --git a/queue-5.4/fuse-verify-attributes.patch b/queue-5.4/fuse-verify-attributes.patch
new file mode 100644 (file)
index 0000000..bb71166
--- /dev/null
@@ -0,0 +1,124 @@
+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);
diff --git a/queue-5.4/fuse-verify-nlink.patch b/queue-5.4/fuse-verify-nlink.patch
new file mode 100644 (file)
index 0000000..706a2ca
--- /dev/null
@@ -0,0 +1,32 @@
+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);
diff --git a/queue-5.4/fuse-verify-write-return.patch b/queue-5.4/fuse-verify-write-return.patch
new file mode 100644 (file)
index 0000000..9ba1d64
--- /dev/null
@@ -0,0 +1,31 @@
+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;
diff --git a/queue-5.4/io_uring-fix-dead-hung-for-non-iter-fixed-rw.patch b/queue-5.4/io_uring-fix-dead-hung-for-non-iter-fixed-rw.patch
new file mode 100644 (file)
index 0000000..6762cab
--- /dev/null
@@ -0,0 +1,60 @@
+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;
diff --git a/queue-5.4/io_uring-transform-send-recvmsg-erestartsys-to-eintr.patch b/queue-5.4/io_uring-transform-send-recvmsg-erestartsys-to-eintr.patch
new file mode 100644 (file)
index 0000000..896cd29
--- /dev/null
@@ -0,0 +1,31 @@
+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);
diff --git a/queue-5.4/mwifiex-re-work-support-for-sdio-hw-reset.patch b/queue-5.4/mwifiex-re-work-support-for-sdio-hw-reset.patch
new file mode 100644 (file)
index 0000000..b0e3051
--- /dev/null
@@ -0,0 +1,137 @@
+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 */
index 8d417fb02c976dd22f57df9b6dab565f29fcd628..217d77483fa1b1e76e508e2871e4e9bad94053b6 100644 (file)
@@ -16,3 +16,10 @@ serial-serial_core-perform-null-checks-for-break_ctl-ops.patch
 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