]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
6.14-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 24 May 2025 15:38:53 +0000 (17:38 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 24 May 2025 15:38:53 +0000 (17:38 +0200)
added patches:
can-bcm-add-locking-for-bcm_op-runtime-updates.patch
can-bcm-add-missing-rcu-read-protection-for-procfs-content.patch
can-slcan-allow-reception-of-short-error-messages.patch
clk-s2mps11-initialise-clk_hw_onecell_data-num-before-accessing-hws-in-probe.patch
crypto-algif_hash-fix-double-free-in-hash_accept.patch
padata-do-not-leak-refcount-in-reorder_work.patch

queue-6.14/can-bcm-add-locking-for-bcm_op-runtime-updates.patch [new file with mode: 0644]
queue-6.14/can-bcm-add-missing-rcu-read-protection-for-procfs-content.patch [new file with mode: 0644]
queue-6.14/can-slcan-allow-reception-of-short-error-messages.patch [new file with mode: 0644]
queue-6.14/clk-s2mps11-initialise-clk_hw_onecell_data-num-before-accessing-hws-in-probe.patch [new file with mode: 0644]
queue-6.14/crypto-algif_hash-fix-double-free-in-hash_accept.patch [new file with mode: 0644]
queue-6.14/padata-do-not-leak-refcount-in-reorder_work.patch [new file with mode: 0644]
queue-6.14/series

diff --git a/queue-6.14/can-bcm-add-locking-for-bcm_op-runtime-updates.patch b/queue-6.14/can-bcm-add-locking-for-bcm_op-runtime-updates.patch
new file mode 100644 (file)
index 0000000..80b8be5
--- /dev/null
@@ -0,0 +1,192 @@
+From c2aba69d0c36a496ab4f2e81e9c2b271f2693fd7 Mon Sep 17 00:00:00 2001
+From: Oliver Hartkopp <socketcan@hartkopp.net>
+Date: Mon, 19 May 2025 14:50:26 +0200
+Subject: can: bcm: add locking for bcm_op runtime updates
+
+From: Oliver Hartkopp <socketcan@hartkopp.net>
+
+commit c2aba69d0c36a496ab4f2e81e9c2b271f2693fd7 upstream.
+
+The CAN broadcast manager (CAN BCM) can send a sequence of CAN frames via
+hrtimer. The content and also the length of the sequence can be changed
+resp reduced at runtime where the 'currframe' counter is then set to zero.
+
+Although this appeared to be a safe operation the updates of 'currframe'
+can be triggered from user space and hrtimer context in bcm_can_tx().
+Anderson Nascimento created a proof of concept that triggered a KASAN
+slab-out-of-bounds read access which can be prevented with a spin_lock_bh.
+
+At the rework of bcm_can_tx() the 'count' variable has been moved into
+the protected section as this variable can be modified from both contexts
+too.
+
+Fixes: ffd980f976e7 ("[CAN]: Add broadcast manager (bcm) protocol")
+Reported-by: Anderson Nascimento <anderson@allelesecurity.com>
+Tested-by: Anderson Nascimento <anderson@allelesecurity.com>
+Reviewed-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net>
+Link: https://patch.msgid.link/20250519125027.11900-1-socketcan@hartkopp.net
+Cc: stable@vger.kernel.org
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/can/bcm.c |   66 +++++++++++++++++++++++++++++++++++++++-------------------
+ 1 file changed, 45 insertions(+), 21 deletions(-)
+
+--- a/net/can/bcm.c
++++ b/net/can/bcm.c
+@@ -58,6 +58,7 @@
+ #include <linux/can/skb.h>
+ #include <linux/can/bcm.h>
+ #include <linux/slab.h>
++#include <linux/spinlock.h>
+ #include <net/sock.h>
+ #include <net/net_namespace.h>
+@@ -122,6 +123,7 @@ struct bcm_op {
+       struct canfd_frame last_sframe;
+       struct sock *sk;
+       struct net_device *rx_reg_dev;
++      spinlock_t bcm_tx_lock; /* protect currframe/count in runtime updates */
+ };
+ struct bcm_sock {
+@@ -285,13 +287,18 @@ static void bcm_can_tx(struct bcm_op *op
+ {
+       struct sk_buff *skb;
+       struct net_device *dev;
+-      struct canfd_frame *cf = op->frames + op->cfsiz * op->currframe;
++      struct canfd_frame *cf;
+       int err;
+       /* no target device? => exit */
+       if (!op->ifindex)
+               return;
++      /* read currframe under lock protection */
++      spin_lock_bh(&op->bcm_tx_lock);
++      cf = op->frames + op->cfsiz * op->currframe;
++      spin_unlock_bh(&op->bcm_tx_lock);
++
+       dev = dev_get_by_index(sock_net(op->sk), op->ifindex);
+       if (!dev) {
+               /* RFC: should this bcm_op remove itself here? */
+@@ -312,6 +319,10 @@ static void bcm_can_tx(struct bcm_op *op
+       skb->dev = dev;
+       can_skb_set_owner(skb, op->sk);
+       err = can_send(skb, 1);
++
++      /* update currframe and count under lock protection */
++      spin_lock_bh(&op->bcm_tx_lock);
++
+       if (!err)
+               op->frames_abs++;
+@@ -320,6 +331,11 @@ static void bcm_can_tx(struct bcm_op *op
+       /* reached last frame? */
+       if (op->currframe >= op->nframes)
+               op->currframe = 0;
++
++      if (op->count > 0)
++              op->count--;
++
++      spin_unlock_bh(&op->bcm_tx_lock);
+ out:
+       dev_put(dev);
+ }
+@@ -430,7 +446,7 @@ static enum hrtimer_restart bcm_tx_timeo
+       struct bcm_msg_head msg_head;
+       if (op->kt_ival1 && (op->count > 0)) {
+-              op->count--;
++              bcm_can_tx(op);
+               if (!op->count && (op->flags & TX_COUNTEVT)) {
+                       /* create notification to user */
+@@ -445,7 +461,6 @@ static enum hrtimer_restart bcm_tx_timeo
+                       bcm_send_to_user(op, &msg_head, NULL, 0);
+               }
+-              bcm_can_tx(op);
+       } else if (op->kt_ival2) {
+               bcm_can_tx(op);
+@@ -956,6 +971,27 @@ static int bcm_tx_setup(struct bcm_msg_h
+               }
+               op->flags = msg_head->flags;
++              /* only lock for unlikely count/nframes/currframe changes */
++              if (op->nframes != msg_head->nframes ||
++                  op->flags & TX_RESET_MULTI_IDX ||
++                  op->flags & SETTIMER) {
++
++                      spin_lock_bh(&op->bcm_tx_lock);
++
++                      if (op->nframes != msg_head->nframes ||
++                          op->flags & TX_RESET_MULTI_IDX) {
++                              /* potentially update changed nframes */
++                              op->nframes = msg_head->nframes;
++                              /* restart multiple frame transmission */
++                              op->currframe = 0;
++                      }
++
++                      if (op->flags & SETTIMER)
++                              op->count = msg_head->count;
++
++                      spin_unlock_bh(&op->bcm_tx_lock);
++              }
++
+       } else {
+               /* insert new BCM operation for the given can_id */
+@@ -963,9 +999,14 @@ static int bcm_tx_setup(struct bcm_msg_h
+               if (!op)
+                       return -ENOMEM;
++              spin_lock_init(&op->bcm_tx_lock);
+               op->can_id = msg_head->can_id;
+               op->cfsiz = CFSIZ(msg_head->flags);
+               op->flags = msg_head->flags;
++              op->nframes = msg_head->nframes;
++
++              if (op->flags & SETTIMER)
++                      op->count = msg_head->count;
+               /* create array for CAN frames and copy the data */
+               if (msg_head->nframes > 1) {
+@@ -1024,22 +1065,8 @@ static int bcm_tx_setup(struct bcm_msg_h
+       } /* if ((op = bcm_find_op(&bo->tx_ops, msg_head->can_id, ifindex))) */
+-      if (op->nframes != msg_head->nframes) {
+-              op->nframes   = msg_head->nframes;
+-              /* start multiple frame transmission with index 0 */
+-              op->currframe = 0;
+-      }
+-
+-      /* check flags */
+-
+-      if (op->flags & TX_RESET_MULTI_IDX) {
+-              /* start multiple frame transmission with index 0 */
+-              op->currframe = 0;
+-      }
+-
+       if (op->flags & SETTIMER) {
+               /* set timer values */
+-              op->count = msg_head->count;
+               op->ival1 = msg_head->ival1;
+               op->ival2 = msg_head->ival2;
+               op->kt_ival1 = bcm_timeval_to_ktime(msg_head->ival1);
+@@ -1056,11 +1083,8 @@ static int bcm_tx_setup(struct bcm_msg_h
+               op->flags |= TX_ANNOUNCE;
+       }
+-      if (op->flags & TX_ANNOUNCE) {
++      if (op->flags & TX_ANNOUNCE)
+               bcm_can_tx(op);
+-              if (op->count)
+-                      op->count--;
+-      }
+       if (op->flags & STARTTIMER)
+               bcm_tx_start_timer(op);
diff --git a/queue-6.14/can-bcm-add-missing-rcu-read-protection-for-procfs-content.patch b/queue-6.14/can-bcm-add-missing-rcu-read-protection-for-procfs-content.patch
new file mode 100644 (file)
index 0000000..4e20de0
--- /dev/null
@@ -0,0 +1,79 @@
+From dac5e6249159ac255dad9781793dbe5908ac9ddb Mon Sep 17 00:00:00 2001
+From: Oliver Hartkopp <socketcan@hartkopp.net>
+Date: Mon, 19 May 2025 14:50:27 +0200
+Subject: can: bcm: add missing rcu read protection for procfs content
+
+From: Oliver Hartkopp <socketcan@hartkopp.net>
+
+commit dac5e6249159ac255dad9781793dbe5908ac9ddb upstream.
+
+When the procfs content is generated for a bcm_op which is in the process
+to be removed the procfs output might show unreliable data (UAF).
+
+As the removal of bcm_op's is already implemented with rcu handling this
+patch adds the missing rcu_read_lock() and makes sure the list entries
+are properly removed under rcu protection.
+
+Fixes: f1b4e32aca08 ("can: bcm: use call_rcu() instead of costly synchronize_rcu()")
+Reported-by: Anderson Nascimento <anderson@allelesecurity.com>
+Suggested-by: Anderson Nascimento <anderson@allelesecurity.com>
+Tested-by: Anderson Nascimento <anderson@allelesecurity.com>
+Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net>
+Link: https://patch.msgid.link/20250519125027.11900-2-socketcan@hartkopp.net
+Cc: stable@vger.kernel.org # >= 5.4
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/can/bcm.c |   13 +++++++++----
+ 1 file changed, 9 insertions(+), 4 deletions(-)
+
+--- a/net/can/bcm.c
++++ b/net/can/bcm.c
+@@ -219,7 +219,9 @@ static int bcm_proc_show(struct seq_file
+       seq_printf(m, " / bound %s", bcm_proc_getifname(net, ifname, bo->ifindex));
+       seq_printf(m, " <<<\n");
+-      list_for_each_entry(op, &bo->rx_ops, list) {
++      rcu_read_lock();
++
++      list_for_each_entry_rcu(op, &bo->rx_ops, list) {
+               unsigned long reduction;
+@@ -275,6 +277,9 @@ static int bcm_proc_show(struct seq_file
+               seq_printf(m, "# sent %ld\n", op->frames_abs);
+       }
+       seq_putc(m, '\n');
++
++      rcu_read_unlock();
++
+       return 0;
+ }
+ #endif /* CONFIG_PROC_FS */
+@@ -858,7 +863,7 @@ static int bcm_delete_rx_op(struct list_
+                                                 REGMASK(op->can_id),
+                                                 bcm_rx_handler, op);
+-                      list_del(&op->list);
++                      list_del_rcu(&op->list);
+                       bcm_remove_op(op);
+                       return 1; /* done */
+               }
+@@ -878,7 +883,7 @@ static int bcm_delete_tx_op(struct list_
+       list_for_each_entry_safe(op, n, ops, list) {
+               if ((op->can_id == mh->can_id) && (op->ifindex == ifindex) &&
+                   (op->flags & CAN_FD_FRAME) == (mh->flags & CAN_FD_FRAME)) {
+-                      list_del(&op->list);
++                      list_del_rcu(&op->list);
+                       bcm_remove_op(op);
+                       return 1; /* done */
+               }
+@@ -1300,7 +1305,7 @@ static int bcm_rx_setup(struct bcm_msg_h
+                                             bcm_rx_handler, op, "bcm", sk);
+               if (err) {
+                       /* this bcm rx op is broken -> remove it */
+-                      list_del(&op->list);
++                      list_del_rcu(&op->list);
+                       bcm_remove_op(op);
+                       return err;
+               }
diff --git a/queue-6.14/can-slcan-allow-reception-of-short-error-messages.patch b/queue-6.14/can-slcan-allow-reception-of-short-error-messages.patch
new file mode 100644 (file)
index 0000000..89c9bb3
--- /dev/null
@@ -0,0 +1,101 @@
+From ef0841e4cb08754be6cb42bf97739fce5d086e5f Mon Sep 17 00:00:00 2001
+From: Carlos Sanchez <carlossanchez@geotab.com>
+Date: Tue, 20 May 2025 12:23:05 +0200
+Subject: can: slcan: allow reception of short error messages
+
+From: Carlos Sanchez <carlossanchez@geotab.com>
+
+commit ef0841e4cb08754be6cb42bf97739fce5d086e5f upstream.
+
+Allows slcan to receive short messages (typically errors) from the serial
+interface.
+
+When error support was added to slcan protocol in
+b32ff4668544e1333b694fcc7812b2d7397b4d6a ("can: slcan: extend the protocol
+with error info") the minimum valid message size changed from 5 (minimum
+standard can frame tIII0) to 3 ("e1a" is a valid protocol message, it is
+one of the examples given in the comments for slcan_bump_err() ), but the
+check for minimum message length prodicating all decoding was not adjusted.
+This makes short error messages discarded and error frames not being
+generated.
+
+This patch changes the minimum length to the new minimum (3 characters,
+excluding terminator, is now a valid message).
+
+Signed-off-by: Carlos Sanchez <carlossanchez@geotab.com>
+Fixes: b32ff4668544 ("can: slcan: extend the protocol with error info")
+Reviewed-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
+Link: https://patch.msgid.link/20250520102305.1097494-1-carlossanchez@geotab.com
+Cc: stable@vger.kernel.org
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/can/slcan/slcan-core.c |   26 ++++++++++++++++++++------
+ 1 file changed, 20 insertions(+), 6 deletions(-)
+
+--- a/drivers/net/can/slcan/slcan-core.c
++++ b/drivers/net/can/slcan/slcan-core.c
+@@ -71,12 +71,21 @@ MODULE_AUTHOR("Dario Binacchi <dario.bin
+ #define SLCAN_CMD_LEN 1
+ #define SLCAN_SFF_ID_LEN 3
+ #define SLCAN_EFF_ID_LEN 8
++#define SLCAN_DATA_LENGTH_LEN 1
++#define SLCAN_ERROR_LEN 1
+ #define SLCAN_STATE_LEN 1
+ #define SLCAN_STATE_BE_RXCNT_LEN 3
+ #define SLCAN_STATE_BE_TXCNT_LEN 3
+-#define SLCAN_STATE_FRAME_LEN       (1 + SLCAN_CMD_LEN + \
+-                                   SLCAN_STATE_BE_RXCNT_LEN + \
+-                                   SLCAN_STATE_BE_TXCNT_LEN)
++#define SLCAN_STATE_MSG_LEN     (SLCAN_CMD_LEN +              \
++                                 SLCAN_STATE_LEN +            \
++                                 SLCAN_STATE_BE_RXCNT_LEN +   \
++                                 SLCAN_STATE_BE_TXCNT_LEN)
++#define SLCAN_ERROR_MSG_LEN_MIN (SLCAN_CMD_LEN +      \
++                                 SLCAN_ERROR_LEN +    \
++                                 SLCAN_DATA_LENGTH_LEN)
++#define SLCAN_FRAME_MSG_LEN_MIN (SLCAN_CMD_LEN +      \
++                                 SLCAN_SFF_ID_LEN +   \
++                                 SLCAN_DATA_LENGTH_LEN)
+ struct slcan {
+       struct can_priv         can;
+@@ -176,6 +185,9 @@ static void slcan_bump_frame(struct slca
+       u32 tmpid;
+       char *cmd = sl->rbuff;
++      if (sl->rcount < SLCAN_FRAME_MSG_LEN_MIN)
++              return;
++
+       skb = alloc_can_skb(sl->dev, &cf);
+       if (unlikely(!skb)) {
+               sl->dev->stats.rx_dropped++;
+@@ -281,7 +293,7 @@ static void slcan_bump_state(struct slca
+               return;
+       }
+-      if (state == sl->can.state || sl->rcount < SLCAN_STATE_FRAME_LEN)
++      if (state == sl->can.state || sl->rcount != SLCAN_STATE_MSG_LEN)
+               return;
+       cmd += SLCAN_STATE_BE_RXCNT_LEN + SLCAN_CMD_LEN + 1;
+@@ -328,6 +340,9 @@ static void slcan_bump_err(struct slcan
+       bool rx_errors = false, tx_errors = false, rx_over_errors = false;
+       int i, len;
++      if (sl->rcount < SLCAN_ERROR_MSG_LEN_MIN)
++              return;
++
+       /* get len from sanitized ASCII value */
+       len = cmd[1];
+       if (len >= '0' && len < '9')
+@@ -456,8 +471,7 @@ static void slcan_bump(struct slcan *sl)
+ static void slcan_unesc(struct slcan *sl, unsigned char s)
+ {
+       if ((s == '\r') || (s == '\a')) { /* CR or BEL ends the pdu */
+-              if (!test_and_clear_bit(SLF_ERROR, &sl->flags) &&
+-                  sl->rcount > 4)
++              if (!test_and_clear_bit(SLF_ERROR, &sl->flags))
+                       slcan_bump(sl);
+               sl->rcount = 0;
diff --git a/queue-6.14/clk-s2mps11-initialise-clk_hw_onecell_data-num-before-accessing-hws-in-probe.patch b/queue-6.14/clk-s2mps11-initialise-clk_hw_onecell_data-num-before-accessing-hws-in-probe.patch
new file mode 100644 (file)
index 0000000..c212009
--- /dev/null
@@ -0,0 +1,61 @@
+From 3e14c7207a975eefcda1929b2134a9f4119dde45 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Andr=C3=A9=20Draszik?= <andre.draszik@linaro.org>
+Date: Wed, 26 Mar 2025 12:08:00 +0000
+Subject: clk: s2mps11: initialise clk_hw_onecell_data::num before accessing ::hws[] in probe()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: AndrĂ© Draszik <andre.draszik@linaro.org>
+
+commit 3e14c7207a975eefcda1929b2134a9f4119dde45 upstream.
+
+With UBSAN enabled, we're getting the following trace:
+
+    UBSAN: array-index-out-of-bounds in .../drivers/clk/clk-s2mps11.c:186:3
+    index 0 is out of range for type 'struct clk_hw *[] __counted_by(num)' (aka 'struct clk_hw *[]')
+
+This is because commit f316cdff8d67 ("clk: Annotate struct
+clk_hw_onecell_data with __counted_by") annotated the hws member of
+that struct with __counted_by, which informs the bounds sanitizer about
+the number of elements in hws, so that it can warn when hws is accessed
+out of bounds.
+
+As noted in that change, the __counted_by member must be initialised
+with the number of elements before the first array access happens,
+otherwise there will be a warning from each access prior to the
+initialisation because the number of elements is zero. This occurs in
+s2mps11_clk_probe() due to ::num being assigned after ::hws access.
+
+Move the assignment to satisfy the requirement of assign-before-access.
+
+Cc: stable@vger.kernel.org
+Fixes: f316cdff8d67 ("clk: Annotate struct clk_hw_onecell_data with __counted_by")
+Signed-off-by: AndrĂ© Draszik <andre.draszik@linaro.org>
+Link: https://lore.kernel.org/r/20250326-s2mps11-ubsan-v1-1-fcc6fce5c8a9@linaro.org
+Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/clk/clk-s2mps11.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/clk/clk-s2mps11.c
++++ b/drivers/clk/clk-s2mps11.c
+@@ -137,6 +137,8 @@ static int s2mps11_clk_probe(struct plat
+       if (!clk_data)
+               return -ENOMEM;
++      clk_data->num = S2MPS11_CLKS_NUM;
++
+       switch (hwid) {
+       case S2MPS11X:
+               s2mps11_reg = S2MPS11_REG_RTC_CTRL;
+@@ -186,7 +188,6 @@ static int s2mps11_clk_probe(struct plat
+               clk_data->hws[i] = &s2mps11_clks[i].hw;
+       }
+-      clk_data->num = S2MPS11_CLKS_NUM;
+       of_clk_add_hw_provider(s2mps11_clks->clk_np, of_clk_hw_onecell_get,
+                              clk_data);
diff --git a/queue-6.14/crypto-algif_hash-fix-double-free-in-hash_accept.patch b/queue-6.14/crypto-algif_hash-fix-double-free-in-hash_accept.patch
new file mode 100644 (file)
index 0000000..8aa8152
--- /dev/null
@@ -0,0 +1,36 @@
+From b2df03ed4052e97126267e8c13ad4204ea6ba9b6 Mon Sep 17 00:00:00 2001
+From: Ivan Pravdin <ipravdin.official@gmail.com>
+Date: Sun, 18 May 2025 18:41:02 -0400
+Subject: crypto: algif_hash - fix double free in hash_accept
+
+From: Ivan Pravdin <ipravdin.official@gmail.com>
+
+commit b2df03ed4052e97126267e8c13ad4204ea6ba9b6 upstream.
+
+If accept(2) is called on socket type algif_hash with
+MSG_MORE flag set and crypto_ahash_import fails,
+sk2 is freed. However, it is also freed in af_alg_release,
+leading to slab-use-after-free error.
+
+Fixes: fe869cdb89c9 ("crypto: algif_hash - User-space interface for hash operations")
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Ivan Pravdin <ipravdin.official@gmail.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ crypto/algif_hash.c |    4 ----
+ 1 file changed, 4 deletions(-)
+
+--- a/crypto/algif_hash.c
++++ b/crypto/algif_hash.c
+@@ -265,10 +265,6 @@ static int hash_accept(struct socket *so
+               goto out_free_state;
+       err = crypto_ahash_import(&ctx2->req, state);
+-      if (err) {
+-              sock_orphan(sk2);
+-              sock_put(sk2);
+-      }
+ out_free_state:
+       kfree_sensitive(state);
diff --git a/queue-6.14/padata-do-not-leak-refcount-in-reorder_work.patch b/queue-6.14/padata-do-not-leak-refcount-in-reorder_work.patch
new file mode 100644 (file)
index 0000000..9b040c0
--- /dev/null
@@ -0,0 +1,55 @@
+From d6ebcde6d4ecf34f8495fb30516645db3aea8993 Mon Sep 17 00:00:00 2001
+From: Dominik Grzegorzek <dominik.grzegorzek@oracle.com>
+Date: Sun, 18 May 2025 19:45:31 +0200
+Subject: padata: do not leak refcount in reorder_work
+
+From: Dominik Grzegorzek <dominik.grzegorzek@oracle.com>
+
+commit d6ebcde6d4ecf34f8495fb30516645db3aea8993 upstream.
+
+A recent patch that addressed a UAF introduced a reference count leak:
+the parallel_data refcount is incremented unconditionally, regardless
+of the return value of queue_work(). If the work item is already queued,
+the incremented refcount is never decremented.
+
+Fix this by checking the return value of queue_work() and decrementing
+the refcount when necessary.
+
+Resolves:
+
+Unreferenced object 0xffff9d9f421e3d80 (size 192):
+  comm "cryptomgr_probe", pid 157, jiffies 4294694003
+  hex dump (first 32 bytes):
+    80 8b cf 41 9f 9d ff ff b8 97 e0 89 ff ff ff ff  ...A............
+    d0 97 e0 89 ff ff ff ff 19 00 00 00 1f 88 23 00  ..............#.
+  backtrace (crc 838fb36):
+    __kmalloc_cache_noprof+0x284/0x320
+    padata_alloc_pd+0x20/0x1e0
+    padata_alloc_shell+0x3b/0xa0
+    0xffffffffc040a54d
+    cryptomgr_probe+0x43/0xc0
+    kthread+0xf6/0x1f0
+    ret_from_fork+0x2f/0x50
+    ret_from_fork_asm+0x1a/0x30
+
+Fixes: dd7d37ccf6b1 ("padata: avoid UAF for reorder_work")
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Dominik Grzegorzek <dominik.grzegorzek@oracle.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ kernel/padata.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/kernel/padata.c
++++ b/kernel/padata.c
+@@ -358,7 +358,8 @@ static void padata_reorder(struct parall
+                * To avoid UAF issue, add pd ref here, and put pd ref after reorder_work finish.
+                */
+               padata_get_pd(pd);
+-              queue_work(pinst->serial_wq, &pd->reorder_work);
++              if (!queue_work(pinst->serial_wq, &pd->reorder_work))
++                      padata_put_pd(pd);
+       }
+ }
index dd0894dac2f6b46e5b3addf66010da49ea919915..9f7a36512718287fa568edd4d9dd64dc1e550453 100644 (file)
@@ -724,3 +724,9 @@ octeontx2-pf-avoid-adding-dcbnl_ops-for-lbk-and-sdp-.patch
 net-tipc-fix-slab-use-after-free-read-in-tipc_aead_e.patch
 octeontx2-af-set-lmt_ena-bit-for-apr-table-entries.patch
 octeontx2-af-fix-apr-entry-mapping-based-on-apr_lmt_.patch
+clk-s2mps11-initialise-clk_hw_onecell_data-num-before-accessing-hws-in-probe.patch
+crypto-algif_hash-fix-double-free-in-hash_accept.patch
+padata-do-not-leak-refcount-in-reorder_work.patch
+can-slcan-allow-reception-of-short-error-messages.patch
+can-bcm-add-locking-for-bcm_op-runtime-updates.patch
+can-bcm-add-missing-rcu-read-protection-for-procfs-content.patch