From patchwork Wed Jan 3 07:27:33 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrei Vagin X-Patchwork-Id: 854896 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="aVNmUKqN"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3zBMw007gDz9s75 for ; Wed, 3 Jan 2018 18:27:44 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751774AbeACH1l (ORCPT ); Wed, 3 Jan 2018 02:27:41 -0500 Received: from mail-pg0-f67.google.com ([74.125.83.67]:43904 "EHLO mail-pg0-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751764AbeACH1j (ORCPT ); Wed, 3 Jan 2018 02:27:39 -0500 Received: by mail-pg0-f67.google.com with SMTP id f18so410415pga.10 for ; Tue, 02 Jan 2018 23:27:39 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id; bh=5aEDtQIUY3bH11QMp0ssFNDK+qPioY0uymgDKhTSm1s=; b=aVNmUKqNKepelAoOX9ZXg4F+/1Eg9OVijwllOQWrDb+43DfJhriWyavQ+XW5aHwRpb s1UQelfGWs1J9JkSaj0fxhfHoPinmdkkAIITMjlp7cOrSTPKi/0CAYgQuSfeZcMutDqU F/GqNFwoDzuSPd1BQ3iHl2obYTaGUOcXw4uX2ZFINrff6F3fwFokY2rLQgrOqLzKzBPa vzL/Hax9chR32WwV7X3mZkVtAhtMZNNq5/Rn6tg6N6wXdkpTmI9VpxJCdbJEsCp/EzfS NqATk2ko3CLvUYV+6k4cXtpepPBpo46DrqzF4aGYpdOfYnhezAS1RAxG7hal0K23qRn9 OxZg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id; bh=5aEDtQIUY3bH11QMp0ssFNDK+qPioY0uymgDKhTSm1s=; b=OqXjT2nqssNS4b3mYkR18MV0RTGsndO+YWfr2RfCatZrvN+8XzDH/K7K+YG9ipuOBF sQGFIMDpC5cv+JHGSzmlC5khlUhZOXnw6jt1HUSol/B4M1i6ObKrm1/hkDv1MGqLXlPx BGiiDmakHJmGvrNWJ1VUMuaQNoD+tK0AOmvtMMneiAV9KNZmSnzhPzg5dBPH9IRfGJm5 oyaAYteSmEPPeIQADGFsUvLlwfty3Ba0kMTI4SZ1WyGr28WlOEg81LoFACdkP0TPRbbg yakv4OQCWDxSSWiKqj4qR0TVNBS1Rkjq/QCi0ykfKAPN9x1Uz2lz/DatILev7VCJ69Xo 38vg== X-Gm-Message-State: AKGB3mKhjzepeea2wuhb7pQmb/6xGmE8TkaI2EGZQbGGudN0K0XycfL5 aD9oIIhoc1/jd29JqSvG+Lg= X-Google-Smtp-Source: ACJfBot+pJu+R2iYxJ9CYOMr4mbqh0dx6B7yuYt0gZp7psL2/zGBEjL32cl6mdwa4ga16SK1zHmOyQ== X-Received: by 10.99.182.7 with SMTP id j7mr503442pgf.93.1514964458894; Tue, 02 Jan 2018 23:27:38 -0800 (PST) Received: from localhost.localdomain (c-73-140-212-29.hsd1.wa.comcast.net. [73.140.212.29]) by smtp.gmail.com with ESMTPSA id l80sm1253687pfk.67.2018.01.02.23.27.37 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 02 Jan 2018 23:27:38 -0800 (PST) From: Andrei Vagin To: "David S. Miller" , netdev@vger.kernel.org Cc: David Ahern , Florian Westphal , Andrei Vagin , Jiri Benc Subject: [PATCH] rtnetlink: give a user socket to get_target_net() Date: Tue, 2 Jan 2018 23:27:33 -0800 Message-Id: <20180103072733.9097-1-avagin@openvz.org> X-Mailer: git-send-email 2.13.6 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org This function is used from two places: rtnl_dump_ifinfo and rtnl_getlink. In rtnl_getlink(), we give a request skb into get_target_net(), but in rtnl_dump_ifinfo, we give a response skb into get_target_net(). The problem here is that NETLINK_CB() isn't initialized for the response skb. In both cases we can get a user socket and give it instead of skb into get_target_net(). This bug was found by syzkaller with this call-trace: kasan: GPF could be caused by NULL-ptr deref or user memory access general protection fault: 0000 [#1] SMP KASAN Modules linked in: CPU: 1 PID: 3149 Comm: syzkaller140561 Not tainted 4.15.0-rc4-mm1+ #47 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 RIP: 0010:__netlink_ns_capable+0x8b/0x120 net/netlink/af_netlink.c:868 RSP: 0018:ffff8801c880f348 EFLAGS: 00010206 RAX: dffffc0000000000 RBX: 0000000000000000 RCX: ffffffff8443f900 RDX: 000000000000007b RSI: ffffffff86510f40 RDI: 00000000000003d8 RBP: ffff8801c880f360 R08: 0000000000000000 R09: 1ffff10039101e4f R10: 0000000000000000 R11: 0000000000000001 R12: ffffffff86510f40 R13: 000000000000000c R14: 0000000000000004 R15: 0000000000000011 FS: 0000000001a1a880(0000) GS:ffff8801db300000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000020151000 CR3: 00000001c9511005 CR4: 00000000001606e0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: netlink_ns_capable+0x26/0x30 net/netlink/af_netlink.c:886 get_target_net+0x9d/0x120 net/core/rtnetlink.c:1765 rtnl_dump_ifinfo+0x2e5/0xee0 net/core/rtnetlink.c:1806 netlink_dump+0x48c/0xce0 net/netlink/af_netlink.c:2222 __netlink_dump_start+0x4f0/0x6d0 net/netlink/af_netlink.c:2319 netlink_dump_start include/linux/netlink.h:214 [inline] rtnetlink_rcv_msg+0x7f0/0xb10 net/core/rtnetlink.c:4485 netlink_rcv_skb+0x21e/0x460 net/netlink/af_netlink.c:2441 rtnetlink_rcv+0x1c/0x20 net/core/rtnetlink.c:4540 netlink_unicast_kernel net/netlink/af_netlink.c:1308 [inline] netlink_unicast+0x4be/0x6a0 net/netlink/af_netlink.c:1334 netlink_sendmsg+0xa4a/0xe60 net/netlink/af_netlink.c:1897 Cc: Jiri Benc Fixes: 79e1ad148c84 ("rtnetlink: use netnsid to query interface") Signed-off-by: Andrei Vagin --- net/core/rtnetlink.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index dabba2a91fc8..778d7f03404a 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c @@ -1681,18 +1681,18 @@ static bool link_dump_filtered(struct net_device *dev, return false; } -static struct net *get_target_net(struct sk_buff *skb, int netnsid) +static struct net *get_target_net(struct sock *sk, int netnsid) { struct net *net; - net = get_net_ns_by_id(sock_net(skb->sk), netnsid); + net = get_net_ns_by_id(sock_net(sk), netnsid); if (!net) return ERR_PTR(-EINVAL); /* For now, the caller is required to have CAP_NET_ADMIN in * the user namespace owning the target net ns. */ - if (!netlink_ns_capable(skb, net->user_ns, CAP_NET_ADMIN)) { + if (!sk_ns_capable(sk, net->user_ns, CAP_NET_ADMIN)) { put_net(net); return ERR_PTR(-EACCES); } @@ -1733,7 +1733,7 @@ static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb) ifla_policy, NULL) >= 0) { if (tb[IFLA_IF_NETNSID]) { netnsid = nla_get_s32(tb[IFLA_IF_NETNSID]); - tgt_net = get_target_net(skb, netnsid); + tgt_net = get_target_net(skb->sk, netnsid); if (IS_ERR(tgt_net)) { tgt_net = net; netnsid = -1; @@ -2883,7 +2883,7 @@ static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr *nlh, if (tb[IFLA_IF_NETNSID]) { netnsid = nla_get_s32(tb[IFLA_IF_NETNSID]); - tgt_net = get_target_net(skb, netnsid); + tgt_net = get_target_net(NETLINK_CB(skb).sk, netnsid); if (IS_ERR(tgt_net)) return PTR_ERR(tgt_net); }