]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - releases/4.5.2/ipv6-count-in-extension-headers-in-skb-network_header.patch
Linux 4.14.121
[thirdparty/kernel/stable-queue.git] / releases / 4.5.2 / ipv6-count-in-extension-headers-in-skb-network_header.patch
CommitLineData
43c68a09
GKH
1From foo@baz Sat Apr 16 09:15:18 PDT 2016
2From: Jakub Sitnicki <jkbs@redhat.com>
3Date: Tue, 5 Apr 2016 18:41:08 +0200
4Subject: ipv6: Count in extension headers in skb->network_header
5
6From: Jakub Sitnicki <jkbs@redhat.com>
7
8[ Upstream commit 3ba3458fb9c050718b95275a3310b74415e767e2 ]
9
10When sending a UDPv6 message longer than MTU, account for the length
11of fragmentable IPv6 extension headers in skb->network_header offset.
12Same as we do in alloc_new_skb path in __ip6_append_data().
13
14This ensures that later on __ip6_make_skb() will make space in
15headroom for fragmentable extension headers:
16
17 /* move skb->data to ip header from ext header */
18 if (skb->data < skb_network_header(skb))
19 __skb_pull(skb, skb_network_offset(skb));
20
21Prevents a splat due to skb_under_panic:
22
23skbuff: skb_under_panic: text:ffffffff8143397b len:2126 put:14 \
24head:ffff880005bacf50 data:ffff880005bacf4a tail:0x48 end:0xc0 dev:lo
25------------[ cut here ]------------
26kernel BUG at net/core/skbuff.c:104!
27invalid opcode: 0000 [#1] KASAN
28CPU: 0 PID: 160 Comm: reproducer Not tainted 4.6.0-rc2 #65
29[...]
30Call Trace:
31 [<ffffffff813eb7b9>] skb_push+0x79/0x80
32 [<ffffffff8143397b>] eth_header+0x2b/0x100
33 [<ffffffff8141e0d0>] neigh_resolve_output+0x210/0x310
34 [<ffffffff814eab77>] ip6_finish_output2+0x4a7/0x7c0
35 [<ffffffff814efe3a>] ip6_output+0x16a/0x280
36 [<ffffffff815440c1>] ip6_local_out+0xb1/0xf0
37 [<ffffffff814f1115>] ip6_send_skb+0x45/0xd0
38 [<ffffffff81518836>] udp_v6_send_skb+0x246/0x5d0
39 [<ffffffff8151985e>] udpv6_sendmsg+0xa6e/0x1090
40[...]
41
42Reported-by: Ji Jianwen <jiji@redhat.com>
43Signed-off-by: Jakub Sitnicki <jkbs@redhat.com>
44Acked-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
45Signed-off-by: David S. Miller <davem@davemloft.net>
46Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
47---
48 net/ipv6/ip6_output.c | 8 ++++----
49 1 file changed, 4 insertions(+), 4 deletions(-)
50
51--- a/net/ipv6/ip6_output.c
52+++ b/net/ipv6/ip6_output.c
53@@ -1091,8 +1091,8 @@ static inline int ip6_ufo_append_data(st
54 int getfrag(void *from, char *to, int offset, int len,
55 int odd, struct sk_buff *skb),
56 void *from, int length, int hh_len, int fragheaderlen,
57- int transhdrlen, int mtu, unsigned int flags,
58- const struct flowi6 *fl6)
59+ int exthdrlen, int transhdrlen, int mtu,
60+ unsigned int flags, const struct flowi6 *fl6)
61
62 {
63 struct sk_buff *skb;
64@@ -1117,7 +1117,7 @@ static inline int ip6_ufo_append_data(st
65 skb_put(skb, fragheaderlen + transhdrlen);
66
67 /* initialize network header pointer */
68- skb_reset_network_header(skb);
69+ skb_set_network_header(skb, exthdrlen);
70
71 /* initialize protocol header pointer */
72 skb->transport_header = skb->network_header + fragheaderlen;
73@@ -1359,7 +1359,7 @@ emsgsize:
74 (rt->dst.dev->features & NETIF_F_UFO) &&
75 (sk->sk_type == SOCK_DGRAM) && !udp_get_no_check6_tx(sk)) {
76 err = ip6_ufo_append_data(sk, queue, getfrag, from, length,
77- hh_len, fragheaderlen,
78+ hh_len, fragheaderlen, exthdrlen,
79 transhdrlen, mtu, flags, fl6);
80 if (err)
81 goto error;