]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - releases/4.9.28/ipv4-ipv6-ensure-raw-socket-message-is-big-enough-to-hold-an-ip-header.patch
5.1-stable patches
[thirdparty/kernel/stable-queue.git] / releases / 4.9.28 / ipv4-ipv6-ensure-raw-socket-message-is-big-enough-to-hold-an-ip-header.patch
1 From foo@baz Thu May 11 11:08:24 CEST 2017
2 From: Alexander Potapenko <glider@google.com>
3 Date: Wed, 3 May 2017 17:06:58 +0200
4 Subject: ipv4, ipv6: ensure raw socket message is big enough to hold an IP header
5
6 From: Alexander Potapenko <glider@google.com>
7
8
9 [ Upstream commit 86f4c90a1c5c1493f07f2d12c1079f5bf01936f2 ]
10
11 raw_send_hdrinc() and rawv6_send_hdrinc() expect that the buffer copied
12 from the userspace contains the IPv4/IPv6 header, so if too few bytes are
13 copied, parts of the header may remain uninitialized.
14
15 This bug has been detected with KMSAN.
16
17 For the record, the KMSAN report:
18
19 ==================================================================
20 BUG: KMSAN: use of unitialized memory in nf_ct_frag6_gather+0xf5a/0x44a0
21 inter: 0
22 CPU: 0 PID: 1036 Comm: probe Not tainted 4.11.0-rc5+ #2455
23 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011
24 Call Trace:
25 __dump_stack lib/dump_stack.c:16
26 dump_stack+0x143/0x1b0 lib/dump_stack.c:52
27 kmsan_report+0x16b/0x1e0 mm/kmsan/kmsan.c:1078
28 __kmsan_warning_32+0x5c/0xa0 mm/kmsan/kmsan_instr.c:510
29 nf_ct_frag6_gather+0xf5a/0x44a0 net/ipv6/netfilter/nf_conntrack_reasm.c:577
30 ipv6_defrag+0x1d9/0x280 net/ipv6/netfilter/nf_defrag_ipv6_hooks.c:68
31 nf_hook_entry_hookfn ./include/linux/netfilter.h:102
32 nf_hook_slow+0x13f/0x3c0 net/netfilter/core.c:310
33 nf_hook ./include/linux/netfilter.h:212
34 NF_HOOK ./include/linux/netfilter.h:255
35 rawv6_send_hdrinc net/ipv6/raw.c:673
36 rawv6_sendmsg+0x2fcb/0x41a0 net/ipv6/raw.c:919
37 inet_sendmsg+0x3f8/0x6d0 net/ipv4/af_inet.c:762
38 sock_sendmsg_nosec net/socket.c:633
39 sock_sendmsg net/socket.c:643
40 SYSC_sendto+0x6a5/0x7c0 net/socket.c:1696
41 SyS_sendto+0xbc/0xe0 net/socket.c:1664
42 do_syscall_64+0x72/0xa0 arch/x86/entry/common.c:285
43 entry_SYSCALL64_slow_path+0x25/0x25 arch/x86/entry/entry_64.S:246
44 RIP: 0033:0x436e03
45 RSP: 002b:00007ffce48baf38 EFLAGS: 00000246 ORIG_RAX: 000000000000002c
46 RAX: ffffffffffffffda RBX: 00000000004002b0 RCX: 0000000000436e03
47 RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000003
48 RBP: 00007ffce48baf90 R08: 00007ffce48baf50 R09: 000000000000001c
49 R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000
50 R13: 0000000000401790 R14: 0000000000401820 R15: 0000000000000000
51 origin: 00000000d9400053
52 save_stack_trace+0x16/0x20 arch/x86/kernel/stacktrace.c:59
53 kmsan_save_stack_with_flags mm/kmsan/kmsan.c:362
54 kmsan_internal_poison_shadow+0xb1/0x1a0 mm/kmsan/kmsan.c:257
55 kmsan_poison_shadow+0x6d/0xc0 mm/kmsan/kmsan.c:270
56 slab_alloc_node mm/slub.c:2735
57 __kmalloc_node_track_caller+0x1f4/0x390 mm/slub.c:4341
58 __kmalloc_reserve net/core/skbuff.c:138
59 __alloc_skb+0x2cd/0x740 net/core/skbuff.c:231
60 alloc_skb ./include/linux/skbuff.h:933
61 alloc_skb_with_frags+0x209/0xbc0 net/core/skbuff.c:4678
62 sock_alloc_send_pskb+0x9ff/0xe00 net/core/sock.c:1903
63 sock_alloc_send_skb+0xe4/0x100 net/core/sock.c:1920
64 rawv6_send_hdrinc net/ipv6/raw.c:638
65 rawv6_sendmsg+0x2918/0x41a0 net/ipv6/raw.c:919
66 inet_sendmsg+0x3f8/0x6d0 net/ipv4/af_inet.c:762
67 sock_sendmsg_nosec net/socket.c:633
68 sock_sendmsg net/socket.c:643
69 SYSC_sendto+0x6a5/0x7c0 net/socket.c:1696
70 SyS_sendto+0xbc/0xe0 net/socket.c:1664
71 do_syscall_64+0x72/0xa0 arch/x86/entry/common.c:285
72 return_from_SYSCALL_64+0x0/0x6a arch/x86/entry/entry_64.S:246
73 ==================================================================
74
75 , triggered by the following syscalls:
76 socket(PF_INET6, SOCK_RAW, IPPROTO_RAW) = 3
77 sendto(3, NULL, 0, 0, {sa_family=AF_INET6, sin6_port=htons(0), inet_pton(AF_INET6, "ff00::", &sin6_addr), sin6_flowinfo=0, sin6_scope_id=0}, 28) = -1 EPERM
78
79 A similar report is triggered in net/ipv4/raw.c if we use a PF_INET socket
80 instead of a PF_INET6 one.
81
82 Signed-off-by: Alexander Potapenko <glider@google.com>
83 Signed-off-by: David S. Miller <davem@davemloft.net>
84 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
85 ---
86 net/ipv4/raw.c | 3 +++
87 net/ipv6/raw.c | 2 ++
88 2 files changed, 5 insertions(+)
89
90 --- a/net/ipv4/raw.c
91 +++ b/net/ipv4/raw.c
92 @@ -356,6 +356,9 @@ static int raw_send_hdrinc(struct sock *
93 rt->dst.dev->mtu);
94 return -EMSGSIZE;
95 }
96 + if (length < sizeof(struct iphdr))
97 + return -EINVAL;
98 +
99 if (flags&MSG_PROBE)
100 goto out;
101
102 --- a/net/ipv6/raw.c
103 +++ b/net/ipv6/raw.c
104 @@ -630,6 +630,8 @@ static int rawv6_send_hdrinc(struct sock
105 ipv6_local_error(sk, EMSGSIZE, fl6, rt->dst.dev->mtu);
106 return -EMSGSIZE;
107 }
108 + if (length < sizeof(struct ipv6hdr))
109 + return -EINVAL;
110 if (flags&MSG_PROBE)
111 goto out;
112