]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - queue-4.9/net-sit-fix-ubsan-undefined-behaviour-in-check_6rd.patch
Linux 4.14.107
[thirdparty/kernel/stable-queue.git] / queue-4.9 / net-sit-fix-ubsan-undefined-behaviour-in-check_6rd.patch
1 From foo@baz Fri Mar 15 21:00:09 PDT 2019
2 From: Miaohe Lin <linmiaohe@huawei.com>
3 Date: Mon, 11 Mar 2019 16:29:32 +0800
4 Subject: net: sit: fix UBSAN Undefined behaviour in check_6rd
5
6 From: Miaohe Lin <linmiaohe@huawei.com>
7
8 [ Upstream commit a843dc4ebaecd15fca1f4d35a97210f72ea1473b ]
9
10 In func check_6rd,tunnel->ip6rd.relay_prefixlen may equal to
11 32,so UBSAN complain about it.
12
13 UBSAN: Undefined behaviour in net/ipv6/sit.c:781:47
14 shift exponent 32 is too large for 32-bit type 'unsigned int'
15 CPU: 6 PID: 20036 Comm: syz-executor.0 Not tainted 4.19.27 #2
16 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.10.2-1ubuntu1
17 04/01/2014
18 Call Trace:
19 __dump_stack lib/dump_stack.c:77 [inline]
20 dump_stack+0xca/0x13e lib/dump_stack.c:113
21 ubsan_epilogue+0xe/0x81 lib/ubsan.c:159
22 __ubsan_handle_shift_out_of_bounds+0x293/0x2e8 lib/ubsan.c:425
23 check_6rd.constprop.9+0x433/0x4e0 net/ipv6/sit.c:781
24 try_6rd net/ipv6/sit.c:806 [inline]
25 ipip6_tunnel_xmit net/ipv6/sit.c:866 [inline]
26 sit_tunnel_xmit+0x141c/0x2720 net/ipv6/sit.c:1033
27 __netdev_start_xmit include/linux/netdevice.h:4300 [inline]
28 netdev_start_xmit include/linux/netdevice.h:4309 [inline]
29 xmit_one net/core/dev.c:3243 [inline]
30 dev_hard_start_xmit+0x17c/0x780 net/core/dev.c:3259
31 __dev_queue_xmit+0x1656/0x2500 net/core/dev.c:3829
32 neigh_output include/net/neighbour.h:501 [inline]
33 ip6_finish_output2+0xa36/0x2290 net/ipv6/ip6_output.c:120
34 ip6_finish_output+0x3e7/0xa20 net/ipv6/ip6_output.c:154
35 NF_HOOK_COND include/linux/netfilter.h:278 [inline]
36 ip6_output+0x1e2/0x720 net/ipv6/ip6_output.c:171
37 dst_output include/net/dst.h:444 [inline]
38 ip6_local_out+0x99/0x170 net/ipv6/output_core.c:176
39 ip6_send_skb+0x9d/0x2f0 net/ipv6/ip6_output.c:1697
40 ip6_push_pending_frames+0xc0/0x100 net/ipv6/ip6_output.c:1717
41 rawv6_push_pending_frames net/ipv6/raw.c:616 [inline]
42 rawv6_sendmsg+0x2435/0x3530 net/ipv6/raw.c:946
43 inet_sendmsg+0xf8/0x5c0 net/ipv4/af_inet.c:798
44 sock_sendmsg_nosec net/socket.c:621 [inline]
45 sock_sendmsg+0xc8/0x110 net/socket.c:631
46 ___sys_sendmsg+0x6cf/0x890 net/socket.c:2114
47 __sys_sendmsg+0xf0/0x1b0 net/socket.c:2152
48 do_syscall_64+0xc8/0x580 arch/x86/entry/common.c:290
49 entry_SYSCALL_64_after_hwframe+0x49/0xbe
50
51 Signed-off-by: linmiaohe <linmiaohe@huawei.com>
52 Signed-off-by: David S. Miller <davem@davemloft.net>
53 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
54 ---
55 net/ipv6/sit.c | 5 +++--
56 1 file changed, 3 insertions(+), 2 deletions(-)
57
58 --- a/net/ipv6/sit.c
59 +++ b/net/ipv6/sit.c
60 @@ -767,8 +767,9 @@ static bool check_6rd(struct ip_tunnel *
61 pbw0 = tunnel->ip6rd.prefixlen >> 5;
62 pbi0 = tunnel->ip6rd.prefixlen & 0x1f;
63
64 - d = (ntohl(v6dst->s6_addr32[pbw0]) << pbi0) >>
65 - tunnel->ip6rd.relay_prefixlen;
66 + d = tunnel->ip6rd.relay_prefixlen < 32 ?
67 + (ntohl(v6dst->s6_addr32[pbw0]) << pbi0) >>
68 + tunnel->ip6rd.relay_prefixlen : 0;
69
70 pbi1 = pbi0 - tunnel->ip6rd.relay_prefixlen;
71 if (pbi1 > 0)