From 589f694eed33dd2987b74b5e92e8f2db4dd23f77 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Sat, 24 May 2025 17:38:53 +0200 Subject: [PATCH] 6.14-stable patches 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 --- ...d-locking-for-bcm_op-runtime-updates.patch | 192 ++++++++++++++++++ ...u-read-protection-for-procfs-content.patch | 79 +++++++ ...ow-reception-of-short-error-messages.patch | 101 +++++++++ ...ta-num-before-accessing-hws-in-probe.patch | 61 ++++++ ..._hash-fix-double-free-in-hash_accept.patch | 36 ++++ ...do-not-leak-refcount-in-reorder_work.patch | 55 +++++ queue-6.14/series | 6 + 7 files changed, 530 insertions(+) create mode 100644 queue-6.14/can-bcm-add-locking-for-bcm_op-runtime-updates.patch create mode 100644 queue-6.14/can-bcm-add-missing-rcu-read-protection-for-procfs-content.patch create mode 100644 queue-6.14/can-slcan-allow-reception-of-short-error-messages.patch create mode 100644 queue-6.14/clk-s2mps11-initialise-clk_hw_onecell_data-num-before-accessing-hws-in-probe.patch create mode 100644 queue-6.14/crypto-algif_hash-fix-double-free-in-hash_accept.patch create mode 100644 queue-6.14/padata-do-not-leak-refcount-in-reorder_work.patch 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 index 0000000000..80b8be5254 --- /dev/null +++ b/queue-6.14/can-bcm-add-locking-for-bcm_op-runtime-updates.patch @@ -0,0 +1,192 @@ +From c2aba69d0c36a496ab4f2e81e9c2b271f2693fd7 Mon Sep 17 00:00:00 2001 +From: Oliver Hartkopp +Date: Mon, 19 May 2025 14:50:26 +0200 +Subject: can: bcm: add locking for bcm_op runtime updates + +From: Oliver Hartkopp + +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 +Tested-by: Anderson Nascimento +Reviewed-by: Marc Kleine-Budde +Signed-off-by: Oliver Hartkopp +Link: https://patch.msgid.link/20250519125027.11900-1-socketcan@hartkopp.net +Cc: stable@vger.kernel.org +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Greg Kroah-Hartman +--- + 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 + #include + #include ++#include + #include + #include + +@@ -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 index 0000000000..4e20de06bc --- /dev/null +++ b/queue-6.14/can-bcm-add-missing-rcu-read-protection-for-procfs-content.patch @@ -0,0 +1,79 @@ +From dac5e6249159ac255dad9781793dbe5908ac9ddb Mon Sep 17 00:00:00 2001 +From: Oliver Hartkopp +Date: Mon, 19 May 2025 14:50:27 +0200 +Subject: can: bcm: add missing rcu read protection for procfs content + +From: Oliver Hartkopp + +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 +Suggested-by: Anderson Nascimento +Tested-by: Anderson Nascimento +Signed-off-by: Oliver Hartkopp +Link: https://patch.msgid.link/20250519125027.11900-2-socketcan@hartkopp.net +Cc: stable@vger.kernel.org # >= 5.4 +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 0000000000..89c9bb33d7 --- /dev/null +++ b/queue-6.14/can-slcan-allow-reception-of-short-error-messages.patch @@ -0,0 +1,101 @@ +From ef0841e4cb08754be6cb42bf97739fce5d086e5f Mon Sep 17 00:00:00 2001 +From: Carlos Sanchez +Date: Tue, 20 May 2025 12:23:05 +0200 +Subject: can: slcan: allow reception of short error messages + +From: Carlos Sanchez + +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 +Fixes: b32ff4668544 ("can: slcan: extend the protocol with error info") +Reviewed-by: Vincent Mailhol +Link: https://patch.msgid.link/20250520102305.1097494-1-carlossanchez@geotab.com +Cc: stable@vger.kernel.org +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Greg Kroah-Hartman +--- + 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 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 index 0000000000..c21200989d --- /dev/null +++ b/queue-6.14/clk-s2mps11-initialise-clk_hw_onecell_data-num-before-accessing-hws-in-probe.patch @@ -0,0 +1,61 @@ +From 3e14c7207a975eefcda1929b2134a9f4119dde45 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Andr=C3=A9=20Draszik?= +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 + +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 +Link: https://lore.kernel.org/r/20250326-s2mps11-ubsan-v1-1-fcc6fce5c8a9@linaro.org +Reviewed-by: Krzysztof Kozlowski +Signed-off-by: Stephen Boyd +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 0000000000..8aa8152589 --- /dev/null +++ b/queue-6.14/crypto-algif_hash-fix-double-free-in-hash_accept.patch @@ -0,0 +1,36 @@ +From b2df03ed4052e97126267e8c13ad4204ea6ba9b6 Mon Sep 17 00:00:00 2001 +From: Ivan Pravdin +Date: Sun, 18 May 2025 18:41:02 -0400 +Subject: crypto: algif_hash - fix double free in hash_accept + +From: Ivan Pravdin + +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: +Signed-off-by: Ivan Pravdin +Signed-off-by: Herbert Xu +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 0000000000..9b040c042a --- /dev/null +++ b/queue-6.14/padata-do-not-leak-refcount-in-reorder_work.patch @@ -0,0 +1,55 @@ +From d6ebcde6d4ecf34f8495fb30516645db3aea8993 Mon Sep 17 00:00:00 2001 +From: Dominik Grzegorzek +Date: Sun, 18 May 2025 19:45:31 +0200 +Subject: padata: do not leak refcount in reorder_work + +From: Dominik Grzegorzek + +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: +Signed-off-by: Dominik Grzegorzek +Signed-off-by: Herbert Xu +Signed-off-by: Greg Kroah-Hartman +--- + 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); + } + } + diff --git a/queue-6.14/series b/queue-6.14/series index dd0894dac2..9f7a365127 100644 --- a/queue-6.14/series +++ b/queue-6.14/series @@ -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 -- 2.47.3