]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
net: garp: reload skb header pointers after pskb_may_pull()
authorDavid Carlier <devnexen@gmail.com>
Thu, 4 Jun 2026 14:19:22 +0000 (15:19 +0100)
committerJakub Kicinski <kuba@kernel.org>
Tue, 9 Jun 2026 02:10:01 +0000 (19:10 -0700)
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 <devnexen@gmail.com>
Link: https://patch.msgid.link/20260604141925.237746-1-devnexen@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
net/802/garp.c

index c7a39f298ad6edf689c1119535b5aabb8083f8cf..56b934ec1aae568fb54971047eff772984f2d14e 100644 (file)
@@ -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;