]> git.proxmox.com Git - mirror_ubuntu-kernels.git/commitdiff
Fix write to cloned skb in ipv6_hop_ioam()
authorJustin Iurman <justin.iurman@uliege.be>
Mon, 19 Feb 2024 13:52:54 +0000 (14:52 +0100)
committerPaolo Abeni <pabeni@redhat.com>
Thu, 22 Feb 2024 08:28:03 +0000 (09:28 +0100)
ioam6_fill_trace_data() writes inside the skb payload without ensuring
it's writeable (e.g., not cloned). This function is called both from the
input and output path. The output path (ioam6_iptunnel) already does the
check. This commit provides a fix for the input path, inside
ipv6_hop_ioam(). It also updates ip6_parse_tlv() to refresh the network
header pointer ("nh") when returning from ipv6_hop_ioam().

Fixes: 9ee11f0fff20 ("ipv6: ioam: Data plane support for Pre-allocated Trace")
Reported-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Justin Iurman <justin.iurman@uliege.be>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
net/ipv6/exthdrs.c

index 4952ae792450575d275f1565d2bc198e440b67f6..02e9ffb63af1971c0949ccd0c392b995efb41ccb 100644 (file)
@@ -177,6 +177,8 @@ static bool ip6_parse_tlv(bool hopbyhop,
                                case IPV6_TLV_IOAM:
                                        if (!ipv6_hop_ioam(skb, off))
                                                return false;
+
+                                       nh = skb_network_header(skb);
                                        break;
                                case IPV6_TLV_JUMBO:
                                        if (!ipv6_hop_jumbo(skb, off))
@@ -943,6 +945,14 @@ static bool ipv6_hop_ioam(struct sk_buff *skb, int optoff)
                if (!skb_valid_dst(skb))
                        ip6_route_input(skb);
 
+               /* About to mangle packet header */
+               if (skb_ensure_writable(skb, optoff + 2 + hdr->opt_len))
+                       goto drop;
+
+               /* Trace pointer may have changed */
+               trace = (struct ioam6_trace_hdr *)(skb_network_header(skb)
+                                                  + optoff + sizeof(*hdr));
+
                ioam6_fill_trace_data(skb, ns, trace, true);
                break;
        default: