Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Justin Iurman and committed by
Paolo Abeni
f198d933 7d2a894d

+10
+10
net/ipv6/exthdrs.c
··· 177 177 case IPV6_TLV_IOAM: 178 178 if (!ipv6_hop_ioam(skb, off)) 179 179 return false; 180 + 181 + nh = skb_network_header(skb); 180 182 break; 181 183 case IPV6_TLV_JUMBO: 182 184 if (!ipv6_hop_jumbo(skb, off)) ··· 944 942 945 943 if (!skb_valid_dst(skb)) 946 944 ip6_route_input(skb); 945 + 946 + /* About to mangle packet header */ 947 + if (skb_ensure_writable(skb, optoff + 2 + hdr->opt_len)) 948 + goto drop; 949 + 950 + /* Trace pointer may have changed */ 951 + trace = (struct ioam6_trace_hdr *)(skb_network_header(skb) 952 + + optoff + sizeof(*hdr)); 947 953 948 954 ioam6_fill_trace_data(skb, ns, trace, true); 949 955 break;