]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.19-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 8 Sep 2024 11:31:39 +0000 (13:31 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 8 Sep 2024 11:31:39 +0000 (13:31 +0200)
added patches:
fuse-use-unsigned-type-for-getxattr-listxattr-size-truncation.patch
mmc-dw_mmc-fix-idmac-operation-with-pages-bigger-than-4k.patch

queue-4.19/fuse-use-unsigned-type-for-getxattr-listxattr-size-truncation.patch [new file with mode: 0644]
queue-4.19/mmc-dw_mmc-fix-idmac-operation-with-pages-bigger-than-4k.patch [new file with mode: 0644]
queue-4.19/series

diff --git a/queue-4.19/fuse-use-unsigned-type-for-getxattr-listxattr-size-truncation.patch b/queue-4.19/fuse-use-unsigned-type-for-getxattr-listxattr-size-truncation.patch
new file mode 100644 (file)
index 0000000..cc6c7ca
--- /dev/null
@@ -0,0 +1,68 @@
+From b18915248a15eae7d901262f108d6ff0ffb4ffc1 Mon Sep 17 00:00:00 2001
+From: Jann Horn <jannh@google.com>
+Date: Mon, 19 Aug 2024 19:52:30 +0200
+Subject: fuse: use unsigned type for getxattr/listxattr size truncation
+
+From: Jann Horn <jannh@google.com>
+
+commit b18915248a15eae7d901262f108d6ff0ffb4ffc1 upstream.
+
+The existing code uses min_t(ssize_t, outarg.size, XATTR_LIST_MAX) when
+parsing the FUSE daemon's response to a zero-length getxattr/listxattr
+request.
+On 32-bit kernels, where ssize_t and outarg.size are the same size, this is
+wrong: The min_t() will pass through any size values that are negative when
+interpreted as signed.
+fuse_listxattr() will then return this userspace-supplied negative value,
+which callers will treat as an error value.
+
+This kind of bug pattern can lead to fairly bad security bugs because of
+how error codes are used in the Linux kernel. If a caller were to convert
+the numeric error into an error pointer, like so:
+
+    struct foo *func(...) {
+      int len = fuse_getxattr(..., NULL, 0);
+      if (len < 0)
+        return ERR_PTR(len);
+      ...
+    }
+
+then it would end up returning this userspace-supplied negative value cast
+to a pointer - but the caller of this function wouldn't recognize it as an
+error pointer (IS_ERR_VALUE() only detects values in the narrow range in
+which legitimate errno values are), and so it would just be treated as a
+kernel pointer.
+
+I think there is at least one theoretical codepath where this could happen,
+but that path would involve virtio-fs with submounts plus some weird
+SELinux configuration, so I think it's probably not a concern in practice.
+
+Cc: stable@vger.kernel.org # v4.9
+Fixes: 63401ccdb2ca ("fuse: limit xattr returned size")
+Signed-off-by: Jann Horn <jannh@google.com>
+Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/fuse/xattr.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/fs/fuse/xattr.c
++++ b/fs/fuse/xattr.c
+@@ -79,7 +79,7 @@ ssize_t fuse_getxattr(struct inode *inod
+       }
+       ret = fuse_simple_request(fc, &args);
+       if (!ret && !size)
+-              ret = min_t(ssize_t, outarg.size, XATTR_SIZE_MAX);
++              ret = min_t(size_t, outarg.size, XATTR_SIZE_MAX);
+       if (ret == -ENOSYS) {
+               fc->no_getxattr = 1;
+               ret = -EOPNOTSUPP;
+@@ -141,7 +141,7 @@ ssize_t fuse_listxattr(struct dentry *en
+       }
+       ret = fuse_simple_request(fc, &args);
+       if (!ret && !size)
+-              ret = min_t(ssize_t, outarg.size, XATTR_LIST_MAX);
++              ret = min_t(size_t, outarg.size, XATTR_LIST_MAX);
+       if (ret > 0 && size)
+               ret = fuse_verify_xattr_list(list, ret);
+       if (ret == -ENOSYS) {
diff --git a/queue-4.19/mmc-dw_mmc-fix-idmac-operation-with-pages-bigger-than-4k.patch b/queue-4.19/mmc-dw_mmc-fix-idmac-operation-with-pages-bigger-than-4k.patch
new file mode 100644 (file)
index 0000000..66638b7
--- /dev/null
@@ -0,0 +1,96 @@
+From 8396c793ffdf28bb8aee7cfe0891080f8cab7890 Mon Sep 17 00:00:00 2001
+From: Sam Protsenko <semen.protsenko@linaro.org>
+Date: Wed, 6 Mar 2024 17:20:52 -0600
+Subject: mmc: dw_mmc: Fix IDMAC operation with pages bigger than 4K
+
+From: Sam Protsenko <semen.protsenko@linaro.org>
+
+commit 8396c793ffdf28bb8aee7cfe0891080f8cab7890 upstream.
+
+Commit 616f87661792 ("mmc: pass queue_limits to blk_mq_alloc_disk") [1]
+revealed the long living issue in dw_mmc.c driver, existing since the
+time when it was first introduced in commit f95f3850f7a9 ("mmc: dw_mmc:
+Add Synopsys DesignWare mmc host driver."), also making kernel boot
+broken on platforms using dw_mmc driver with 16K or 64K pages enabled,
+with this message in dmesg:
+
+    mmcblk: probe of mmc0:0001 failed with error -22
+
+That's happening because mmc_blk_probe() fails when it calls
+blk_validate_limits() consequently, which returns the error due to
+failed max_segment_size check in this code:
+
+    /*
+     * The maximum segment size has an odd historic 64k default that
+     * drivers probably should override.  Just like the I/O size we
+     * require drivers to at least handle a full page per segment.
+     */
+    ...
+    if (WARN_ON_ONCE(lim->max_segment_size < PAGE_SIZE))
+        return -EINVAL;
+
+In case when IDMAC (Internal DMA Controller) is used, dw_mmc.c always
+sets .max_seg_size to 4 KiB:
+
+    mmc->max_seg_size = 0x1000;
+
+The comment in the code above explains why it's incorrect. Arnd
+suggested setting .max_seg_size to .max_req_size to fix it, which is
+also what some other drivers are doing:
+
+   $ grep -rl 'max_seg_size.*=.*max_req_size' drivers/mmc/host/ | \
+     wc -l
+   18
+
+This change is not only fixing the boot with 16K/64K pages, but also
+leads to a better MMC performance. The linear write performance was
+tested on E850-96 board (eMMC only), before commit [1] (where it's
+possible to boot with 16K/64K pages without this fix, to be able to do
+a comparison). It was tested with this command:
+
+    # dd if=/dev/zero of=somefile bs=1M count=500 oflag=sync
+
+Test results are as follows:
+
+  - 4K pages,  .max_seg_size = 4 KiB:                   94.2 MB/s
+  - 4K pages,  .max_seg_size = .max_req_size = 512 KiB: 96.9 MB/s
+  - 16K pages, .max_seg_size = 4 KiB:                   126 MB/s
+  - 16K pages, .max_seg_size = .max_req_size = 2 MiB:   128 MB/s
+  - 64K pages, .max_seg_size = 4 KiB:                   138 MB/s
+  - 64K pages, .max_seg_size = .max_req_size = 8 MiB:   138 MB/s
+
+Unfortunately, SD card controller is not enabled in E850-96 yet, so it
+wasn't possible for me to run the test on some cheap SD cards to check
+this patch's impact on those. But it's possible that this change might
+also reduce the writes count, thus improving SD/eMMC longevity.
+
+All credit for the analysis and the suggested solution goes to Arnd.
+
+[1] https://lore.kernel.org/all/20240215070300.2200308-18-hch@lst.de/
+
+Fixes: f95f3850f7a9 ("mmc: dw_mmc: Add Synopsys DesignWare mmc host driver.")
+Suggested-by: Arnd Bergmann <arnd@arndb.de>
+Reported-by: Linux Kernel Functional Testing <lkft@linaro.org>
+Closes: https://lore.kernel.org/all/CA+G9fYtddf2Fd3be+YShHP6CmSDNcn0ptW8qg+stUKW+Cn0rjQ@mail.gmail.com/
+Signed-off-by: Sam Protsenko <semen.protsenko@linaro.org>
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/r/20240306232052.21317-1-semen.protsenko@linaro.org
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/mmc/host/dw_mmc.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/mmc/host/dw_mmc.c
++++ b/drivers/mmc/host/dw_mmc.c
+@@ -2857,8 +2857,8 @@ static int dw_mci_init_slot(struct dw_mc
+       if (host->use_dma == TRANS_MODE_IDMAC) {
+               mmc->max_segs = host->ring_size;
+               mmc->max_blk_size = 65535;
+-              mmc->max_seg_size = 0x1000;
+-              mmc->max_req_size = mmc->max_seg_size * host->ring_size;
++              mmc->max_req_size = DW_MCI_DESC_DATA_LENGTH * host->ring_size;
++              mmc->max_seg_size = mmc->max_req_size;
+               mmc->max_blk_count = mmc->max_req_size / 512;
+       } else if (host->use_dma == TRANS_MODE_EDMAC) {
+               mmc->max_segs = 64;
index cac3fe4cffefa4cab4848f0caf13082be2446aad..2d553b17b098ad5764aa3d3df051e477f191b3ea 100644 (file)
@@ -18,3 +18,5 @@ alsa-usb-audio-fix-gpf-in-snd_usb_pipe_sanity_check.patch
 sch-netem-fix-use-after-free-in-netem_dequeue.patch
 alsa-hda-conexant-add-pincfg-quirk-to-enable-top-speakers-on-sirius-devices.patch
 ata-libata-fix-memory-leak-for-error-path-in-ata_host_alloc.patch
+mmc-dw_mmc-fix-idmac-operation-with-pages-bigger-than-4k.patch
+fuse-use-unsigned-type-for-getxattr-listxattr-size-truncation.patch