| From: Eric Dumazet <edumazet@google.com> |
| Date: Wed, 11 Apr 2018 14:36:28 -0700 |
| Subject: tcp: md5: reject TCP_MD5SIG or TCP_MD5SIG_EXT on established sockets |
| |
| commit 7212303268918b9a203aebeacfdbd83b5e87b20d upstream. |
| |
| syzbot/KMSAN reported an uninit-value in tcp_parse_options() [1] |
| |
| I believe this was caused by a TCP_MD5SIG being set on live |
| flow. |
| |
| This is highly unexpected, since TCP option space is limited. |
| |
| For instance, presence of TCP MD5 option automatically disables |
| TCP TimeStamp option at SYN/SYNACK time, which we can not do |
| once flow has been established. |
| |
| Really, adding/deleting an MD5 key only makes sense on sockets |
| in CLOSE or LISTEN state. |
| |
| [1] |
| BUG: KMSAN: uninit-value in tcp_parse_options+0xd74/0x1a30 net/ipv4/tcp_input.c:3720 |
| CPU: 1 PID: 6177 Comm: syzkaller192004 Not tainted 4.16.0+ #83 |
| Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 |
| Call Trace: |
| __dump_stack lib/dump_stack.c:17 [inline] |
| dump_stack+0x185/0x1d0 lib/dump_stack.c:53 |
| kmsan_report+0x142/0x240 mm/kmsan/kmsan.c:1067 |
| __msan_warning_32+0x6c/0xb0 mm/kmsan/kmsan_instr.c:676 |
| tcp_parse_options+0xd74/0x1a30 net/ipv4/tcp_input.c:3720 |
| tcp_fast_parse_options net/ipv4/tcp_input.c:3858 [inline] |
| tcp_validate_incoming+0x4f1/0x2790 net/ipv4/tcp_input.c:5184 |
| tcp_rcv_established+0xf60/0x2bb0 net/ipv4/tcp_input.c:5453 |
| tcp_v4_do_rcv+0x6cd/0xd90 net/ipv4/tcp_ipv4.c:1469 |
| sk_backlog_rcv include/net/sock.h:908 [inline] |
| __release_sock+0x2d6/0x680 net/core/sock.c:2271 |
| release_sock+0x97/0x2a0 net/core/sock.c:2786 |
| tcp_sendmsg+0xd6/0x100 net/ipv4/tcp.c:1464 |
| inet_sendmsg+0x48d/0x740 net/ipv4/af_inet.c:764 |
| sock_sendmsg_nosec net/socket.c:630 [inline] |
| sock_sendmsg net/socket.c:640 [inline] |
| SYSC_sendto+0x6c3/0x7e0 net/socket.c:1747 |
| SyS_sendto+0x8a/0xb0 net/socket.c:1715 |
| do_syscall_64+0x309/0x430 arch/x86/entry/common.c:287 |
| entry_SYSCALL_64_after_hwframe+0x3d/0xa2 |
| RIP: 0033:0x448fe9 |
| RSP: 002b:00007fd472c64d38 EFLAGS: 00000216 ORIG_RAX: 000000000000002c |
| RAX: ffffffffffffffda RBX: 00000000006e5a30 RCX: 0000000000448fe9 |
| RDX: 000000000000029f RSI: 0000000020a88f88 RDI: 0000000000000004 |
| RBP: 00000000006e5a34 R08: 0000000020e68000 R09: 0000000000000010 |
| R10: 00000000200007fd R11: 0000000000000216 R12: 0000000000000000 |
| R13: 00007fff074899ef R14: 00007fd472c659c0 R15: 0000000000000009 |
| |
| Uninit was created at: |
| kmsan_save_stack_with_flags mm/kmsan/kmsan.c:278 [inline] |
| kmsan_internal_poison_shadow+0xb8/0x1b0 mm/kmsan/kmsan.c:188 |
| kmsan_kmalloc+0x94/0x100 mm/kmsan/kmsan.c:314 |
| kmsan_slab_alloc+0x11/0x20 mm/kmsan/kmsan.c:321 |
| slab_post_alloc_hook mm/slab.h:445 [inline] |
| slab_alloc_node mm/slub.c:2737 [inline] |
| __kmalloc_node_track_caller+0xaed/0x11c0 mm/slub.c:4369 |
| __kmalloc_reserve net/core/skbuff.c:138 [inline] |
| __alloc_skb+0x2cf/0x9f0 net/core/skbuff.c:206 |
| alloc_skb include/linux/skbuff.h:984 [inline] |
| tcp_send_ack+0x18c/0x910 net/ipv4/tcp_output.c:3624 |
| __tcp_ack_snd_check net/ipv4/tcp_input.c:5040 [inline] |
| tcp_ack_snd_check net/ipv4/tcp_input.c:5053 [inline] |
| tcp_rcv_established+0x2103/0x2bb0 net/ipv4/tcp_input.c:5469 |
| tcp_v4_do_rcv+0x6cd/0xd90 net/ipv4/tcp_ipv4.c:1469 |
| sk_backlog_rcv include/net/sock.h:908 [inline] |
| __release_sock+0x2d6/0x680 net/core/sock.c:2271 |
| release_sock+0x97/0x2a0 net/core/sock.c:2786 |
| tcp_sendmsg+0xd6/0x100 net/ipv4/tcp.c:1464 |
| inet_sendmsg+0x48d/0x740 net/ipv4/af_inet.c:764 |
| sock_sendmsg_nosec net/socket.c:630 [inline] |
| sock_sendmsg net/socket.c:640 [inline] |
| SYSC_sendto+0x6c3/0x7e0 net/socket.c:1747 |
| SyS_sendto+0x8a/0xb0 net/socket.c:1715 |
| do_syscall_64+0x309/0x430 arch/x86/entry/common.c:287 |
| entry_SYSCALL_64_after_hwframe+0x3d/0xa2 |
| |
| Fixes: cfb6eeb4c860 ("[TCP]: MD5 Signature Option (RFC2385) support.") |
| Signed-off-by: Eric Dumazet <edumazet@google.com> |
| Reported-by: syzbot <syzkaller@googlegroups.com> |
| Acked-by: Yuchung Cheng <ycheng@google.com> |
| Signed-off-by: David S. Miller <davem@davemloft.net> |
| [bwh: Backported to 3.16: adjust context] |
| Signed-off-by: Ben Hutchings <ben@decadent.org.uk> |
| --- |
| net/ipv4/tcp.c | 6 ++++-- |
| 1 file changed, 4 insertions(+), 2 deletions(-) |
| |
| --- a/net/ipv4/tcp.c |
| +++ b/net/ipv4/tcp.c |
| @@ -2683,8 +2683,10 @@ static int do_tcp_setsockopt(struct sock |
| |
| #ifdef CONFIG_TCP_MD5SIG |
| case TCP_MD5SIG: |
| - /* Read the IP->Key mappings from userspace */ |
| - err = tp->af_specific->md5_parse(sk, optval, optlen); |
| + if ((1 << sk->sk_state) & (TCPF_CLOSE | TCPF_LISTEN)) |
| + err = tp->af_specific->md5_parse(sk, optval, optlen); |
| + else |
| + err = -EINVAL; |
| break; |
| #endif |
| case TCP_USER_TIMEOUT: |