From: Greg Kroah-Hartman Date: Mon, 18 May 2020 08:12:17 +0000 (+0200) Subject: 5.6-stable patches X-Git-Tag: v4.4.224~34 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=f02877bc2259a2570a86c03151db1dfef3880bc3;p=thirdparty%2Fkernel%2Fstable-queue.git 5.6-stable patches added patches: bootconfig-fix-to-prevent-warning-message-if-no-bootconfig-option.patch bootconfig-fix-to-remove-bootconfig-data-from-initrd-while-boot.patch usb-usbfs-correct-kernel-user-page-attribute-mismatch.patch usb-usbfs-fix-mmap-dma-mismatch.patch --- diff --git a/queue-5.6/bootconfig-fix-to-prevent-warning-message-if-no-bootconfig-option.patch b/queue-5.6/bootconfig-fix-to-prevent-warning-message-if-no-bootconfig-option.patch new file mode 100644 index 00000000000..b0611181dd4 --- /dev/null +++ b/queue-5.6/bootconfig-fix-to-prevent-warning-message-if-no-bootconfig-option.patch @@ -0,0 +1,65 @@ +From 611d0a95d46b0977a530b4d538948c69d447b001 Mon Sep 17 00:00:00 2001 +From: Masami Hiramatsu +Date: Mon, 11 May 2020 10:39:24 +0900 +Subject: bootconfig: Fix to prevent warning message if no bootconfig option + +From: Masami Hiramatsu + +commit 611d0a95d46b0977a530b4d538948c69d447b001 upstream. + +Commit de462e5f1071 ("bootconfig: Fix to remove bootconfig +data from initrd while boot") causes a cosmetic regression +on dmesg, which warns "no bootconfig data" message without +bootconfig cmdline option. + +Fix setup_boot_config() by moving no bootconfig check after +commandline option check. + +Link: http://lkml.kernel.org/r/9b1ba335-071d-c983-89a4-2677b522dcc8@molgen.mpg.de +Link: http://lkml.kernel.org/r/158916116468.21787.14558782332170588206.stgit@devnote2 + +Fixes: de462e5f1071 ("bootconfig: Fix to remove bootconfig data from initrd while boot") +Reported-by: Paul Menzel +Reviewed-by: Paul Menzel +Signed-off-by: Masami Hiramatsu +Signed-off-by: Steven Rostedt (VMware) +Signed-off-by: Greg Kroah-Hartman + +--- + init/main.c | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +--- a/init/main.c ++++ b/init/main.c +@@ -398,9 +398,8 @@ static void __init setup_boot_config(con + char *data, *copy; + int ret; + ++ /* Cut out the bootconfig data even if we have no bootconfig option */ + data = get_boot_config_from_initrd(&size, &csum); +- if (!data) +- goto not_found; + + strlcpy(tmp_cmdline, boot_command_line, COMMAND_LINE_SIZE); + parse_args("bootconfig", tmp_cmdline, NULL, 0, 0, 0, NULL, +@@ -409,6 +408,11 @@ static void __init setup_boot_config(con + if (!bootconfig_found) + return; + ++ if (!data) { ++ pr_err("'bootconfig' found on command line, but no bootconfig found\n"); ++ return; ++ } ++ + if (size >= XBC_DATA_MAX) { + pr_err("bootconfig size %d greater than max size %d\n", + size, XBC_DATA_MAX); +@@ -440,8 +444,6 @@ static void __init setup_boot_config(con + extra_init_args = xbc_make_cmdline("init"); + } + return; +-not_found: +- pr_err("'bootconfig' found on command line, but no bootconfig found\n"); + } + + #else diff --git a/queue-5.6/bootconfig-fix-to-remove-bootconfig-data-from-initrd-while-boot.patch b/queue-5.6/bootconfig-fix-to-remove-bootconfig-data-from-initrd-while-boot.patch new file mode 100644 index 00000000000..91c3f6de1ad --- /dev/null +++ b/queue-5.6/bootconfig-fix-to-remove-bootconfig-data-from-initrd-while-boot.patch @@ -0,0 +1,147 @@ +From de462e5f10718517bacf2f84c8aa2804567ef7df Mon Sep 17 00:00:00 2001 +From: Masami Hiramatsu +Date: Sun, 26 Apr 2020 15:53:30 +0900 +Subject: bootconfig: Fix to remove bootconfig data from initrd while boot + +From: Masami Hiramatsu + +commit de462e5f10718517bacf2f84c8aa2804567ef7df upstream. + +If there is a bootconfig data in the tail of initrd/initramfs, +initrd image sanity check caused an error while decompression +stage as follows. + +[ 0.883882] Unpacking initramfs... +[ 2.696429] Initramfs unpacking failed: invalid magic at start of compressed archive + +This error will be ignored if CONFIG_BLK_DEV_RAM=n, +but CONFIG_BLK_DEV_RAM=y the kernel failed to mount rootfs +and causes a panic. + +To fix this issue, shrink down the initrd_end for removing +tailing bootconfig data while boot the kernel. + +Link: http://lkml.kernel.org/r/158788401014.24243.17424755854115077915.stgit@devnote2 + +Cc: Borislav Petkov +Cc: Kees Cook +Cc: Ingo Molnar +Cc: Andrew Morton +Cc: stable@vger.kernel.org +Fixes: 7684b8582c24 ("bootconfig: Load boot config from the tail of initrd") +Signed-off-by: Masami Hiramatsu +Signed-off-by: Steven Rostedt (VMware) +Signed-off-by: Greg Kroah-Hartman + +--- + init/main.c | 69 +++++++++++++++++++++++++++++++++++++++++++++--------------- + 1 file changed, 52 insertions(+), 17 deletions(-) + +--- a/init/main.c ++++ b/init/main.c +@@ -257,6 +257,47 @@ static int __init loglevel(char *str) + + early_param("loglevel", loglevel); + ++#ifdef CONFIG_BLK_DEV_INITRD ++static void * __init get_boot_config_from_initrd(u32 *_size, u32 *_csum) ++{ ++ u32 size, csum; ++ char *data; ++ u32 *hdr; ++ ++ if (!initrd_end) ++ return NULL; ++ ++ data = (char *)initrd_end - BOOTCONFIG_MAGIC_LEN; ++ if (memcmp(data, BOOTCONFIG_MAGIC, BOOTCONFIG_MAGIC_LEN)) ++ return NULL; ++ ++ hdr = (u32 *)(data - 8); ++ size = hdr[0]; ++ csum = hdr[1]; ++ ++ data = ((void *)hdr) - size; ++ if ((unsigned long)data < initrd_start) { ++ pr_err("bootconfig size %d is greater than initrd size %ld\n", ++ size, initrd_end - initrd_start); ++ return NULL; ++ } ++ ++ /* Remove bootconfig from initramfs/initrd */ ++ initrd_end = (unsigned long)data; ++ if (_size) ++ *_size = size; ++ if (_csum) ++ *_csum = csum; ++ ++ return data; ++} ++#else ++static void * __init get_boot_config_from_initrd(u32 *_size, u32 *_csum) ++{ ++ return NULL; ++} ++#endif ++ + #ifdef CONFIG_BOOT_CONFIG + + char xbc_namebuf[XBC_KEYLEN_MAX] __initdata; +@@ -355,9 +396,12 @@ static void __init setup_boot_config(con + static char tmp_cmdline[COMMAND_LINE_SIZE] __initdata; + u32 size, csum; + char *data, *copy; +- u32 *hdr; + int ret; + ++ data = get_boot_config_from_initrd(&size, &csum); ++ if (!data) ++ goto not_found; ++ + strlcpy(tmp_cmdline, boot_command_line, COMMAND_LINE_SIZE); + parse_args("bootconfig", tmp_cmdline, NULL, 0, 0, 0, NULL, + bootconfig_params); +@@ -365,27 +409,12 @@ static void __init setup_boot_config(con + if (!bootconfig_found) + return; + +- if (!initrd_end) +- goto not_found; +- +- data = (char *)initrd_end - BOOTCONFIG_MAGIC_LEN; +- if (memcmp(data, BOOTCONFIG_MAGIC, BOOTCONFIG_MAGIC_LEN)) +- goto not_found; +- +- hdr = (u32 *)(data - 8); +- size = hdr[0]; +- csum = hdr[1]; +- + if (size >= XBC_DATA_MAX) { + pr_err("bootconfig size %d greater than max size %d\n", + size, XBC_DATA_MAX); + return; + } + +- data = ((void *)hdr) - size; +- if ((unsigned long)data < initrd_start) +- goto not_found; +- + if (boot_config_checksum((unsigned char *)data, size) != csum) { + pr_err("bootconfig checksum failed\n"); + return; +@@ -414,8 +443,14 @@ static void __init setup_boot_config(con + not_found: + pr_err("'bootconfig' found on command line, but no bootconfig found\n"); + } ++ + #else +-#define setup_boot_config(cmdline) do { } while (0) ++ ++static void __init setup_boot_config(const char *cmdline) ++{ ++ /* Remove bootconfig data from initrd */ ++ get_boot_config_from_initrd(NULL, NULL); ++} + + static int __init warn_bootconfig(char *str) + { diff --git a/queue-5.6/series b/queue-5.6/series index ee97ba36d38..23da92a3ebb 100644 --- a/queue-5.6/series +++ b/queue-5.6/series @@ -131,3 +131,7 @@ gcc-10-disable-restrict-warning-for-now.patch gcc-10-warnings-fix-low-hanging-fruit.patch gcc-10-mark-more-functions-__init-to-avoid-section-mismatch-warnings.patch gcc-10-avoid-shadowing-standard-library-free-in-crypto.patch +bootconfig-fix-to-remove-bootconfig-data-from-initrd-while-boot.patch +bootconfig-fix-to-prevent-warning-message-if-no-bootconfig-option.patch +usb-usbfs-correct-kernel-user-page-attribute-mismatch.patch +usb-usbfs-fix-mmap-dma-mismatch.patch diff --git a/queue-5.6/usb-usbfs-correct-kernel-user-page-attribute-mismatch.patch b/queue-5.6/usb-usbfs-correct-kernel-user-page-attribute-mismatch.patch new file mode 100644 index 00000000000..1978b516bc3 --- /dev/null +++ b/queue-5.6/usb-usbfs-correct-kernel-user-page-attribute-mismatch.patch @@ -0,0 +1,61 @@ +From 2bef9aed6f0e22391c8d4570749b1acc9bc3981e Mon Sep 17 00:00:00 2001 +From: Jeremy Linton +Date: Mon, 4 May 2020 15:13:48 -0500 +Subject: usb: usbfs: correct kernel->user page attribute mismatch + +From: Jeremy Linton + +commit 2bef9aed6f0e22391c8d4570749b1acc9bc3981e upstream. + +On some architectures (e.g. arm64) requests for +IO coherent memory may use non-cachable attributes if +the relevant device isn't cache coherent. If these +pages are then remapped into userspace as cacheable, +they may not be coherent with the non-cacheable mappings. + +In particular this happens with libusb, when it attempts +to create zero-copy buffers for use by rtl-sdr +(https://github.com/osmocom/rtl-sdr/). On low end arm +devices with non-coherent USB ports, the application will +be unexpectedly killed, while continuing to work fine on +arm machines with coherent USB controllers. + +This bug has been discovered/reported a few times over +the last few years. In the case of rtl-sdr a compile time +option to enable/disable zero copy was implemented to +work around it. + +Rather than relaying on application specific workarounds, +dma_mmap_coherent() can be used instead of remap_pfn_range(). +The page cache/etc attributes will then be correctly set in +userspace to match the kernel mapping. + +Signed-off-by: Jeremy Linton +Cc: stable +Link: https://lore.kernel.org/r/20200504201348.1183246-1-jeremy.linton@arm.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/core/devio.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +--- a/drivers/usb/core/devio.c ++++ b/drivers/usb/core/devio.c +@@ -217,6 +217,7 @@ static int usbdev_mmap(struct file *file + { + struct usb_memory *usbm = NULL; + struct usb_dev_state *ps = file->private_data; ++ struct usb_hcd *hcd = bus_to_hcd(ps->dev->bus); + size_t size = vma->vm_end - vma->vm_start; + void *mem; + unsigned long flags; +@@ -250,9 +251,7 @@ static int usbdev_mmap(struct file *file + usbm->vma_use_count = 1; + INIT_LIST_HEAD(&usbm->memlist); + +- if (remap_pfn_range(vma, vma->vm_start, +- virt_to_phys(usbm->mem) >> PAGE_SHIFT, +- size, vma->vm_page_prot) < 0) { ++ if (dma_mmap_coherent(hcd->self.sysdev, vma, mem, dma_handle, size)) { + dec_usb_memory_use_count(usbm, &usbm->vma_use_count); + return -EAGAIN; + } diff --git a/queue-5.6/usb-usbfs-fix-mmap-dma-mismatch.patch b/queue-5.6/usb-usbfs-fix-mmap-dma-mismatch.patch new file mode 100644 index 00000000000..c9fb94f35b5 --- /dev/null +++ b/queue-5.6/usb-usbfs-fix-mmap-dma-mismatch.patch @@ -0,0 +1,59 @@ +From a0e710a7def471b8eb779ff551fc27701da49599 Mon Sep 17 00:00:00 2001 +From: Greg Kroah-Hartman +Date: Thu, 14 May 2020 13:27:11 +0200 +Subject: USB: usbfs: fix mmap dma mismatch + +From: Greg Kroah-Hartman + +commit a0e710a7def471b8eb779ff551fc27701da49599 upstream. + +In commit 2bef9aed6f0e ("usb: usbfs: correct kernel->user page attribute +mismatch") we switched from always calling remap_pfn_range() to call +dma_mmap_coherent() to handle issues with systems with non-coherent USB host +controller drivers. Unfortunatly, as syzbot quickly told us, not all the world +is host controllers with DMA support, so we need to check what host controller +we are attempting to talk to before doing this type of allocation. + +Thanks to Christoph for the quick idea of how to fix this. + +Fixes: 2bef9aed6f0e ("usb: usbfs: correct kernel->user page attribute mismatch") +Cc: Christoph Hellwig +Cc: Hillf Danton +Cc: Thomas Gleixner +Cc: Jeremy Linton +Cc: stable +Reported-by: syzbot+353be47c9ce21b68b7ed@syzkaller.appspotmail.com +Reviewed-by: Jeremy Linton +Reviewed-by: Christoph Hellwig +Link: https://lore.kernel.org/r/20200514112711.1858252-1-gregkh@linuxfoundation.org +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/core/devio.c | 16 +++++++++++++--- + 1 file changed, 13 insertions(+), 3 deletions(-) + +--- a/drivers/usb/core/devio.c ++++ b/drivers/usb/core/devio.c +@@ -251,9 +251,19 @@ static int usbdev_mmap(struct file *file + usbm->vma_use_count = 1; + INIT_LIST_HEAD(&usbm->memlist); + +- if (dma_mmap_coherent(hcd->self.sysdev, vma, mem, dma_handle, size)) { +- dec_usb_memory_use_count(usbm, &usbm->vma_use_count); +- return -EAGAIN; ++ if (hcd->localmem_pool || !hcd_uses_dma(hcd)) { ++ if (remap_pfn_range(vma, vma->vm_start, ++ virt_to_phys(usbm->mem) >> PAGE_SHIFT, ++ size, vma->vm_page_prot) < 0) { ++ dec_usb_memory_use_count(usbm, &usbm->vma_use_count); ++ return -EAGAIN; ++ } ++ } else { ++ if (dma_mmap_coherent(hcd->self.sysdev, vma, mem, dma_handle, ++ size)) { ++ dec_usb_memory_use_count(usbm, &usbm->vma_use_count); ++ return -EAGAIN; ++ } + } + + vma->vm_flags |= VM_IO;