]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 10 Nov 2024 05:01:12 +0000 (06:01 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 10 Nov 2024 05:01:12 +0000 (06:01 +0100)
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

queue-5.4/mtd-rawnand-protect-access-to-rawnand-devices-while-in-suspend.patch [new file with mode: 0644]
queue-5.4/net-bridge-xmit-make-sure-we-have-at-least-eth-header-len-bytes.patch [new file with mode: 0644]
queue-5.4/series
queue-5.4/spi-fix-deadlock-when-adding-spi-controllers-on-spi-buses.patch [new file with mode: 0644]
queue-5.4/spi-fix-use-after-free-of-the-add_lock-mutex.patch [new file with mode: 0644]

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 (file)
index 0000000..3abcea0
--- /dev/null
@@ -0,0 +1,163 @@
+From 8cba323437a49a45756d661f500b324fc2d486fe Mon Sep 17 00:00:00 2001
+From: Sean Nyekjaer <sean@geanix.com>
+Date: Tue, 8 Feb 2022 09:52:13 +0100
+Subject: mtd: rawnand: protect access to rawnand devices while in suspend
+
+From: Sean Nyekjaer <sean@geanix.com>
+
+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 <sean@geanix.com>
+Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
+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 <florian.fainelli@broadcom.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..4edd578
--- /dev/null
@@ -0,0 +1,78 @@
+From 8bd67ebb50c0145fd2ca8681ab65eb7e8cde1afc Mon Sep 17 00:00:00 2001
+From: Nikolay Aleksandrov <razor@blackwall.org>
+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 <razor@blackwall.org>
+
+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 <razor@blackwall.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Randy MacLeod <Randy.MacLeod@windriver.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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();
index b5257b134815b23fc0968028fc86ba1ac5f9ff3b..3c110c74304b7b8dc7631953c23ad8c390899acd 100644 (file)
@@ -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 (file)
index 0000000..0fd7c86
--- /dev/null
@@ -0,0 +1,104 @@
+From 6098475d4cb48d821bdf453c61118c56e26294f0 Mon Sep 17 00:00:00 2001
+From: Mark Brown <broonie@kernel.org>
+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 <broonie@kernel.org>
+
+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 <u.kleine-koenig@pengutronix.de>
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Hardik Gohil <hgohil@mvista.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..f796880
--- /dev/null
@@ -0,0 +1,63 @@
+From 6c53b45c71b4920b5e62f0ea8079a1da382b9434 Mon Sep 17 00:00:00 2001
+From: Michael Walle <michael@walle.cc>
+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 <michael@walle.cc>
+
+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 <michael@walle.cc>
+Reviewed-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Reviewed-by: Lukas Wunner <lukas@wunner.de>
+Cc: stable@vger.kernel.org # v5.15
+Link: https://lore.kernel.org/r/20211111083713.3335171-1-michael@walle.cc
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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);