From patchwork Wed May 3 15:06:58 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Potapenko X-Patchwork-Id: 758099 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3wJ1jV2lmdz9rxm for ; Thu, 4 May 2017 01:07:26 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=google.com header.i=@google.com header.b="CJtwjWXb"; dkim-atps=neutral Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752337AbdECPHN (ORCPT ); Wed, 3 May 2017 11:07:13 -0400 Received: from mail-wm0-f46.google.com ([74.125.82.46]:38604 "EHLO mail-wm0-f46.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751851AbdECPHE (ORCPT ); Wed, 3 May 2017 11:07:04 -0400 Received: by mail-wm0-f46.google.com with SMTP id r190so62046763wme.1 for ; Wed, 03 May 2017 08:07:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=from:to:cc:subject:date:message-id; bh=vadYYsy1p/ab/mOwSCRNf9ONHtn400hpK691FaSw/Fg=; b=CJtwjWXbad3Qp8/2JukC0NTqnU1/V5y4FyqGQPkM2Dmg8JNnJrI0panLQqOCpJJmsc 0sppRogS06ci39u9ADfXtXBwWSOJmzO+8oB5erjAg0WOZfmlzocXqIKnA1HNqQ5LH9du quXxxkQDABK68RqjFo+qqdblui3VJtBSmSBCMRkh3UeC2jFFugwgiTirgpjMw5xLoH3u EUEXIgv2/K4yHlRDTIn97yxrYqsnSU/I/SiloUolveHDBcjHz6TfLmfUE3UlSfrpKINc xkn4ogdHXi6V49d/u/3AoaM2f0ygcUf/6s1JF0kZEkyjookvmDZxkfSxojJUEnzTf3qx gFTQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=vadYYsy1p/ab/mOwSCRNf9ONHtn400hpK691FaSw/Fg=; b=rJyaHEXbG67n9+zNJ2+lywODCbRR8U8Z2Usndtm0Sq7K6Y5PcvAp7Sv/Y6p3IdZ662 BH0kXyHhtj14kRSyJH0HwPMt91ZB4VVMGW8ppO70aU0Ded1EGxHiaduhL+BVGHGE4GTG ZwqjZtC1Okt3T/VDGyO35m1dB9C1AxkDEwWDMxhxv/U+G2Nq7bOhcEEXZYJiws/8m4dO EGDCQuLhGK+Si1bk0iYW081zm4nMafFktCTrM4FWKup5SlQ/PBRis83eF55azepTxPok +5ozIn7lHc/aO1Ikvwga1VkRTXbFMvMrcYnRMSJqtR4i3ZJzzCBe3Svqn/Mzm/gfl6C0 EmiQ== X-Gm-Message-State: AN3rC/6E+pzOg+oJGJrigL+srjfZzllfRgCGRD2VYw9hqci5DjG/Ys6w 099qbj/7sIGyi/Yu X-Received: by 10.28.132.76 with SMTP id g73mr6920774wmd.63.1493824022410; Wed, 03 May 2017 08:07:02 -0700 (PDT) Received: from glider0.muc.corp.google.com ([100.105.28.21]) by smtp.gmail.com with ESMTPSA id a197sm1101125wma.1.2017.05.03.08.07.01 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 03 May 2017 08:07:01 -0700 (PDT) From: Alexander Potapenko To: dvyukov@google.com, kcc@google.com, edumazet@google.com, davem@davemloft.net, kuznet@ms2.inr.ac.ru Cc: linux-kernel@vger.kernel.org, netdev@vger.kernel.org Subject: [PATCH] ipv4, ipv6: ensure raw socket message is big enough to hold an IP header Date: Wed, 3 May 2017 17:06:58 +0200 Message-Id: <20170503150658.44421-1-glider@google.com> X-Mailer: git-send-email 2.13.0.rc1.294.g07d810a77f-goog Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org raw_send_hdrinc() and rawv6_send_hdrinc() expect that the buffer copied from the userspace contains the IPv4/IPv6 header, so if too few bytes are copied, parts of the header may remain uninitialized. This bug has been detected with KMSAN. Signed-off-by: Alexander Potapenko --- The previous version of this patch was called "ipv6: ensure message length for raw socket is at least sizeof(ipv6hdr)" For the record, the KMSAN report: ================================================================== BUG: KMSAN: use of unitialized memory in nf_ct_frag6_gather+0xf5a/0x44a0 inter: 0 CPU: 0 PID: 1036 Comm: probe Not tainted 4.11.0-rc5+ #2455 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011 Call Trace: __dump_stack lib/dump_stack.c:16 dump_stack+0x143/0x1b0 lib/dump_stack.c:52 kmsan_report+0x16b/0x1e0 mm/kmsan/kmsan.c:1078 __kmsan_warning_32+0x5c/0xa0 mm/kmsan/kmsan_instr.c:510 nf_ct_frag6_gather+0xf5a/0x44a0 net/ipv6/netfilter/nf_conntrack_reasm.c:577 ipv6_defrag+0x1d9/0x280 net/ipv6/netfilter/nf_defrag_ipv6_hooks.c:68 nf_hook_entry_hookfn ./include/linux/netfilter.h:102 nf_hook_slow+0x13f/0x3c0 net/netfilter/core.c:310 nf_hook ./include/linux/netfilter.h:212 NF_HOOK ./include/linux/netfilter.h:255 rawv6_send_hdrinc net/ipv6/raw.c:673 rawv6_sendmsg+0x2fcb/0x41a0 net/ipv6/raw.c:919 inet_sendmsg+0x3f8/0x6d0 net/ipv4/af_inet.c:762 sock_sendmsg_nosec net/socket.c:633 sock_sendmsg net/socket.c:643 SYSC_sendto+0x6a5/0x7c0 net/socket.c:1696 SyS_sendto+0xbc/0xe0 net/socket.c:1664 do_syscall_64+0x72/0xa0 arch/x86/entry/common.c:285 entry_SYSCALL64_slow_path+0x25/0x25 arch/x86/entry/entry_64.S:246 RIP: 0033:0x436e03 RSP: 002b:00007ffce48baf38 EFLAGS: 00000246 ORIG_RAX: 000000000000002c RAX: ffffffffffffffda RBX: 00000000004002b0 RCX: 0000000000436e03 RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000003 RBP: 00007ffce48baf90 R08: 00007ffce48baf50 R09: 000000000000001c R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000 R13: 0000000000401790 R14: 0000000000401820 R15: 0000000000000000 origin: 00000000d9400053 save_stack_trace+0x16/0x20 arch/x86/kernel/stacktrace.c:59 kmsan_save_stack_with_flags mm/kmsan/kmsan.c:362 kmsan_internal_poison_shadow+0xb1/0x1a0 mm/kmsan/kmsan.c:257 kmsan_poison_shadow+0x6d/0xc0 mm/kmsan/kmsan.c:270 slab_alloc_node mm/slub.c:2735 __kmalloc_node_track_caller+0x1f4/0x390 mm/slub.c:4341 __kmalloc_reserve net/core/skbuff.c:138 __alloc_skb+0x2cd/0x740 net/core/skbuff.c:231 alloc_skb ./include/linux/skbuff.h:933 alloc_skb_with_frags+0x209/0xbc0 net/core/skbuff.c:4678 sock_alloc_send_pskb+0x9ff/0xe00 net/core/sock.c:1903 sock_alloc_send_skb+0xe4/0x100 net/core/sock.c:1920 rawv6_send_hdrinc net/ipv6/raw.c:638 rawv6_sendmsg+0x2918/0x41a0 net/ipv6/raw.c:919 inet_sendmsg+0x3f8/0x6d0 net/ipv4/af_inet.c:762 sock_sendmsg_nosec net/socket.c:633 sock_sendmsg net/socket.c:643 SYSC_sendto+0x6a5/0x7c0 net/socket.c:1696 SyS_sendto+0xbc/0xe0 net/socket.c:1664 do_syscall_64+0x72/0xa0 arch/x86/entry/common.c:285 return_from_SYSCALL_64+0x0/0x6a arch/x86/entry/entry_64.S:246 ================================================================== , triggered by the following syscalls: socket(PF_INET6, SOCK_RAW, IPPROTO_RAW) = 3 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 A similar report is triggered in net/ipv4/raw.c if we use a PF_INET socket instead of a PF_INET6 one. --- net/ipv4/raw.c | 3 +++ net/ipv6/raw.c | 2 ++ 2 files changed, 5 insertions(+) diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c index 9d943974de2b..bdffad875691 100644 --- a/net/ipv4/raw.c +++ b/net/ipv4/raw.c @@ -358,6 +358,9 @@ static int raw_send_hdrinc(struct sock *sk, struct flowi4 *fl4, rt->dst.dev->mtu); return -EMSGSIZE; } + if (length < sizeof(struct iphdr)) + return -EINVAL; + if (flags&MSG_PROBE) goto out; diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index f174e76e6505..805464668bd8 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c @@ -632,6 +632,8 @@ static int rawv6_send_hdrinc(struct sock *sk, struct msghdr *msg, int length, ipv6_local_error(sk, EMSGSIZE, fl6, rt->dst.dev->mtu); return -EMSGSIZE; } + if (length < sizeof(struct ipv6hdr)) + return -EINVAL; if (flags&MSG_PROBE) goto out;