aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJustin Iurman <justin.iurman@uliege.be>2024-02-19 14:52:54 +0100
committerPaolo Abeni <pabeni@redhat.com>2024-02-22 09:28:03 +0100
commitf198d933c2e4f8f89e0620fbaf1ea7eac384a0eb (patch)
tree52e851fa5eb318d30a1e410e2b557ebf651a7e4d
parent7d2a894d7f487dcb894df023e9d3014cf5b93fe5 (diff)
downloadlinux-f198d933c2e4f8f89e0620fbaf1ea7eac384a0eb.tar.gz
Fix write to cloned skb in ipv6_hop_ioam()
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>
Notes
Fixes: 9ee11f0fff20 ("ipv6: ioam: Data plane support for Pre-allocated Trace") # v5.15-rc1 Stable: 8fbc19196dbe # v6.6.19 Stable: 37919ef31d7c # v6.1.80 Lore: https://lore.kernel.org/r/20240219134821.14009-2-justin.iurman@uliege.be # lkml, netdev Lore: https://lore.kernel.org/r/20240219135255.15429-2-justin.iurman@uliege.be # lkml, netdev Lore: https://lore.kernel.org/r/20240227131616.346583875@linuxfoundation.org # linux-patches, stable Lore: https://lore.kernel.org/r/20240227131634.817527902@linuxfoundation.org # linux-patches, stable Lore: https://lore.kernel.org/r/20240227131641.390800714@linuxfoundation.org # linux-patches, stable
-rw-r--r--net/ipv6/exthdrs.c10
1 files changed, 10 insertions, 0 deletions
diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c
index 4952ae7924505..02e9ffb63af19 100644
--- a/net/ipv6/exthdrs.c
+++ b/net/ipv6/exthdrs.c
@@ -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: