From: Greg Kroah-Hartman Date: Sun, 8 Sep 2024 11:31:39 +0000 (+0200) Subject: 4.19-stable patches X-Git-Tag: v4.19.322~109 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=6ddbe8c6559261a86af4a6fa195c6725165e7c1e;p=thirdparty%2Fkernel%2Fstable-queue.git 4.19-stable patches added patches: fuse-use-unsigned-type-for-getxattr-listxattr-size-truncation.patch mmc-dw_mmc-fix-idmac-operation-with-pages-bigger-than-4k.patch --- 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 index 00000000000..cc6c7caf213 --- /dev/null +++ b/queue-4.19/fuse-use-unsigned-type-for-getxattr-listxattr-size-truncation.patch @@ -0,0 +1,68 @@ +From b18915248a15eae7d901262f108d6ff0ffb4ffc1 Mon Sep 17 00:00:00 2001 +From: Jann Horn +Date: Mon, 19 Aug 2024 19:52:30 +0200 +Subject: fuse: use unsigned type for getxattr/listxattr size truncation + +From: Jann Horn + +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 +Signed-off-by: Miklos Szeredi +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..66638b7aa29 --- /dev/null +++ b/queue-4.19/mmc-dw_mmc-fix-idmac-operation-with-pages-bigger-than-4k.patch @@ -0,0 +1,96 @@ +From 8396c793ffdf28bb8aee7cfe0891080f8cab7890 Mon Sep 17 00:00:00 2001 +From: Sam Protsenko +Date: Wed, 6 Mar 2024 17:20:52 -0600 +Subject: mmc: dw_mmc: Fix IDMAC operation with pages bigger than 4K + +From: Sam Protsenko + +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 +Reported-by: Linux Kernel Functional Testing +Closes: https://lore.kernel.org/all/CA+G9fYtddf2Fd3be+YShHP6CmSDNcn0ptW8qg+stUKW+Cn0rjQ@mail.gmail.com/ +Signed-off-by: Sam Protsenko +Cc: stable@vger.kernel.org +Link: https://lore.kernel.org/r/20240306232052.21317-1-semen.protsenko@linaro.org +Signed-off-by: Ulf Hansson +Signed-off-by: Greg Kroah-Hartman +--- + 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; diff --git a/queue-4.19/series b/queue-4.19/series index cac3fe4cffe..2d553b17b09 100644 --- a/queue-4.19/series +++ b/queue-4.19/series @@ -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