Skip to content

Commit 17175d1

Browse files
qsnklassert
authored andcommitted
xfrm: esp6: fix encapsulation header offset computation
In commit 0146dca, I incorrectly adapted the code that computes the location of the UDP or TCP encapsulation header from IPv4 to IPv6. In esp6_input_done2, skb->transport_header points to the ESP header, so by adding skb_network_header_len, uh and th will point to the ESP header, not the encapsulation header that's in front of it. Since the TCP header's size can change with options, we have to start from the IPv6 header and walk past possible extensions. Fixes: 0146dca ("xfrm: add support for UDPv6 encapsulation of ESP") Fixes: 26333c3 ("xfrm: add IPv6 support for espintcp") Reported-by: Tobias Brunner <[email protected]> Tested-by: Tobias Brunner <[email protected]> Signed-off-by: Sabrina Dubroca <[email protected]> Signed-off-by: Steffen Klassert <[email protected]>
1 parent 4f47e8a commit 17175d1

File tree

1 file changed

+9
-3
lines changed

1 file changed

+9
-3
lines changed

net/ipv6/esp6.c

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -805,10 +805,16 @@ int esp6_input_done2(struct sk_buff *skb, int err)
805805

806806
if (x->encap) {
807807
const struct ipv6hdr *ip6h = ipv6_hdr(skb);
808+
int offset = skb_network_offset(skb) + sizeof(*ip6h);
808809
struct xfrm_encap_tmpl *encap = x->encap;
809-
struct udphdr *uh = (void *)(skb_network_header(skb) + hdr_len);
810-
struct tcphdr *th = (void *)(skb_network_header(skb) + hdr_len);
811-
__be16 source;
810+
u8 nexthdr = ip6h->nexthdr;
811+
__be16 frag_off, source;
812+
struct udphdr *uh;
813+
struct tcphdr *th;
814+
815+
offset = ipv6_skip_exthdr(skb, offset, &nexthdr, &frag_off);
816+
uh = (void *)(skb->data + offset);
817+
th = (void *)(skb->data + offset);
812818

813819
switch (x->encap->encap_type) {
814820
case TCP_ENCAP_ESPINTCP:

0 commit comments

Comments
 (0)