From: David Carlier Date: Thu, 4 Jun 2026 14:19:22 +0000 (+0100) Subject: net: garp: reload skb header pointers after pskb_may_pull() X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ab71cf79e2f86012828bc1a3b8cf656a6a597a43;p=thirdparty%2Flinux.git net: garp: reload skb header pointers after pskb_may_pull() garp_pdu_parse_attr() keeps a pointer into the skb linear area across pskb_may_pull(skb, ga->len), and garp_pdu_parse_msg() dereferences gm on every loop iteration even though the nested parse may pull again. pskb_may_pull() can reallocate the skb head, which would leave those pointers stale. This is not reachable today: GARP PDUs arrive via the 802.2 LLC SAP path, where llc_fixup_skb() already pulls and trims the whole payload into the linear area, so the inner pulls never reallocate. Reload ga after the pull and snapshot gm->attrtype into a local anyway, to harden the parser and match the skb_header_pointer() discipline used by mrp.c. No functional change. Signed-off-by: David Carlier Link: https://patch.msgid.link/20260604141925.237746-1-devnexen@gmail.com Signed-off-by: Jakub Kicinski --- diff --git a/net/802/garp.c b/net/802/garp.c index c7a39f298ad6e..56b934ec1aae5 100644 --- a/net/802/garp.c +++ b/net/802/garp.c @@ -452,6 +452,7 @@ static int garp_pdu_parse_attr(struct garp_applicant *app, struct sk_buff *skb, if (!pskb_may_pull(skb, ga->len)) return -1; + ga = (struct garp_attr_hdr *)skb->data; skb_pull(skb, ga->len); dlen = ga->len - sizeof(*ga); @@ -492,6 +493,7 @@ static int garp_pdu_parse_attr(struct garp_applicant *app, struct sk_buff *skb, static int garp_pdu_parse_msg(struct garp_applicant *app, struct sk_buff *skb) { const struct garp_msg_hdr *gm; + u8 attrtype; if (!pskb_may_pull(skb, sizeof(*gm))) return -1; @@ -499,9 +501,10 @@ static int garp_pdu_parse_msg(struct garp_applicant *app, struct sk_buff *skb) if (gm->attrtype == 0) return -1; skb_pull(skb, sizeof(*gm)); + attrtype = gm->attrtype; while (skb->len > 0) { - if (garp_pdu_parse_attr(app, skb, gm->attrtype) < 0) + if (garp_pdu_parse_attr(app, skb, attrtype) < 0) return -1; if (garp_pdu_parse_end_mark(skb) < 0) break;