[PATCH net 1/6] net/ncsi: validate response packet lengths against the skb

Michael Bommarito
2026-04-22T16:05:07Z

ncsi_rcv_rsp() reads the common packet header before checking that the
skb contains enough data for it, and ncsi_validate_rsp_pkt() trusts
the response payload length before accessing the checksum field.

Malformed NC-SI replies can therefore drive header and checksum reads
past the received packet body. Make the dispatcher pull the common
header first, then have ncsi_validate_rsp_pkt() pull the full response
body before validating the packet.

This keeps malformed responses on the error path instead of letting the
parser walk past the skb payload.

Fixes: 138635cc27c9 ("net/ncsi: NCSI response packet handler")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-4-7
Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
---
net/ncsi/ncsi-rsp.c | 12 ++++++++++++
1 file changed, 12 insertions(+)

diff --git a/net/ncsi/ncsi-rsp.c b/net/ncsi/ncsi-rsp.c
index fbd84bc8026a..1fe061ede26d 100644
--- a/net/ncsi/ncsi-rsp.c
+++ b/net/ncsi/ncsi-rsp.c
@@ -38,11 +38,18 @@ static int ncsi_validate_rsp_pkt(struct ncsi_request *nr,
struct ncsi_rsp_pkt_hdr *h;
u32 checksum;
__be32 *pchecksum;
+ unsigned int len;

/* Check NCSI packet header. We don't need validate
* the packet type, which should have been checked
* before calling this function.
*/
+ len = skb_network_offset(nr->rsp) + sizeof(*h) + ALIGN(payload, 4);
+ if (!pskb_may_pull(nr->rsp, len)) {
+ netdev_dbg(nr->ndp->ndev.dev, "NCSI: packet too short\n");
+ return -EINVAL;
+ }
+
h = (struct ncsi_rsp_pkt_hdr *)skb_network_header(nr->rsp);

if (h->common.revision != NCSI_PKT_REVISION) {
@@ -1182,6 +1189,11 @@ int ncsi_rcv_rsp(struct sk_buff *skb, struct net_device *dev,
}

/* Check if it is AEN packet */
+ if (!pskb_may_pull(skb, skb_network_offset(skb) + sizeof(*hdr))) {
+ ret = -EINVAL;
+ goto err_free_skb;
+ }
+
hdr = (struct ncsi_pkt_hdr *)skb_network_header(skb);
if (hdr->type == NCSI_PKT_AEN)
return ncsi_aen_handler(ndp, skb);
--
2.53.0