--- /dev/null
+From eaa517b77e63442260640d875f824d1111ca6569 Mon Sep 17 00:00:00 2001
+From: Ido Schimmel <idosch@nvidia.com>
+Date: Wed, 9 Apr 2025 14:24:40 +0300
+Subject: ethtool: cmis_cdb: Fix incorrect read / write length extension
+
+From: Ido Schimmel <idosch@nvidia.com>
+
+commit eaa517b77e63442260640d875f824d1111ca6569 upstream.
+
+The 'read_write_len_ext' field in 'struct ethtool_cmis_cdb_cmd_args'
+stores the maximum number of bytes that can be read from or written to
+the Local Payload (LPL) page in a single multi-byte access.
+
+Cited commit started overwriting this field with the maximum number of
+bytes that can be read from or written to the Extended Payload (LPL)
+pages in a single multi-byte access. Transceiver modules that support
+auto paging can advertise a number larger than 255 which is problematic
+as 'read_write_len_ext' is a 'u8', resulting in the number getting
+truncated and firmware flashing failing [1].
+
+Fix by ignoring the maximum EPL access size as the kernel does not
+currently support auto paging (even if the transceiver module does) and
+will not try to read / write more than 128 bytes at once.
+
+[1]
+Transceiver module firmware flashing started for device enp177s0np0
+Transceiver module firmware flashing in progress for device enp177s0np0
+Progress: 0%
+Transceiver module firmware flashing encountered an error for device enp177s0np0
+Status message: Write FW block EPL command failed, LPL length is longer
+ than CDB read write length extension allows.
+
+Fixes: 9a3b0d078bd8 ("net: ethtool: Add support for writing firmware blocks using EPL payload")
+Reported-by: Damodharam Ammepalli <damodharam.ammepalli@broadcom.com>
+Closes: https://lore.kernel.org/netdev/20250402183123.321036-3-michael.chan@broadcom.com/
+Tested-by: Damodharam Ammepalli <damodharam.ammepalli@broadcom.com>
+Signed-off-by: Ido Schimmel <idosch@nvidia.com>
+Reviewed-by: Damodharam Ammepalli <damodharam.ammepalli@broadcom.com>
+Reviewed-by: Petr Machata <petrm@nvidia.com>
+Link: https://patch.msgid.link/20250409112440.365672-1-idosch@nvidia.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ethtool/cmis.h | 1 -
+ net/ethtool/cmis_cdb.c | 18 +++---------------
+ 2 files changed, 3 insertions(+), 16 deletions(-)
+
+--- a/net/ethtool/cmis.h
++++ b/net/ethtool/cmis.h
+@@ -101,7 +101,6 @@ struct ethtool_cmis_cdb_rpl {
+ };
+
+ u32 ethtool_cmis_get_max_lpl_size(u8 num_of_byte_octs);
+-u32 ethtool_cmis_get_max_epl_size(u8 num_of_byte_octs);
+
+ void ethtool_cmis_cdb_compose_args(struct ethtool_cmis_cdb_cmd_args *args,
+ enum ethtool_cmis_cdb_cmd_id cmd, u8 *lpl,
+--- a/net/ethtool/cmis_cdb.c
++++ b/net/ethtool/cmis_cdb.c
+@@ -16,15 +16,6 @@ u32 ethtool_cmis_get_max_lpl_size(u8 num
+ return 8 * (1 + min_t(u8, num_of_byte_octs, 15));
+ }
+
+-/* For accessing the EPL field on page 9Fh, the allowable length extension is
+- * min(i, 255) byte octets where i specifies the allowable additional number of
+- * byte octets in a READ or a WRITE.
+- */
+-u32 ethtool_cmis_get_max_epl_size(u8 num_of_byte_octs)
+-{
+- return 8 * (1 + min_t(u8, num_of_byte_octs, 255));
+-}
+-
+ void ethtool_cmis_cdb_compose_args(struct ethtool_cmis_cdb_cmd_args *args,
+ enum ethtool_cmis_cdb_cmd_id cmd, u8 *lpl,
+ u8 lpl_len, u8 *epl, u16 epl_len,
+@@ -33,19 +24,16 @@ void ethtool_cmis_cdb_compose_args(struc
+ {
+ args->req.id = cpu_to_be16(cmd);
+ args->req.lpl_len = lpl_len;
+- if (lpl) {
++ if (lpl)
+ memcpy(args->req.payload, lpl, args->req.lpl_len);
+- args->read_write_len_ext =
+- ethtool_cmis_get_max_lpl_size(read_write_len_ext);
+- }
+ if (epl) {
+ args->req.epl_len = cpu_to_be16(epl_len);
+ args->req.epl = epl;
+- args->read_write_len_ext =
+- ethtool_cmis_get_max_epl_size(read_write_len_ext);
+ }
+
+ args->max_duration = max_duration;
++ args->read_write_len_ext =
++ ethtool_cmis_get_max_lpl_size(read_write_len_ext);
+ args->msleep_pre_rpl = msleep_pre_rpl;
+ args->rpl_exp_len = rpl_exp_len;
+ args->flags = flags;
--- /dev/null
+From a005fa5d7502eefec7ee6e1c01adadc06de2f9ad Mon Sep 17 00:00:00 2001
+From: "Kito Xu (veritas501)" <hxzene@gmail.com>
+Date: Mon, 25 May 2026 08:25:53 -0400
+Subject: net/sched: act_mirred: Fix blockcast recursion bypass leading to stack overflow
+
+From: Kito Xu (veritas501) <hxzene@gmail.com>
+
+commit a005fa5d7502eefec7ee6e1c01adadc06de2f9ad upstream.
+
+tcf_mirred_act() checks sched_mirred_nest against MIRRED_NEST_LIMIT (4)
+to prevent deep recursion. However, when the action uses blockcast
+(tcfm_blockid != 0), the function returns at the tcf_blockcast() call
+BEFORE reaching the counter increment. As a result, the recursion
+counter never advances and the limit check is entirely bypassed.
+
+When two devices share a TC egress block with a mirred blockcast rule,
+a packet egressing on device A is mirrored to device B via blockcast;
+device B's egress TC re-enters tcf_mirred_act() via blockcast and
+mirrors back to A, creating an unbounded recursion loop:
+
+ tcf_mirred_act -> tcf_blockcast -> tcf_mirred_to_dev -> dev_queue_xmit
+ -> sch_handle_egress -> tcf_classify -> tcf_mirred_act -> (repeat)
+
+This recursion continues until the kernel stack overflows.
+
+The bug is reachable from an unprivileged user via
+unshare(CLONE_NEWUSER | CLONE_NEWNET): user namespaces grant
+CAP_NET_ADMIN in the new network namespace, which is sufficient to
+create dummy devices, attach clsact qdiscs with shared blocks, and
+install mirred blockcast filters.
+
+ BUG: TASK stack guard page was hit at ffffc90000b7fff8
+ Oops: stack guard page: 0000 [#1] SMP KASAN NOPTI
+ CPU: 2 UID: 1000 PID: 169 Comm: poc Not tainted 7.0.0-rc7-next-20260410
+ RIP: 0010:xas_find+0x17/0x480
+ Call Trace:
+ xa_find+0x17b/0x1d0
+ tcf_mirred_act+0x640/0x1060
+ tcf_action_exec+0x400/0x530
+ basic_classify+0x128/0x1d0
+ tcf_classify+0xd83/0x1150
+ tc_run+0x328/0x620
+ __dev_queue_xmit+0x797/0x3100
+ tcf_mirred_to_dev+0x7b1/0xf70
+ tcf_mirred_act+0x68a/0x1060
+ [repeating ~30+ times until stack overflow]
+ Kernel panic - not syncing: Fatal exception in interrupt
+
+Fix this by incrementing sched_mirred_nest before calling
+tcf_blockcast() and decrementing it on return, mirroring the
+non-blockcast path. This ensures subsequent recursive entries see the
+updated counter and are correctly limited by MIRRED_NEST_LIMIT.
+
+Fixes: fe946a751d9b ("net/sched: act_mirred: add loop detection")
+Signed-off-by: Kito Xu (veritas501) <hxzene@gmail.com>
+Link: https://patch.msgid.link/20260525122556.973584-7-jhs@mojatatu.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/sched/act_mirred.c | 18 +++++++++++-------
+ 1 file changed, 11 insertions(+), 7 deletions(-)
+
+--- a/net/sched/act_mirred.c
++++ b/net/sched/act_mirred.c
+@@ -388,14 +388,12 @@ static int tcf_blockcast_mirror(struct s
+
+ static int tcf_blockcast(struct sk_buff *skb, struct tcf_mirred *m,
+ const u32 blockid, struct tcf_result *res,
+- int retval)
++ int m_eaction, int retval)
+ {
+ const u32 exception_ifindex = skb->dev->ifindex;
+ struct tcf_block *block;
+ bool is_redirect;
+- int m_eaction;
+
+- m_eaction = READ_ONCE(m->tcfm_eaction);
+ is_redirect = tcf_mirred_is_act_redirect(m_eaction);
+
+ /* we are already under rcu protection, so can call block lookup
+@@ -445,8 +443,16 @@ TC_INDIRECT_SCOPE int tcf_mirred_act(str
+ tcf_action_update_bstats(&m->common, skb);
+
+ blockid = READ_ONCE(m->tcfm_blockid);
+- if (blockid)
+- return tcf_blockcast(skb, m, blockid, res, retval);
++ m_eaction = READ_ONCE(m->tcfm_eaction);
++ want_ingress = tcf_mirred_act_wants_ingress(m_eaction);
++ if (blockid) {
++ if (!want_ingress)
++ xmit->sched_mirred_dev[xmit->sched_mirred_nest++] = NULL;
++ retval = tcf_blockcast(skb, m, blockid, res, m_eaction, retval);
++ if (!want_ingress)
++ xmit->sched_mirred_nest--;
++ return retval;
++ }
+
+ is_redirect = tcf_mirred_is_act_redirect(m_eaction);
+
+@@ -457,8 +463,6 @@ TC_INDIRECT_SCOPE int tcf_mirred_act(str
+ goto err_out;
+ }
+
+- m_eaction = READ_ONCE(m->tcfm_eaction);
+- want_ingress = tcf_mirred_act_wants_ingress(m_eaction);
+ if (!want_ingress) {
+ for (i = 0; i < xmit->sched_mirred_nest; i++) {
+ if (xmit->sched_mirred_dev[i] != dev)