From: Sasha Levin Date: Wed, 2 Oct 2024 05:17:37 +0000 (-0400) Subject: Fixes for 4.19 X-Git-Tag: v6.6.54~44 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=a12db1f0f4b46494089f1ee104c526a014e4f696;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 4.19 Signed-off-by: Sasha Levin --- diff --git a/queue-4.19/pci-xilinx-nwl-fix-off-by-one-in-intx-irq-handler.patch b/queue-4.19/pci-xilinx-nwl-fix-off-by-one-in-intx-irq-handler.patch new file mode 100644 index 00000000000..a3b83293a44 --- /dev/null +++ b/queue-4.19/pci-xilinx-nwl-fix-off-by-one-in-intx-irq-handler.patch @@ -0,0 +1,73 @@ +From 7b44c2d6f28c89480381db98f78873be78ce8c42 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 31 May 2024 12:13:32 -0400 +Subject: PCI: xilinx-nwl: Fix off-by-one in INTx IRQ handler + +From: Sean Anderson + +[ Upstream commit 0199d2f2bd8cd97b310f7ed82a067247d7456029 ] + +MSGF_LEG_MASK is laid out with INTA in bit 0, INTB in bit 1, INTC in bit 2, +and INTD in bit 3. Hardware IRQ numbers start at 0, and we register +PCI_NUM_INTX IRQs. So to enable INTA (aka hwirq 0) we should set bit 0. +Remove the subtraction of one. + +This bug would cause INTx interrupts not to be delivered, as enabling INTB +would actually enable INTA, and enabling INTA wouldn't enable anything at +all. It is likely that this got overlooked for so long since most PCIe +hardware uses MSIs. This fixes the following UBSAN error: + + UBSAN: shift-out-of-bounds in ../drivers/pci/controller/pcie-xilinx-nwl.c:389:11 + shift exponent 18446744073709551615 is too large for 32-bit type 'int' + CPU: 1 PID: 61 Comm: kworker/u10:1 Not tainted 6.6.20+ #268 + Hardware name: xlnx,zynqmp (DT) + Workqueue: events_unbound deferred_probe_work_func + Call trace: + dump_backtrace (arch/arm64/kernel/stacktrace.c:235) + show_stack (arch/arm64/kernel/stacktrace.c:242) + dump_stack_lvl (lib/dump_stack.c:107) + dump_stack (lib/dump_stack.c:114) + __ubsan_handle_shift_out_of_bounds (lib/ubsan.c:218 lib/ubsan.c:387) + nwl_unmask_leg_irq (drivers/pci/controller/pcie-xilinx-nwl.c:389 (discriminator 1)) + irq_enable (kernel/irq/internals.h:234 kernel/irq/chip.c:170 kernel/irq/chip.c:439 kernel/irq/chip.c:432 kernel/irq/chip.c:345) + __irq_startup (kernel/irq/internals.h:239 kernel/irq/chip.c:180 kernel/irq/chip.c:250) + irq_startup (kernel/irq/chip.c:270) + __setup_irq (kernel/irq/manage.c:1800) + request_threaded_irq (kernel/irq/manage.c:2206) + pcie_pme_probe (include/linux/interrupt.h:168 drivers/pci/pcie/pme.c:348) + +Fixes: 9a181e1093af ("PCI: xilinx-nwl: Modify IRQ chip for legacy interrupts") +Link: https://lore.kernel.org/r/20240531161337.864994-3-sean.anderson@linux.dev +Signed-off-by: Sean Anderson +Signed-off-by: Bjorn Helgaas +Cc: stable@vger.kernel.org +Signed-off-by: Sasha Levin +--- + drivers/pci/controller/pcie-xilinx-nwl.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/pci/controller/pcie-xilinx-nwl.c b/drivers/pci/controller/pcie-xilinx-nwl.c +index 79d72ec8f5c36..9fde526045ec0 100644 +--- a/drivers/pci/controller/pcie-xilinx-nwl.c ++++ b/drivers/pci/controller/pcie-xilinx-nwl.c +@@ -389,7 +389,7 @@ static void nwl_mask_leg_irq(struct irq_data *data) + u32 mask; + u32 val; + +- mask = 1 << (data->hwirq - 1); ++ mask = 1 << data->hwirq; + raw_spin_lock_irqsave(&pcie->leg_mask_lock, flags); + val = nwl_bridge_readl(pcie, MSGF_LEG_MASK); + nwl_bridge_writel(pcie, (val & (~mask)), MSGF_LEG_MASK); +@@ -403,7 +403,7 @@ static void nwl_unmask_leg_irq(struct irq_data *data) + u32 mask; + u32 val; + +- mask = 1 << (data->hwirq - 1); ++ mask = 1 << data->hwirq; + raw_spin_lock_irqsave(&pcie->leg_mask_lock, flags); + val = nwl_bridge_readl(pcie, MSGF_LEG_MASK); + nwl_bridge_writel(pcie, (val | mask), MSGF_LEG_MASK); +-- +2.43.0 + diff --git a/queue-4.19/pci-xilinx-nwl-use-irq_data_get_irq_chip_data.patch b/queue-4.19/pci-xilinx-nwl-use-irq_data_get_irq_chip_data.patch new file mode 100644 index 00000000000..8e6c818bad1 --- /dev/null +++ b/queue-4.19/pci-xilinx-nwl-use-irq_data_get_irq_chip_data.patch @@ -0,0 +1,65 @@ +From 448bc5773b15229410d90bd24bc87a4732212b02 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 10 Dec 2020 20:25:54 +0100 +Subject: PCI: xilinx-nwl: Use irq_data_get_irq_chip_data() + +From: Thomas Gleixner + +[ Upstream commit e56427068a8d796bb7b8e297f2b6e947380e383f ] + +Going through a full irq descriptor lookup instead of just using the proper +helper function which provides direct access is suboptimal. + +In fact it _is_ wrong because the chip callback needs to get the chip data +which is relevant for the chip while using the irq descriptor variant +returns the irq chip data of the top level chip of a hierarchy. It does not +matter in this case because the chip is the top level chip, but that +doesn't make it more correct. + +Signed-off-by: Thomas Gleixner +Reviewed-by: Rob Herring +Cc: Bjorn Helgaas +Link: https://lore.kernel.org/r/20201210194044.364211860@linutronix.de +Stable-dep-of: 0199d2f2bd8c ("PCI: xilinx-nwl: Fix off-by-one in INTx IRQ handler") +Signed-off-by: Sasha Levin +--- + drivers/pci/controller/pcie-xilinx-nwl.c | 8 ++------ + 1 file changed, 2 insertions(+), 6 deletions(-) + +diff --git a/drivers/pci/controller/pcie-xilinx-nwl.c b/drivers/pci/controller/pcie-xilinx-nwl.c +index 4b7b906967582..79d72ec8f5c36 100644 +--- a/drivers/pci/controller/pcie-xilinx-nwl.c ++++ b/drivers/pci/controller/pcie-xilinx-nwl.c +@@ -384,13 +384,11 @@ static void nwl_pcie_msi_handler_low(struct irq_desc *desc) + + static void nwl_mask_leg_irq(struct irq_data *data) + { +- struct irq_desc *desc = irq_to_desc(data->irq); +- struct nwl_pcie *pcie; ++ struct nwl_pcie *pcie = irq_data_get_irq_chip_data(data); + unsigned long flags; + u32 mask; + u32 val; + +- pcie = irq_desc_get_chip_data(desc); + mask = 1 << (data->hwirq - 1); + raw_spin_lock_irqsave(&pcie->leg_mask_lock, flags); + val = nwl_bridge_readl(pcie, MSGF_LEG_MASK); +@@ -400,13 +398,11 @@ static void nwl_mask_leg_irq(struct irq_data *data) + + static void nwl_unmask_leg_irq(struct irq_data *data) + { +- struct irq_desc *desc = irq_to_desc(data->irq); +- struct nwl_pcie *pcie; ++ struct nwl_pcie *pcie = irq_data_get_irq_chip_data(data); + unsigned long flags; + u32 mask; + u32 val; + +- pcie = irq_desc_get_chip_data(desc); + mask = 1 << (data->hwirq - 1); + raw_spin_lock_irqsave(&pcie->leg_mask_lock, flags); + val = nwl_bridge_readl(pcie, MSGF_LEG_MASK); +-- +2.43.0 + diff --git a/queue-4.19/pps-add-an-error-check-in-parport_attach.patch b/queue-4.19/pps-add-an-error-check-in-parport_attach.patch new file mode 100644 index 00000000000..8f801069eb2 --- /dev/null +++ b/queue-4.19/pps-add-an-error-check-in-parport_attach.patch @@ -0,0 +1,65 @@ +From 33fd06ead6e961e605c1df5fba7ace543d55ad80 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 28 Aug 2024 21:18:14 +0800 +Subject: pps: add an error check in parport_attach + +From: Ma Ke + +[ Upstream commit 62c5a01a5711c8e4be8ae7b6f0db663094615d48 ] + +In parport_attach, the return value of ida_alloc is unchecked, witch leads +to the use of an invalid index value. + +To address this issue, index should be checked. When the index value is +abnormal, the device should be freed. + +Found by code review, compile tested only. + +Cc: stable@vger.kernel.org +Fixes: fb56d97df70e ("pps: client: use new parport device model") +Signed-off-by: Ma Ke +Acked-by: Rodolfo Giometti +Link: https://lore.kernel.org/r/20240828131814.3034338-1-make24@iscas.ac.cn +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/pps/clients/pps_parport.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/drivers/pps/clients/pps_parport.c b/drivers/pps/clients/pps_parport.c +index de49ae85adbeb..9710207bce7cc 100644 +--- a/drivers/pps/clients/pps_parport.c ++++ b/drivers/pps/clients/pps_parport.c +@@ -159,6 +159,9 @@ static void parport_attach(struct parport *port) + } + + index = ida_alloc(&pps_client_index, GFP_KERNEL); ++ if (index < 0) ++ goto err_free_device; ++ + memset(&pps_client_cb, 0, sizeof(pps_client_cb)); + pps_client_cb.private = device; + pps_client_cb.irq_func = parport_irq; +@@ -169,7 +172,7 @@ static void parport_attach(struct parport *port) + index); + if (!device->pardev) { + pr_err("couldn't register with %s\n", port->name); +- goto err_free; ++ goto err_free_ida; + } + + if (parport_claim_or_block(device->pardev) < 0) { +@@ -197,8 +200,9 @@ static void parport_attach(struct parport *port) + parport_release(device->pardev); + err_unregister_dev: + parport_unregister_device(device->pardev); +-err_free: ++err_free_ida: + ida_free(&pps_client_index, index); ++err_free_device: + kfree(device); + } + +-- +2.43.0 + diff --git a/queue-4.19/pps-remove-usage-of-the-deprecated-ida_simple_xx-api.patch b/queue-4.19/pps-remove-usage-of-the-deprecated-ida_simple_xx-api.patch new file mode 100644 index 00000000000..ecb43060c26 --- /dev/null +++ b/queue-4.19/pps-remove-usage-of-the-deprecated-ida_simple_xx-api.patch @@ -0,0 +1,59 @@ +From 127d505fbff7cd460a6524cf5687ccc8430222f5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 14 Apr 2024 12:10:17 +0200 +Subject: pps: remove usage of the deprecated ida_simple_xx() API + +From: Christophe JAILLET + +[ Upstream commit 55dbc5b5174d0e7d1fa397d05aa4cb145e8b887e ] + +ida_alloc() and ida_free() should be preferred to the deprecated +ida_simple_get() and ida_simple_remove(). + +This is less verbose. + +Link: https://lkml.kernel.org/r/9f681747d446b874952a892491387d79ffe565a9.1713089394.git.christophe.jaillet@wanadoo.fr +Signed-off-by: Christophe JAILLET +Cc: Rodolfo Giometti +Cc: Greg Kroah-Hartman +Signed-off-by: Andrew Morton +Stable-dep-of: 62c5a01a5711 ("pps: add an error check in parport_attach") +Signed-off-by: Sasha Levin +--- + drivers/pps/clients/pps_parport.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/pps/clients/pps_parport.c b/drivers/pps/clients/pps_parport.c +index 4db824f88d009..de49ae85adbeb 100644 +--- a/drivers/pps/clients/pps_parport.c ++++ b/drivers/pps/clients/pps_parport.c +@@ -158,7 +158,7 @@ static void parport_attach(struct parport *port) + return; + } + +- index = ida_simple_get(&pps_client_index, 0, 0, GFP_KERNEL); ++ index = ida_alloc(&pps_client_index, GFP_KERNEL); + memset(&pps_client_cb, 0, sizeof(pps_client_cb)); + pps_client_cb.private = device; + pps_client_cb.irq_func = parport_irq; +@@ -198,7 +198,7 @@ static void parport_attach(struct parport *port) + err_unregister_dev: + parport_unregister_device(device->pardev); + err_free: +- ida_simple_remove(&pps_client_index, index); ++ ida_free(&pps_client_index, index); + kfree(device); + } + +@@ -218,7 +218,7 @@ static void parport_detach(struct parport *port) + pps_unregister_source(device->pps); + parport_release(pardev); + parport_unregister_device(pardev); +- ida_simple_remove(&pps_client_index, device->index); ++ ida_free(&pps_client_index, device->index); + kfree(device); + } + +-- +2.43.0 + diff --git a/queue-4.19/series b/queue-4.19/series index 572e6ebe796..96db9a6a846 100644 --- a/queue-4.19/series +++ b/queue-4.19/series @@ -124,3 +124,11 @@ f2fs-avoid-potential-int-overflow-in-sanity_check_area_boundary.patch vfs-fix-race-between-evice_inodes-and-find_inode-iput.patch fs-fix-file_set_fowner-lsm-hook-inconsistencies.patch nfs-fix-memory-leak-in-error-path-of-nfs4_do_reclaim.patch +pci-xilinx-nwl-use-irq_data_get_irq_chip_data.patch +pci-xilinx-nwl-fix-off-by-one-in-intx-irq-handler.patch +soc-versatile-realview-fix-memory-leak-during-device.patch +soc-versatile-realview-fix-soc_dev-leak-during-devic.patch +usb-yurex-replace-snprintf-with-the-safer-scnprintf-.patch +usb-misc-yurex-fix-race-between-read-and-write.patch +pps-remove-usage-of-the-deprecated-ida_simple_xx-api.patch +pps-add-an-error-check-in-parport_attach.patch diff --git a/queue-4.19/soc-versatile-realview-fix-memory-leak-during-device.patch b/queue-4.19/soc-versatile-realview-fix-memory-leak-during-device.patch new file mode 100644 index 00000000000..091c4c15ee8 --- /dev/null +++ b/queue-4.19/soc-versatile-realview-fix-memory-leak-during-device.patch @@ -0,0 +1,50 @@ +From 5c14ee9da5e42a7278b66ae4419c9ba956c729e6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 25 Aug 2024 20:05:23 +0200 +Subject: soc: versatile: realview: fix memory leak during device remove + +From: Krzysztof Kozlowski + +[ Upstream commit 1c4f26a41f9d052f334f6ae629e01f598ed93508 ] + +If device is unbound, the memory allocated for soc_dev_attr should be +freed to prevent leaks. + +Signed-off-by: Krzysztof Kozlowski +Link: https://lore.kernel.org/20240825-soc-dev-fixes-v1-2-ff4b35abed83@linaro.org +Signed-off-by: Linus Walleij +Stable-dep-of: c774f2564c00 ("soc: versatile: realview: fix soc_dev leak during device remove") +Signed-off-by: Sasha Levin +--- + drivers/soc/versatile/soc-realview.c | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +diff --git a/drivers/soc/versatile/soc-realview.c b/drivers/soc/versatile/soc-realview.c +index caf698e5f0b0b..98b6c60de7f64 100644 +--- a/drivers/soc/versatile/soc-realview.c ++++ b/drivers/soc/versatile/soc-realview.c +@@ -95,7 +95,7 @@ static int realview_soc_probe(struct platform_device *pdev) + if (IS_ERR(syscon_regmap)) + return PTR_ERR(syscon_regmap); + +- soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL); ++ soc_dev_attr = devm_kzalloc(&pdev->dev, sizeof(*soc_dev_attr), GFP_KERNEL); + if (!soc_dev_attr) + return -ENOMEM; + +@@ -107,10 +107,9 @@ static int realview_soc_probe(struct platform_device *pdev) + soc_dev_attr->machine = "RealView"; + soc_dev_attr->family = "Versatile"; + soc_dev = soc_device_register(soc_dev_attr); +- if (IS_ERR(soc_dev)) { +- kfree(soc_dev_attr); ++ if (IS_ERR(soc_dev)) + return -ENODEV; +- } ++ + ret = regmap_read(syscon_regmap, REALVIEW_SYS_ID_OFFSET, + &realview_coreid); + if (ret) +-- +2.43.0 + diff --git a/queue-4.19/soc-versatile-realview-fix-soc_dev-leak-during-devic.patch b/queue-4.19/soc-versatile-realview-fix-soc_dev-leak-during-devic.patch new file mode 100644 index 00000000000..f1f12d5efee --- /dev/null +++ b/queue-4.19/soc-versatile-realview-fix-soc_dev-leak-during-devic.patch @@ -0,0 +1,63 @@ +From eae61d1515e2e50aeaa915e65dc191b47a25dba9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 25 Aug 2024 20:05:24 +0200 +Subject: soc: versatile: realview: fix soc_dev leak during device remove + +From: Krzysztof Kozlowski + +[ Upstream commit c774f2564c0086c23f5269fd4691f233756bf075 ] + +If device is unbound, the soc_dev should be unregistered to prevent +memory leak. + +Fixes: a2974c9c1f83 ("soc: add driver for the ARM RealView") +Cc: stable@vger.kernel.org +Signed-off-by: Krzysztof Kozlowski +Link: https://lore.kernel.org/20240825-soc-dev-fixes-v1-3-ff4b35abed83@linaro.org +Signed-off-by: Linus Walleij +Signed-off-by: Sasha Levin +--- + drivers/soc/versatile/soc-realview.c | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +diff --git a/drivers/soc/versatile/soc-realview.c b/drivers/soc/versatile/soc-realview.c +index 98b6c60de7f64..a9220701c190b 100644 +--- a/drivers/soc/versatile/soc-realview.c ++++ b/drivers/soc/versatile/soc-realview.c +@@ -8,6 +8,7 @@ + * published by the Free Software Foundation. + * + */ ++#include + #include + #include + #include +@@ -83,6 +84,13 @@ static ssize_t realview_get_build(struct device *dev, + static struct device_attribute realview_build_attr = + __ATTR(build, S_IRUGO, realview_get_build, NULL); + ++static void realview_soc_socdev_release(void *data) ++{ ++ struct soc_device *soc_dev = data; ++ ++ soc_device_unregister(soc_dev); ++} ++ + static int realview_soc_probe(struct platform_device *pdev) + { + struct regmap *syscon_regmap; +@@ -110,6 +118,11 @@ static int realview_soc_probe(struct platform_device *pdev) + if (IS_ERR(soc_dev)) + return -ENODEV; + ++ ret = devm_add_action_or_reset(&pdev->dev, realview_soc_socdev_release, ++ soc_dev); ++ if (ret) ++ return ret; ++ + ret = regmap_read(syscon_regmap, REALVIEW_SYS_ID_OFFSET, + &realview_coreid); + if (ret) +-- +2.43.0 + diff --git a/queue-4.19/usb-misc-yurex-fix-race-between-read-and-write.patch b/queue-4.19/usb-misc-yurex-fix-race-between-read-and-write.patch new file mode 100644 index 00000000000..b8f3e2d67ce --- /dev/null +++ b/queue-4.19/usb-misc-yurex-fix-race-between-read-and-write.patch @@ -0,0 +1,63 @@ +From 0bcf12b77daed81b870305d3bfa70942fd64b4f6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 12 Sep 2024 15:21:22 +0200 +Subject: USB: misc: yurex: fix race between read and write + +From: Oliver Neukum + +[ Upstream commit 93907620b308609c72ba4b95b09a6aa2658bb553 ] + +The write code path touches the bbu member in a non atomic manner +without taking the spinlock. Fix it. + +The bug is as old as the driver. + +Signed-off-by: Oliver Neukum +CC: stable@vger.kernel.org +Link: https://lore.kernel.org/r/20240912132126.1034743-1-oneukum@suse.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/usb/misc/yurex.c | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +diff --git a/drivers/usb/misc/yurex.c b/drivers/usb/misc/yurex.c +index a85cc0f3e15c4..5f271d25b633d 100644 +--- a/drivers/usb/misc/yurex.c ++++ b/drivers/usb/misc/yurex.c +@@ -405,7 +405,6 @@ static ssize_t yurex_read(struct file *file, char __user *buffer, size_t count, + struct usb_yurex *dev; + int len = 0; + char in_buffer[MAX_S64_STRLEN]; +- unsigned long flags; + + dev = file->private_data; + +@@ -418,9 +417,9 @@ static ssize_t yurex_read(struct file *file, char __user *buffer, size_t count, + if (WARN_ON_ONCE(dev->bbu > S64_MAX || dev->bbu < S64_MIN)) + return -EIO; + +- spin_lock_irqsave(&dev->lock, flags); ++ spin_lock_irq(&dev->lock); + scnprintf(in_buffer, MAX_S64_STRLEN, "%lld\n", dev->bbu); +- spin_unlock_irqrestore(&dev->lock, flags); ++ spin_unlock_irq(&dev->lock); + mutex_unlock(&dev->io_mutex); + + return simple_read_from_buffer(buffer, count, ppos, in_buffer, len); +@@ -510,8 +509,11 @@ static ssize_t yurex_write(struct file *file, const char __user *user_buffer, + __func__, retval); + goto error; + } +- if (set && timeout) ++ if (set && timeout) { ++ spin_lock_irq(&dev->lock); + dev->bbu = c2; ++ spin_unlock_irq(&dev->lock); ++ } + return timeout ? count : -EIO; + + error: +-- +2.43.0 + diff --git a/queue-4.19/usb-yurex-replace-snprintf-with-the-safer-scnprintf-.patch b/queue-4.19/usb-yurex-replace-snprintf-with-the-safer-scnprintf-.patch new file mode 100644 index 00000000000..c4ea7190630 --- /dev/null +++ b/queue-4.19/usb-yurex-replace-snprintf-with-the-safer-scnprintf-.patch @@ -0,0 +1,77 @@ +From adfae745bc262b2b829ca72060b5e083929e049a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 13 Dec 2023 16:42:37 +0000 +Subject: usb: yurex: Replace snprintf() with the safer scnprintf() variant + +From: Lee Jones + +[ Upstream commit 86b20af11e84c26ae3fde4dcc4f490948e3f8035 ] + +There is a general misunderstanding amongst engineers that {v}snprintf() +returns the length of the data *actually* encoded into the destination +array. However, as per the C99 standard {v}snprintf() really returns +the length of the data that *would have been* written if there were +enough space for it. This misunderstanding has led to buffer-overruns +in the past. It's generally considered safer to use the {v}scnprintf() +variants in their place (or even sprintf() in simple cases). So let's +do that. + +Whilst we're at it, let's define some magic numbers to increase +readability and ease of maintenance. + +Link: https://lwn.net/Articles/69419/ +Link: https://github.com/KSPP/linux/issues/105 +Cc: Tomoki Sekiyama +Signed-off-by: Lee Jones +Link: https://lore.kernel.org/r/20231213164246.1021885-9-lee@kernel.org +Signed-off-by: Greg Kroah-Hartman +Stable-dep-of: 93907620b308 ("USB: misc: yurex: fix race between read and write") +Signed-off-by: Sasha Levin +--- + drivers/usb/misc/yurex.c | 12 +++++++----- + 1 file changed, 7 insertions(+), 5 deletions(-) + +diff --git a/drivers/usb/misc/yurex.c b/drivers/usb/misc/yurex.c +index 08b72bb22b7ef..a85cc0f3e15c4 100644 +--- a/drivers/usb/misc/yurex.c ++++ b/drivers/usb/misc/yurex.c +@@ -34,6 +34,8 @@ + #define YUREX_BUF_SIZE 8 + #define YUREX_WRITE_TIMEOUT (HZ*2) + ++#define MAX_S64_STRLEN 20 /* {-}922337203685477580{7,8} */ ++ + /* table of devices that work with this driver */ + static struct usb_device_id yurex_table[] = { + { USB_DEVICE(YUREX_VENDOR_ID, YUREX_PRODUCT_ID) }, +@@ -402,7 +404,7 @@ static ssize_t yurex_read(struct file *file, char __user *buffer, size_t count, + { + struct usb_yurex *dev; + int len = 0; +- char in_buffer[20]; ++ char in_buffer[MAX_S64_STRLEN]; + unsigned long flags; + + dev = file->private_data; +@@ -413,14 +415,14 @@ static ssize_t yurex_read(struct file *file, char __user *buffer, size_t count, + return -ENODEV; + } + ++ if (WARN_ON_ONCE(dev->bbu > S64_MAX || dev->bbu < S64_MIN)) ++ return -EIO; ++ + spin_lock_irqsave(&dev->lock, flags); +- len = snprintf(in_buffer, 20, "%lld\n", dev->bbu); ++ scnprintf(in_buffer, MAX_S64_STRLEN, "%lld\n", dev->bbu); + spin_unlock_irqrestore(&dev->lock, flags); + mutex_unlock(&dev->io_mutex); + +- if (WARN_ON_ONCE(len >= sizeof(in_buffer))) +- return -EIO; +- + return simple_read_from_buffer(buffer, count, ppos, in_buffer, len); + } + +-- +2.43.0 +