From patchwork Tue Sep 4 19:53:49 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Brauner X-Patchwork-Id: 966067 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@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; dmarc=none (p=none dis=none) header.from=brauner.io Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 424cwp3Frnz9sBy for ; Wed, 5 Sep 2018 05:54:18 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728119AbeIEAUx (ORCPT ); Tue, 4 Sep 2018 20:20:53 -0400 Received: from mail-wm0-f67.google.com ([74.125.82.67]:35642 "EHLO mail-wm0-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727466AbeIEAUw (ORCPT ); Tue, 4 Sep 2018 20:20:52 -0400 Received: by mail-wm0-f67.google.com with SMTP id o18-v6so5483206wmc.0; Tue, 04 Sep 2018 12:54:13 -0700 (PDT) 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:in-reply-to :references; bh=Vgt87KYeAjeIkoBgyI5+YB6DhGbFDAp74UmjVTyrJkE=; b=Kym8ovVIPdUP2v769U6MtAfwpAbuw9ZtH5YEHLnwuGmdJiMGfrJNlXgBjmXOOrW1AF jZ/FpwQFocuVLCcl+Yx/+cpKFwfWt6jkyifHDjILM/1+AqlMwqM41/cwQSnII7UpS4rE kkOaYYn2ECl08ZuV3cf+lSn0PMeRXRy1Eh1kIfonawz+XYYSm+FBi3VpBh4N39ATfklG JqDL8UH0f9sOu+amVXoegzOoGu7oNYWr7WFmoDIe7eeUne9z+3fAoxf7iVlfscSi4M2/ h22s1+6YfhQMEDhM64wpFEVdCGgUJZEbiB82OEXB4zUaXBIERFXSklL5BvAXMg+Q5V4p 9DsA== X-Gm-Message-State: APzg51CKh9/rg1UdVFMaodHfMi6V8bbFPT2oa2R6z2mH1vNs06zxUkFU FhuVPLHbl1TugW1G7Z1XsnptvfYDagHGzA== X-Google-Smtp-Source: ANB0Vdbf246MaZBLp9RfDLYUWS3fM5S4uwp1o6xws8bvroH8HtunxK0ToZbwr4iKcqXUuGEaOYCTUQ== X-Received: by 2002:a1c:d702:: with SMTP id o2-v6mr8884305wmg.115.1536090852712; Tue, 04 Sep 2018 12:54:12 -0700 (PDT) Received: from localhost.localdomain ([2a02:8070:8895:9700:f474:3704:f9a0:fc57]) by smtp.gmail.com with ESMTPSA id 144-v6sm99440wma.19.2018.09.04.12.54.11 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 04 Sep 2018 12:54:12 -0700 (PDT) From: Christian Brauner To: netdev@vger.kernel.org, linux-kernel@vger.kernel.org Cc: davem@davemloft.net, kuznet@ms2.inr.ac.ru, yoshfuji@linux-ipv6.org, pombredanne@nexb.com, kstewart@linuxfoundation.org, gregkh@linuxfoundation.org, dsahern@gmail.com, fw@strlen.de, ktkhai@virtuozzo.com, lucien.xin@gmail.com, jakub.kicinski@netronome.com, jbenc@redhat.com, nicolas.dichtel@6wind.com, Christian Brauner Subject: [PATCH net-next v2 3/9] ipv4: enable IFA_TARGET_NETNSID for RTM_GETADDR Date: Tue, 4 Sep 2018 21:53:49 +0200 Message-Id: <20180904195355.4695-4-christian@brauner.io> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180904195355.4695-1-christian@brauner.io> References: <20180904195355.4695-1-christian@brauner.io> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org - Backwards Compatibility: If userspace wants to determine whether ipv4 RTM_GETADDR requests support the new IFA_TARGET_NETNSID property it should verify that the reply includes the IFA_TARGET_NETNSID property. If it does not userspace should assume that IFA_TARGET_NETNSID is not supported for ipv4 RTM_GETADDR requests on this kernel. - From what I gather from current userspace tools that make use of RTM_GETADDR requests some of them pass down struct ifinfomsg when they should actually pass down struct ifaddrmsg. To not break existing tools that pass down the wrong struct we will do the same as for RTM_GETLINK | NLM_F_DUMP requests and not error out when the nlmsg_parse() fails. - Security: Callers must have CAP_NET_ADMIN in the owning user namespace of the target network namespace. Signed-off-by: Christian Brauner --- v1->v2: - rename from IFA_IF_NETNSID to IFA_TARGET_NETNSID v0->v1: - unchanged --- net/ipv4/devinet.c | 38 ++++++++++++++++++++++++++++++-------- 1 file changed, 30 insertions(+), 8 deletions(-) diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c index ea4bd8a52422..5cb849300b81 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c @@ -100,6 +100,7 @@ static const struct nla_policy ifa_ipv4_policy[IFA_MAX+1] = { [IFA_CACHEINFO] = { .len = sizeof(struct ifa_cacheinfo) }, [IFA_FLAGS] = { .type = NLA_U32 }, [IFA_RT_PRIORITY] = { .type = NLA_U32 }, + [IFA_TARGET_NETNSID] = { .type = NLA_S32 }, }; #define IN4_ADDR_HSIZE_SHIFT 8 @@ -1584,7 +1585,8 @@ static int put_cacheinfo(struct sk_buff *skb, unsigned long cstamp, } static int inet_fill_ifaddr(struct sk_buff *skb, struct in_ifaddr *ifa, - u32 portid, u32 seq, int event, unsigned int flags) + u32 portid, u32 seq, int event, unsigned int flags, + int netnsid) { struct ifaddrmsg *ifm; struct nlmsghdr *nlh; @@ -1601,6 +1603,9 @@ static int inet_fill_ifaddr(struct sk_buff *skb, struct in_ifaddr *ifa, ifm->ifa_scope = ifa->ifa_scope; ifm->ifa_index = ifa->ifa_dev->dev->ifindex; + if (netnsid >= 0 && nla_put_s32(skb, IFA_TARGET_NETNSID, netnsid)) + goto nla_put_failure; + if (!(ifm->ifa_flags & IFA_F_PERMANENT)) { preferred = ifa->ifa_preferred_lft; valid = ifa->ifa_valid_lft; @@ -1648,6 +1653,9 @@ static int inet_fill_ifaddr(struct sk_buff *skb, struct in_ifaddr *ifa, static int inet_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb) { struct net *net = sock_net(skb->sk); + struct nlattr *tb[IFA_MAX+1]; + struct net *tgt_net = net; + int netnsid = -1; int h, s_h; int idx, s_idx; int ip_idx, s_ip_idx; @@ -1660,12 +1668,23 @@ static int inet_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb) s_idx = idx = cb->args[1]; s_ip_idx = ip_idx = cb->args[2]; + if (nlmsg_parse(cb->nlh, sizeof(struct ifaddrmsg), tb, IFA_MAX, + ifa_ipv4_policy, NULL) >= 0) { + if (tb[IFA_TARGET_NETNSID]) { + netnsid = nla_get_s32(tb[IFA_TARGET_NETNSID]); + + tgt_net = rtnl_get_net_ns_capable(skb->sk, netnsid); + if (IS_ERR(tgt_net)) + return PTR_ERR(tgt_net); + } + } + for (h = s_h; h < NETDEV_HASHENTRIES; h++, s_idx = 0) { idx = 0; - head = &net->dev_index_head[h]; + head = &tgt_net->dev_index_head[h]; rcu_read_lock(); - cb->seq = atomic_read(&net->ipv4.dev_addr_genid) ^ - net->dev_base_seq; + cb->seq = atomic_read(&tgt_net->ipv4.dev_addr_genid) ^ + tgt_net->dev_base_seq; hlist_for_each_entry_rcu(dev, head, index_hlist) { if (idx < s_idx) goto cont; @@ -1680,9 +1699,10 @@ static int inet_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb) if (ip_idx < s_ip_idx) continue; if (inet_fill_ifaddr(skb, ifa, - NETLINK_CB(cb->skb).portid, - cb->nlh->nlmsg_seq, - RTM_NEWADDR, NLM_F_MULTI) < 0) { + NETLINK_CB(cb->skb).portid, + cb->nlh->nlmsg_seq, + RTM_NEWADDR, NLM_F_MULTI, + netnsid) < 0) { rcu_read_unlock(); goto done; } @@ -1698,6 +1718,8 @@ static int inet_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb) cb->args[0] = h; cb->args[1] = idx; cb->args[2] = ip_idx; + if (netnsid >= 0) + put_net(tgt_net); return skb->len; } @@ -1715,7 +1737,7 @@ static void rtmsg_ifa(int event, struct in_ifaddr *ifa, struct nlmsghdr *nlh, if (!skb) goto errout; - err = inet_fill_ifaddr(skb, ifa, portid, seq, event, 0); + err = inet_fill_ifaddr(skb, ifa, portid, seq, event, 0, -1); if (err < 0) { /* -EMSGSIZE implies BUG in inet_nlmsg_size() */ WARN_ON(err == -EMSGSIZE);