From: Greg Kroah-Hartman Date: Sun, 10 Nov 2024 05:01:12 +0000 (+0100) Subject: 5.4-stable patches X-Git-Tag: v5.15.172~44 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=383355ea1bb0447f44af7e03566f0d117fddba39;p=thirdparty%2Fkernel%2Fstable-queue.git 5.4-stable patches added patches: mtd-rawnand-protect-access-to-rawnand-devices-while-in-suspend.patch net-bridge-xmit-make-sure-we-have-at-least-eth-header-len-bytes.patch spi-fix-deadlock-when-adding-spi-controllers-on-spi-buses.patch spi-fix-use-after-free-of-the-add_lock-mutex.patch --- diff --git a/queue-5.4/mtd-rawnand-protect-access-to-rawnand-devices-while-in-suspend.patch b/queue-5.4/mtd-rawnand-protect-access-to-rawnand-devices-while-in-suspend.patch new file mode 100644 index 00000000000..3abcea0491f --- /dev/null +++ b/queue-5.4/mtd-rawnand-protect-access-to-rawnand-devices-while-in-suspend.patch @@ -0,0 +1,163 @@ +From 8cba323437a49a45756d661f500b324fc2d486fe Mon Sep 17 00:00:00 2001 +From: Sean Nyekjaer +Date: Tue, 8 Feb 2022 09:52:13 +0100 +Subject: mtd: rawnand: protect access to rawnand devices while in suspend + +From: Sean Nyekjaer + +commit 8cba323437a49a45756d661f500b324fc2d486fe upstream. + +Prevent rawnand access while in a suspended state. + +Commit 013e6292aaf5 ("mtd: rawnand: Simplify the locking") allows the +rawnand layer to return errors rather than waiting in a blocking wait. + +Tested on a iMX6ULL. + +Fixes: 013e6292aaf5 ("mtd: rawnand: Simplify the locking") +Signed-off-by: Sean Nyekjaer +Reviewed-by: Boris Brezillon +Cc: stable@vger.kernel.org +Signed-off-by: Miquel Raynal +Link: https://lore.kernel.org/linux-mtd/20220208085213.1838273-1-sean@geanix.com +[florian: Adjust rawnand.h members documentation and position] +Signed-off-by: Florian Fainelli +Signed-off-by: Greg Kroah-Hartman +--- + drivers/mtd/nand/raw/nand_base.c | 44 +++++++++++++++++---------------------- + include/linux/mtd/rawnand.h | 2 + + 2 files changed, 22 insertions(+), 24 deletions(-) + +--- a/drivers/mtd/nand/raw/nand_base.c ++++ b/drivers/mtd/nand/raw/nand_base.c +@@ -359,16 +359,19 @@ static int nand_isbad_bbm(struct nand_ch + * + * Return: -EBUSY if the chip has been suspended, 0 otherwise + */ +-static int nand_get_device(struct nand_chip *chip) ++static void nand_get_device(struct nand_chip *chip) + { +- mutex_lock(&chip->lock); +- if (chip->suspended) { ++ /* Wait until the device is resumed. */ ++ while (1) { ++ mutex_lock(&chip->lock); ++ if (!chip->suspended) { ++ mutex_lock(&chip->controller->lock); ++ return; ++ } + mutex_unlock(&chip->lock); +- return -EBUSY; +- } +- mutex_lock(&chip->controller->lock); + +- return 0; ++ wait_event(chip->resume_wq, !chip->suspended); ++ } + } + + /** +@@ -593,9 +596,7 @@ static int nand_block_markbad_lowlevel(s + nand_erase_nand(chip, &einfo, 0); + + /* Write bad block marker to OOB */ +- ret = nand_get_device(chip); +- if (ret) +- return ret; ++ nand_get_device(chip); + + ret = nand_markbad_bbm(chip, ofs); + nand_release_device(chip); +@@ -3576,9 +3577,7 @@ static int nand_read_oob(struct mtd_info + ops->mode != MTD_OPS_RAW) + return -ENOTSUPP; + +- ret = nand_get_device(chip); +- if (ret) +- return ret; ++ nand_get_device(chip); + + if (!ops->datbuf) + ret = nand_do_read_oob(chip, from, ops); +@@ -4122,13 +4121,11 @@ static int nand_write_oob(struct mtd_inf + struct mtd_oob_ops *ops) + { + struct nand_chip *chip = mtd_to_nand(mtd); +- int ret; ++ int ret = 0; + + ops->retlen = 0; + +- ret = nand_get_device(chip); +- if (ret) +- return ret; ++ nand_get_device(chip); + + switch (ops->mode) { + case MTD_OPS_PLACE_OOB: +@@ -4184,9 +4181,7 @@ int nand_erase_nand(struct nand_chip *ch + return -EINVAL; + + /* Grab the lock and see if the device is available */ +- ret = nand_get_device(chip); +- if (ret) +- return ret; ++ nand_get_device(chip); + + /* Shift to get first page */ + page = (int)(instr->addr >> chip->page_shift); +@@ -4273,7 +4268,7 @@ static void nand_sync(struct mtd_info *m + pr_debug("%s: called\n", __func__); + + /* Grab the lock and see if the device is available */ +- WARN_ON(nand_get_device(chip)); ++ nand_get_device(chip); + /* Release it and go back */ + nand_release_device(chip); + } +@@ -4290,9 +4285,7 @@ static int nand_block_isbad(struct mtd_i + int ret; + + /* Select the NAND device */ +- ret = nand_get_device(chip); +- if (ret) +- return ret; ++ nand_get_device(chip); + + nand_select_target(chip, chipnr); + +@@ -4354,6 +4347,8 @@ static void nand_resume(struct mtd_info + pr_err("%s called for a chip which is not in suspended state\n", + __func__); + mutex_unlock(&chip->lock); ++ ++ wake_up_all(&chip->resume_wq); + } + + /** +@@ -5014,6 +5009,7 @@ static int nand_scan_ident(struct nand_c + chip->cur_cs = -1; + + mutex_init(&chip->lock); ++ init_waitqueue_head(&chip->resume_wq); + + /* Enforce the right timings for reset/detection */ + onfi_fill_data_interface(chip, NAND_SDR_IFACE, 0); +--- a/include/linux/mtd/rawnand.h ++++ b/include/linux/mtd/rawnand.h +@@ -1064,6 +1064,7 @@ struct nand_legacy { + * @lock: lock protecting the suspended field. Also used to + * serialize accesses to the NAND device. + * @suspended: set to 1 when the device is suspended, 0 when it's not. ++ * @resume_wq: wait queue to sleep if rawnand is in suspended state. + * @bbt: [INTERN] bad block table pointer + * @bbt_td: [REPLACEABLE] bad block table descriptor for flash + * lookup. +@@ -1117,6 +1118,7 @@ struct nand_chip { + + struct mutex lock; + unsigned int suspended : 1; ++ wait_queue_head_t resume_wq; + + uint8_t *oob_poi; + struct nand_controller *controller; diff --git a/queue-5.4/net-bridge-xmit-make-sure-we-have-at-least-eth-header-len-bytes.patch b/queue-5.4/net-bridge-xmit-make-sure-we-have-at-least-eth-header-len-bytes.patch new file mode 100644 index 00000000000..4edd5789cc9 --- /dev/null +++ b/queue-5.4/net-bridge-xmit-make-sure-we-have-at-least-eth-header-len-bytes.patch @@ -0,0 +1,78 @@ +From 8bd67ebb50c0145fd2ca8681ab65eb7e8cde1afc Mon Sep 17 00:00:00 2001 +From: Nikolay Aleksandrov +Date: Mon, 13 May 2024 13:34:19 +0300 +Subject: net: bridge: xmit: make sure we have at least eth header len bytes + +From: Nikolay Aleksandrov + +commit 8bd67ebb50c0145fd2ca8681ab65eb7e8cde1afc upstream. + +syzbot triggered an uninit value[1] error in bridge device's xmit path +by sending a short (less than ETH_HLEN bytes) skb. To fix it check if +we can actually pull that amount instead of assuming. + +Tested with dropwatch: + drop at: br_dev_xmit+0xb93/0x12d0 [bridge] (0xffffffffc06739b3) + origin: software + timestamp: Mon May 13 11:31:53 2024 778214037 nsec + protocol: 0x88a8 + length: 2 + original length: 2 + drop reason: PKT_TOO_SMALL + +[1] +BUG: KMSAN: uninit-value in br_dev_xmit+0x61d/0x1cb0 net/bridge/br_device.c:65 + br_dev_xmit+0x61d/0x1cb0 net/bridge/br_device.c:65 + __netdev_start_xmit include/linux/netdevice.h:4903 [inline] + netdev_start_xmit include/linux/netdevice.h:4917 [inline] + xmit_one net/core/dev.c:3531 [inline] + dev_hard_start_xmit+0x247/0xa20 net/core/dev.c:3547 + __dev_queue_xmit+0x34db/0x5350 net/core/dev.c:4341 + dev_queue_xmit include/linux/netdevice.h:3091 [inline] + __bpf_tx_skb net/core/filter.c:2136 [inline] + __bpf_redirect_common net/core/filter.c:2180 [inline] + __bpf_redirect+0x14a6/0x1620 net/core/filter.c:2187 + ____bpf_clone_redirect net/core/filter.c:2460 [inline] + bpf_clone_redirect+0x328/0x470 net/core/filter.c:2432 + ___bpf_prog_run+0x13fe/0xe0f0 kernel/bpf/core.c:1997 + __bpf_prog_run512+0xb5/0xe0 kernel/bpf/core.c:2238 + bpf_dispatcher_nop_func include/linux/bpf.h:1234 [inline] + __bpf_prog_run include/linux/filter.h:657 [inline] + bpf_prog_run include/linux/filter.h:664 [inline] + bpf_test_run+0x499/0xc30 net/bpf/test_run.c:425 + bpf_prog_test_run_skb+0x14ea/0x1f20 net/bpf/test_run.c:1058 + bpf_prog_test_run+0x6b7/0xad0 kernel/bpf/syscall.c:4269 + __sys_bpf+0x6aa/0xd90 kernel/bpf/syscall.c:5678 + __do_sys_bpf kernel/bpf/syscall.c:5767 [inline] + __se_sys_bpf kernel/bpf/syscall.c:5765 [inline] + __x64_sys_bpf+0xa0/0xe0 kernel/bpf/syscall.c:5765 + x64_sys_call+0x96b/0x3b50 arch/x86/include/generated/asm/syscalls_64.h:322 + do_syscall_x64 arch/x86/entry/common.c:52 [inline] + do_syscall_64+0xcf/0x1e0 arch/x86/entry/common.c:83 + entry_SYSCALL_64_after_hwframe+0x77/0x7f + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Reported-by: syzbot+a63a1f6a062033cf0f40@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=a63a1f6a062033cf0f40 +Signed-off-by: Nikolay Aleksandrov +Signed-off-by: David S. Miller +Signed-off-by: Randy MacLeod +Signed-off-by: Greg Kroah-Hartman +--- + net/bridge/br_device.c | 5 +++++ + 1 file changed, 5 insertions(+) + +--- a/net/bridge/br_device.c ++++ b/net/bridge/br_device.c +@@ -35,6 +35,11 @@ netdev_tx_t br_dev_xmit(struct sk_buff * + const unsigned char *dest; + u16 vid = 0; + ++ if (unlikely(!pskb_may_pull(skb, ETH_HLEN))) { ++ kfree_skb(skb); ++ return NETDEV_TX_OK; ++ } ++ + memset(skb->cb, 0, sizeof(struct br_input_skb_cb)); + + rcu_read_lock(); diff --git a/queue-5.4/series b/queue-5.4/series index b5257b13481..3c110c74304 100644 --- a/queue-5.4/series +++ b/queue-5.4/series @@ -31,3 +31,7 @@ dm-cache-fix-potential-out-of-bounds-access-on-the-first-resume.patch dm-unstriped-cast-an-operand-to-sector_t-to-prevent-potential-uint32_t-overflow.patch nfs-fix-kmsan-warning-in-decode_getfattr_attrs.patch btrfs-reinitialize-delayed-ref-list-after-deleting-it-from-the-list.patch +mtd-rawnand-protect-access-to-rawnand-devices-while-in-suspend.patch +spi-fix-deadlock-when-adding-spi-controllers-on-spi-buses.patch +spi-fix-use-after-free-of-the-add_lock-mutex.patch +net-bridge-xmit-make-sure-we-have-at-least-eth-header-len-bytes.patch diff --git a/queue-5.4/spi-fix-deadlock-when-adding-spi-controllers-on-spi-buses.patch b/queue-5.4/spi-fix-deadlock-when-adding-spi-controllers-on-spi-buses.patch new file mode 100644 index 00000000000..0fd7c86802e --- /dev/null +++ b/queue-5.4/spi-fix-deadlock-when-adding-spi-controllers-on-spi-buses.patch @@ -0,0 +1,104 @@ +From 6098475d4cb48d821bdf453c61118c56e26294f0 Mon Sep 17 00:00:00 2001 +From: Mark Brown +Date: Fri, 8 Oct 2021 14:31:57 +0100 +Subject: spi: Fix deadlock when adding SPI controllers on SPI buses +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Mark Brown + +commit 6098475d4cb48d821bdf453c61118c56e26294f0 upstream. + +Currently we have a global spi_add_lock which we take when adding new +devices so that we can check that we're not trying to reuse a chip +select that's already controlled. This means that if the SPI device is +itself a SPI controller and triggers the instantiation of further SPI +devices we trigger a deadlock as we try to register and instantiate +those devices while in the process of doing so for the parent controller +and hence already holding the global spi_add_lock. Since we only care +about concurrency within a single SPI bus move the lock to be per +controller, avoiding the deadlock. + +This can be easily triggered in the case of spi-mux. + +Reported-by: Uwe Kleine-König +Signed-off-by: Mark Brown +Signed-off-by: Hardik Gohil +Signed-off-by: Greg Kroah-Hartman +--- + drivers/spi/spi.c | 15 +++++---------- + include/linux/spi/spi.h | 3 +++ + 2 files changed, 8 insertions(+), 10 deletions(-) + +--- a/drivers/spi/spi.c ++++ b/drivers/spi/spi.c +@@ -472,12 +472,6 @@ static LIST_HEAD(spi_controller_list); + */ + static DEFINE_MUTEX(board_lock); + +-/* +- * Prevents addition of devices with same chip select and +- * addition of devices below an unregistering controller. +- */ +-static DEFINE_MUTEX(spi_add_lock); +- + /** + * spi_alloc_device - Allocate a new SPI device + * @ctlr: Controller to which device is connected +@@ -580,7 +574,7 @@ int spi_add_device(struct spi_device *sp + * chipselect **BEFORE** we call setup(), else we'll trash + * its configuration. Lock against concurrent add() calls. + */ +- mutex_lock(&spi_add_lock); ++ mutex_lock(&ctlr->add_lock); + + status = bus_for_each_dev(&spi_bus_type, NULL, spi, spi_dev_check); + if (status) { +@@ -624,7 +618,7 @@ int spi_add_device(struct spi_device *sp + } + + done: +- mutex_unlock(&spi_add_lock); ++ mutex_unlock(&ctlr->add_lock); + return status; + } + EXPORT_SYMBOL_GPL(spi_add_device); +@@ -2512,6 +2506,7 @@ int spi_register_controller(struct spi_c + spin_lock_init(&ctlr->bus_lock_spinlock); + mutex_init(&ctlr->bus_lock_mutex); + mutex_init(&ctlr->io_mutex); ++ mutex_init(&ctlr->add_lock); + ctlr->bus_lock_flag = 0; + init_completion(&ctlr->xfer_completion); + if (!ctlr->max_dma_len) +@@ -2657,7 +2652,7 @@ void spi_unregister_controller(struct sp + + /* Prevent addition of new devices, unregister existing ones */ + if (IS_ENABLED(CONFIG_SPI_DYNAMIC)) +- mutex_lock(&spi_add_lock); ++ mutex_lock(&ctlr->add_lock); + + device_for_each_child(&ctlr->dev, NULL, __unregister); + +@@ -2688,7 +2683,7 @@ void spi_unregister_controller(struct sp + mutex_unlock(&board_lock); + + if (IS_ENABLED(CONFIG_SPI_DYNAMIC)) +- mutex_unlock(&spi_add_lock); ++ mutex_unlock(&ctlr->add_lock); + } + EXPORT_SYMBOL_GPL(spi_unregister_controller); + +--- a/include/linux/spi/spi.h ++++ b/include/linux/spi/spi.h +@@ -483,6 +483,9 @@ struct spi_controller { + /* I/O mutex */ + struct mutex io_mutex; + ++ /* Used to avoid adding the same CS twice */ ++ struct mutex add_lock; ++ + /* lock and mutex for SPI bus locking */ + spinlock_t bus_lock_spinlock; + struct mutex bus_lock_mutex; diff --git a/queue-5.4/spi-fix-use-after-free-of-the-add_lock-mutex.patch b/queue-5.4/spi-fix-use-after-free-of-the-add_lock-mutex.patch new file mode 100644 index 00000000000..f7968808668 --- /dev/null +++ b/queue-5.4/spi-fix-use-after-free-of-the-add_lock-mutex.patch @@ -0,0 +1,63 @@ +From 6c53b45c71b4920b5e62f0ea8079a1da382b9434 Mon Sep 17 00:00:00 2001 +From: Michael Walle +Date: Thu, 11 Nov 2021 09:37:13 +0100 +Subject: spi: fix use-after-free of the add_lock mutex +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Michael Walle + +commit 6c53b45c71b4920b5e62f0ea8079a1da382b9434 upstream. + +Commit 6098475d4cb4 ("spi: Fix deadlock when adding SPI controllers on +SPI buses") introduced a per-controller mutex. But mutex_unlock() of +said lock is called after the controller is already freed: + + spi_unregister_controller(ctlr) + -> put_device(&ctlr->dev) + -> spi_controller_release(dev) + -> mutex_unlock(&ctrl->add_lock) + +Move the put_device() after the mutex_unlock(). + +Fixes: 6098475d4cb4 ("spi: Fix deadlock when adding SPI controllers on SPI buses") +Signed-off-by: Michael Walle +Reviewed-by: Uwe Kleine-König +Reviewed-by: Lukas Wunner +Cc: stable@vger.kernel.org # v5.15 +Link: https://lore.kernel.org/r/20211111083713.3335171-1-michael@walle.cc +Signed-off-by: Mark Brown +Signed-off-by: Greg Kroah-Hartman +--- + drivers/spi/spi.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +--- a/drivers/spi/spi.c ++++ b/drivers/spi/spi.c +@@ -2670,12 +2670,6 @@ void spi_unregister_controller(struct sp + + device_del(&ctlr->dev); + +- /* Release the last reference on the controller if its driver +- * has not yet been converted to devm_spi_alloc_master/slave(). +- */ +- if (!ctlr->devm_allocated) +- put_device(&ctlr->dev); +- + /* free bus id */ + mutex_lock(&board_lock); + if (found == ctlr) +@@ -2684,6 +2678,12 @@ void spi_unregister_controller(struct sp + + if (IS_ENABLED(CONFIG_SPI_DYNAMIC)) + mutex_unlock(&ctlr->add_lock); ++ ++ /* Release the last reference on the controller if its driver ++ * has not yet been converted to devm_spi_alloc_master/slave(). ++ */ ++ if (!ctlr->devm_allocated) ++ put_device(&ctlr->dev); + } + EXPORT_SYMBOL_GPL(spi_unregister_controller); +