From: Stanislaw Pal <kuncy7@gmail.com>
To: Christian Marangi <ansuelsmth@gmail.com>,
Andrew Lunn <andrew@lunn.ch>, Vladimir Oltean <olteanv@gmail.com>
Cc: "David S . Miller" <davem@davemloft.net>,
Eric Dumazet <edumazet@kernel.org>,
Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>,
Yongzhao Chen <yongzhao.derek@gmail.com>,
netdev@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: [PATCH net-next v2 4/4] net: dsa: qca8k: bound the data of a management ack frame
Date: Wed, 4 Nov 2026 22:07:57 +0100 [thread overview]
Message-ID: <20261104210757.467964-5-kuncy7@gmail.com> (raw)
In-Reply-To: <20261104210757.467964-1-kuncy7@gmail.com>
qca8k_rw_reg_ack_handler() answers a management read by copying the
data that follows the Ethernet header into mgmt_eth_data->data. It
trusts the frame for both the length and the layout: the length field
of the frame allows up to 32 bytes while the buffer holds 16, so a
frame announcing more than three registers writes past the buffer into
the fields that follow it in qca8k_priv; and qca_tag_rcv() made only
the 2 byte tag linear, so the copy reads skb->data without checking
that the frame has the bytes it announces. The handler runs for every
ack frame, whatever its sequence number.
Size the buffer to what a management frame can carry, and pull the
announced data into the linear area before reading it. A frame that
is too short is left unacknowledged, so the read fails and the caller
falls back to MDIO.
An LLM assistant (Claude, claude-fable-5-1) helped write the change
and this description; I reviewed both and built them with W=1 on
arm64. The management path was exercised on a QCA8337 behind an
IPQ5018 (GL.iNet GL-B3000) with tag_qca.
Fixes: 90386223f44e ("net: dsa: qca8k: add support for larger read/write size with mgmt Ethernet")
Signed-off-by: Stanislaw Pal <kuncy7@gmail.com>
---
drivers/net/dsa/qca/qca8k-8xxx.c | 21 ++++++++++++++++-----
drivers/net/dsa/qca/qca8k.h | 3 ++-
2 files changed, 18 insertions(+), 6 deletions(-)
diff --git a/drivers/net/dsa/qca/qca8k-8xxx.c b/drivers/net/dsa/qca/qca8k-8xxx.c
index bc77dd45b6..01834e16a2 100644
--- a/drivers/net/dsa/qca/qca8k-8xxx.c
+++ b/drivers/net/dsa/qca/qca8k-8xxx.c
@@ -170,6 +170,7 @@ static void qca8k_rw_reg_ack_handler(struct dsa_switch *ds, struct sk_buff *skb)
struct qca8k_mgmt_eth_data *mgmt_eth_data;
struct qca8k_priv *priv = ds->priv;
struct qca_mgmt_ethhdr *mgmt_ethhdr;
+ int data_len = 0;
u32 command;
u8 len, cmd;
int i;
@@ -190,6 +191,17 @@ static void qca8k_rw_reg_ack_handler(struct dsa_switch *ds, struct sk_buff *skb)
/* We can ignore odd value, we always round up them in the alloc function. */
len *= sizeof(u16);
+ if (cmd == MDIO_READ && len > QCA_HDR_MGMT_DATA1_LEN)
+ data_len = min_t(int, QCA_HDR_MGMT_DATA2_LEN,
+ len - QCA_HDR_MGMT_DATA1_LEN);
+
+ /* The tagger made only the tag linear. Leave a frame that is too
+ * short for the data it announces unacknowledged: the read fails
+ * and the caller falls back to MDIO.
+ */
+ if (data_len && !pskb_may_pull(skb, data_len))
+ goto complete;
+
/* Make sure the seq match the requested packet */
if (get_unaligned_le32(&mgmt_ethhdr->seq) == mgmt_eth_data->seq)
mgmt_eth_data->ack = true;
@@ -199,13 +211,11 @@ static void qca8k_rw_reg_ack_handler(struct dsa_switch *ds, struct sk_buff *skb)
*val = get_unaligned_le32(&mgmt_ethhdr->mdio_data);
- /* Get the rest of the 12 byte of data.
- * The read/write function will extract the requested data.
+ /* Get the rest of the data.
+ * The read function extracts what it asked for.
*/
- if (len > QCA_HDR_MGMT_DATA1_LEN) {
+ if (data_len) {
__le32 *data2 = (__le32 *)skb->data;
- int data_len = min_t(int, QCA_HDR_MGMT_DATA2_LEN,
- len - QCA_HDR_MGMT_DATA1_LEN);
val++;
@@ -217,6 +227,7 @@ static void qca8k_rw_reg_ack_handler(struct dsa_switch *ds, struct sk_buff *skb)
}
}
+complete:
complete(&mgmt_eth_data->rw_done);
}
diff --git a/drivers/net/dsa/qca/qca8k.h b/drivers/net/dsa/qca/qca8k.h
index 79754755f1..b7aa0d832e 100644
--- a/drivers/net/dsa/qca/qca8k.h
+++ b/drivers/net/dsa/qca/qca8k.h
@@ -396,7 +396,8 @@ struct qca8k_mgmt_eth_data {
struct mutex mutex; /* Enforce one mdio read/write at time */
bool ack;
u32 seq;
- u32 data[4];
+ /* The data a management frame can carry */
+ u32 data[(QCA_HDR_MGMT_DATA1_LEN + QCA_HDR_MGMT_DATA2_LEN) / sizeof(u32)];
};
struct qca8k_mib_eth_data {
--
2.43.0
prev parent reply other threads:[~2026-11-04 21:08 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-04 21:07 [PATCH net-next v2 0/4] net: dsa: qca8k: fix the MIB autocast and management frame handlers Stanislaw Pal
2026-11-04 21:07 ` [PATCH net-next v2 1/4] net: dsa: qca8k: read each register into its own word over MDIO Stanislaw Pal
2026-11-04 21:07 ` [PATCH net-next v2 2/4] net: dsa: qca8k: drop MIB autocast frames once the request is over Stanislaw Pal
2026-11-04 21:07 ` [PATCH net-next v2 3/4] net: dsa: qca8k: check the length of MIB autocast frames Stanislaw Pal
2026-11-04 21:07 ` Stanislaw Pal [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261104210757.467964-5-kuncy7@gmail.com \
--to=kuncy7@gmail.com \
--cc=andrew@lunn.ch \
--cc=ansuelsmth@gmail.com \
--cc=davem@davemloft.net \
--cc=edumazet@kernel.org \
--cc=kuba@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=netdev@vger.kernel.org \
--cc=olteanv@gmail.com \
--cc=pabeni@redhat.com \
--cc=yongzhao.derek@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®