]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
geneve: ensure the skb is writable before fixing its headers
authorAntoine Tenart <atenart@kernel.org>
Thu, 9 Jul 2026 12:50:00 +0000 (14:50 +0200)
committerJakub Kicinski <kuba@kernel.org>
Tue, 21 Jul 2026 17:20:05 +0000 (10:20 -0700)
Make sure the IPv4/6 and UDP headers are writable before fixing them up in
geneve_post_decap_hint. As skb_ensure_writable can reallocate the skb linear
area, reload the GRO hint header pointer and only set the IPv4/6 header ones
after the call.

Fixes: fd0dd796576e ("geneve: use GRO hint option in the RX path")
Reported-by: Sashiko <sashiko-bot@kernel.org>
Closes: https://sashiko.dev/#/patchset/20260529144713.780938-1-atenart%40kernel.org
Signed-off-by: Antoine Tenart <atenart@kernel.org>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20260709125000.141092-1-atenart@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/geneve.c

index bed1c9713e0a1725ca3c298778d934a206a79ecd..bb275b30d3e5653e4e9788e398a6f72c50e8a06f 100644 (file)
@@ -586,6 +586,7 @@ static int geneve_post_decap_hint(const struct sock *sk, struct sk_buff *skb,
        struct iphdr *iph;
        struct udphdr *uh;
        __be16 p;
+       int err;
 
        hint_off = geneve_sk_gro_hint_off(sk, *geneveh, &p, &len);
        if (!hint_off)
@@ -610,12 +611,20 @@ static int geneve_post_decap_hint(const struct sock *sk, struct sk_buff *skb,
                     !geneve_opt_gro_hint_validate(skb->data, gro_hint)))
                return -EINVAL;
 
-       ipv6h = (void *)skb->data + gro_hint->nested_nh_offset;
-       iph = (struct iphdr *)ipv6h;
        total_len = skb->len - gro_hint->nested_nh_offset;
        if (total_len >= GRO_LEGACY_MAX_SIZE)
                return -E2BIG;
 
+       err = skb_ensure_writable(skb, gro_hint->nested_tp_offset + sizeof(*uh));
+       if (unlikely(err))
+               return err;
+
+       *geneveh = geneve_hdr(skb);
+       gro_hint = geneve_opt_gro_hint(*geneveh, hint_off);
+
+       ipv6h = (void *)skb->data + gro_hint->nested_nh_offset;
+       iph = (struct iphdr *)ipv6h;
+
        /*
         * After stripping the outer encap, the packet still carries a
         * tunnel encapsulation: the nested one.