From patchwork Mon Jul 15 10:00:20 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicolas Dichtel X-Patchwork-Id: 1131910 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=6wind.com Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 45nJtw122Nz9sP7 for ; Mon, 15 Jul 2019 20:00:40 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729735AbfGOKAi (ORCPT ); Mon, 15 Jul 2019 06:00:38 -0400 Received: from host.76.145.23.62.rev.coltfrance.com ([62.23.145.76]:35104 "EHLO proxy.6wind.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729709AbfGOKAe (ORCPT ); Mon, 15 Jul 2019 06:00:34 -0400 Received: from bretzel.dev.6wind.com (unknown [10.16.0.19]) by proxy.6wind.com (Postfix) with ESMTPS id 188F12E8834; Mon, 15 Jul 2019 12:00:31 +0200 (CEST) Received: from dichtel by bretzel.dev.6wind.com with local (Exim 4.89) (envelope-from ) id 1hmxmY-0002E5-PX; Mon, 15 Jul 2019 12:00:30 +0200 From: Nicolas Dichtel To: steffen.klassert@secunet.com, davem@davemloft.net Cc: netdev@vger.kernel.org, Nicolas Dichtel , Julien Floret Subject: [PATCH ipsec v2 1/4] xfrm interface: avoid corruption on changelink Date: Mon, 15 Jul 2019 12:00:20 +0200 Message-Id: <20190715100023.8475-2-nicolas.dichtel@6wind.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190715100023.8475-1-nicolas.dichtel@6wind.com> References: <20190715100023.8475-1-nicolas.dichtel@6wind.com> MIME-Version: 1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org The new parameters must not be stored in the netdev_priv() before validation, it may corrupt the interface. Note also that if data is NULL, only a memset() is done. $ ip link add xfrm1 type xfrm dev lo if_id 1 $ ip link add xfrm2 type xfrm dev lo if_id 2 $ ip link set xfrm1 type xfrm dev lo if_id 2 RTNETLINK answers: File exists $ ip -d link list dev xfrm1 5: xfrm1@lo: mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000 link/none 00:00:00:00:00:00 brd 00:00:00:00:00:00 promiscuity 0 minmtu 68 maxmtu 1500 xfrm if_id 0x2 addrgenmode eui64 numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535 => "if_id 0x2" Fixes: f203b76d7809 ("xfrm: Add virtual xfrm interfaces") Signed-off-by: Nicolas Dichtel Tested-by: Julien Floret --- net/xfrm/xfrm_interface.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/net/xfrm/xfrm_interface.c b/net/xfrm/xfrm_interface.c index 74868f9d81fb..2310dc9e35c2 100644 --- a/net/xfrm/xfrm_interface.c +++ b/net/xfrm/xfrm_interface.c @@ -671,12 +671,12 @@ static int xfrmi_changelink(struct net_device *dev, struct nlattr *tb[], struct nlattr *data[], struct netlink_ext_ack *extack) { - struct xfrm_if *xi = netdev_priv(dev); struct net *net = dev_net(dev); + struct xfrm_if_parms p; + struct xfrm_if *xi; - xfrmi_netlink_parms(data, &xi->p); - - xi = xfrmi_locate(net, &xi->p); + xfrmi_netlink_parms(data, &p); + xi = xfrmi_locate(net, &p); if (!xi) { xi = netdev_priv(dev); } else { @@ -684,7 +684,7 @@ static int xfrmi_changelink(struct net_device *dev, struct nlattr *tb[], return -EEXIST; } - return xfrmi_update(xi, &xi->p); + return xfrmi_update(xi, &p); } static size_t xfrmi_get_size(const struct net_device *dev) From patchwork Mon Jul 15 10:00:21 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicolas Dichtel X-Patchwork-Id: 1131908 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=6wind.com Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 45nJts0fNnz9sP7 for ; Mon, 15 Jul 2019 20:00:37 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729727AbfGOKAf (ORCPT ); Mon, 15 Jul 2019 06:00:35 -0400 Received: from host.76.145.23.62.rev.coltfrance.com ([62.23.145.76]:35107 "EHLO proxy.6wind.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729702AbfGOKAe (ORCPT ); Mon, 15 Jul 2019 06:00:34 -0400 Received: from bretzel.dev.6wind.com (unknown [10.16.0.19]) by proxy.6wind.com (Postfix) with ESMTPS id 2A43B2E8835; Mon, 15 Jul 2019 12:00:31 +0200 (CEST) Received: from dichtel by bretzel.dev.6wind.com with local (Exim 4.89) (envelope-from ) id 1hmxmZ-0002E8-2Q; Mon, 15 Jul 2019 12:00:31 +0200 From: Nicolas Dichtel To: steffen.klassert@secunet.com, davem@davemloft.net Cc: netdev@vger.kernel.org, Nicolas Dichtel Subject: [PATCH ipsec v2 2/4] xfrm interface: ifname may be wrong in logs Date: Mon, 15 Jul 2019 12:00:21 +0200 Message-Id: <20190715100023.8475-3-nicolas.dichtel@6wind.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190715100023.8475-1-nicolas.dichtel@6wind.com> References: <20190715100023.8475-1-nicolas.dichtel@6wind.com> MIME-Version: 1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org The ifname is copied when the interface is created, but is never updated later. In fact, this property is used only in one error message, where the netdevice pointer is available, thus let's use it. Fixes: f203b76d7809 ("xfrm: Add virtual xfrm interfaces") Signed-off-by: Nicolas Dichtel --- include/net/xfrm.h | 1 - net/xfrm/xfrm_interface.c | 10 +--------- 2 files changed, 1 insertion(+), 10 deletions(-) diff --git a/include/net/xfrm.h b/include/net/xfrm.h index b22db30c3d88..ad761ef84797 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h @@ -983,7 +983,6 @@ static inline void xfrm_dst_destroy(struct xfrm_dst *xdst) void xfrm_dst_ifdown(struct dst_entry *dst, struct net_device *dev); struct xfrm_if_parms { - char name[IFNAMSIZ]; /* name of XFRM device */ int link; /* ifindex of underlying L2 interface */ u32 if_id; /* interface identifyer */ }; diff --git a/net/xfrm/xfrm_interface.c b/net/xfrm/xfrm_interface.c index 2310dc9e35c2..68336ee00d72 100644 --- a/net/xfrm/xfrm_interface.c +++ b/net/xfrm/xfrm_interface.c @@ -145,8 +145,6 @@ static int xfrmi_create(struct net_device *dev) if (err < 0) goto out; - strcpy(xi->p.name, dev->name); - dev_hold(dev); xfrmi_link(xfrmn, xi); @@ -294,7 +292,7 @@ xfrmi_xmit2(struct sk_buff *skb, struct net_device *dev, struct flowi *fl) if (tdev == dev) { stats->collisions++; net_warn_ratelimited("%s: Local routing loop detected!\n", - xi->p.name); + dev->name); goto tx_err_dst_release; } @@ -638,12 +636,6 @@ static int xfrmi_newlink(struct net *src_net, struct net_device *dev, int err; xfrmi_netlink_parms(data, &p); - - if (!tb[IFLA_IFNAME]) - return -EINVAL; - - nla_strlcpy(p.name, tb[IFLA_IFNAME], IFNAMSIZ); - xi = xfrmi_locate(net, &p); if (xi) return -EEXIST; From patchwork Mon Jul 15 10:00:22 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicolas Dichtel X-Patchwork-Id: 1131906 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=6wind.com Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 45nJtq47hLz9sP7 for ; Mon, 15 Jul 2019 20:00:35 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729722AbfGOKAe (ORCPT ); Mon, 15 Jul 2019 06:00:34 -0400 Received: from host.76.145.23.62.rev.coltfrance.com ([62.23.145.76]:35110 "EHLO proxy.6wind.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729707AbfGOKAe (ORCPT ); Mon, 15 Jul 2019 06:00:34 -0400 Received: from bretzel.dev.6wind.com (unknown [10.16.0.19]) by proxy.6wind.com (Postfix) with ESMTPS id 3FF6B2E8836; Mon, 15 Jul 2019 12:00:31 +0200 (CEST) Received: from dichtel by bretzel.dev.6wind.com with local (Exim 4.89) (envelope-from ) id 1hmxmZ-0002EB-4u; Mon, 15 Jul 2019 12:00:31 +0200 From: Nicolas Dichtel To: steffen.klassert@secunet.com, davem@davemloft.net Cc: netdev@vger.kernel.org, Nicolas Dichtel , Julien Floret Subject: [PATCH ipsec v2 3/4] xfrm interface: fix list corruption for x-netns Date: Mon, 15 Jul 2019 12:00:22 +0200 Message-Id: <20190715100023.8475-4-nicolas.dichtel@6wind.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190715100023.8475-1-nicolas.dichtel@6wind.com> References: <20190715100023.8475-1-nicolas.dichtel@6wind.com> MIME-Version: 1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org dev_net(dev) is the netns of the device and xi->net is the link netns, where the device has been linked. changelink() must operate in the link netns to avoid a corruption of the xfrm lists. Note that xi->net and dev_net(xi->physdev) are always the same. Before the patch, the xfrmi lists may be corrupted and can later trigger a kernel panic. Fixes: f203b76d7809 ("xfrm: Add virtual xfrm interfaces") Reported-by: Julien Floret Signed-off-by: Nicolas Dichtel Tested-by: Julien Floret --- net/xfrm/xfrm_interface.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/net/xfrm/xfrm_interface.c b/net/xfrm/xfrm_interface.c index 68336ee00d72..53e5e47b2c55 100644 --- a/net/xfrm/xfrm_interface.c +++ b/net/xfrm/xfrm_interface.c @@ -503,7 +503,7 @@ static int xfrmi_change(struct xfrm_if *xi, const struct xfrm_if_parms *p) static int xfrmi_update(struct xfrm_if *xi, struct xfrm_if_parms *p) { - struct net *net = dev_net(xi->dev); + struct net *net = xi->net; struct xfrmi_net *xfrmn = net_generic(net, xfrmi_net_id); int err; @@ -663,9 +663,9 @@ static int xfrmi_changelink(struct net_device *dev, struct nlattr *tb[], struct nlattr *data[], struct netlink_ext_ack *extack) { - struct net *net = dev_net(dev); + struct xfrm_if *xi = netdev_priv(dev); + struct net *net = xi->net; struct xfrm_if_parms p; - struct xfrm_if *xi; xfrmi_netlink_parms(data, &p); xi = xfrmi_locate(net, &p); @@ -707,7 +707,7 @@ static struct net *xfrmi_get_link_net(const struct net_device *dev) { struct xfrm_if *xi = netdev_priv(dev); - return dev_net(xi->phydev); + return xi->net; } static const struct nla_policy xfrmi_policy[IFLA_XFRM_MAX + 1] = { From patchwork Mon Jul 15 10:00:23 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicolas Dichtel X-Patchwork-Id: 1131909 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=6wind.com Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 45nJtv2btpz9sP0 for ; Mon, 15 Jul 2019 20:00:39 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729731AbfGOKAi (ORCPT ); Mon, 15 Jul 2019 06:00:38 -0400 Received: from host.76.145.23.62.rev.coltfrance.com ([62.23.145.76]:35112 "EHLO proxy.6wind.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729703AbfGOKAf (ORCPT ); Mon, 15 Jul 2019 06:00:35 -0400 Received: from bretzel.dev.6wind.com (unknown [10.16.0.19]) by proxy.6wind.com (Postfix) with ESMTPS id 551922E8837; Mon, 15 Jul 2019 12:00:31 +0200 (CEST) Received: from dichtel by bretzel.dev.6wind.com with local (Exim 4.89) (envelope-from ) id 1hmxmZ-0002EE-7s; Mon, 15 Jul 2019 12:00:31 +0200 From: Nicolas Dichtel To: steffen.klassert@secunet.com, davem@davemloft.net Cc: netdev@vger.kernel.org, Nicolas Dichtel , Julien Floret Subject: [PATCH ipsec v2 4/4] xfrm interface: fix management of phydev Date: Mon, 15 Jul 2019 12:00:23 +0200 Message-Id: <20190715100023.8475-5-nicolas.dichtel@6wind.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190715100023.8475-1-nicolas.dichtel@6wind.com> References: <20190715100023.8475-1-nicolas.dichtel@6wind.com> MIME-Version: 1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org With the current implementation, phydev cannot be removed: $ ip link add dummy type dummy $ ip link add xfrm1 type xfrm dev dummy if_id 1 $ ip l d dummy kernel:[77938.465445] unregister_netdevice: waiting for dummy to become free. Usage count = 1 Manage it like in ip tunnels, ie just keep the ifindex. Not that the side effect, is that the phydev is now optional. Fixes: f203b76d7809 ("xfrm: Add virtual xfrm interfaces") Signed-off-by: Nicolas Dichtel Tested-by: Julien Floret --- include/net/xfrm.h | 1 - net/xfrm/xfrm_interface.c | 32 +++++++++++++++++--------------- 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/include/net/xfrm.h b/include/net/xfrm.h index ad761ef84797..aa08a7a5f6ac 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h @@ -990,7 +990,6 @@ struct xfrm_if_parms { struct xfrm_if { struct xfrm_if __rcu *next; /* next interface in list */ struct net_device *dev; /* virtual device associated with interface */ - struct net_device *phydev; /* physical device */ struct net *net; /* netns for packet i/o */ struct xfrm_if_parms p; /* interface parms */ diff --git a/net/xfrm/xfrm_interface.c b/net/xfrm/xfrm_interface.c index 53e5e47b2c55..2ab4859df55a 100644 --- a/net/xfrm/xfrm_interface.c +++ b/net/xfrm/xfrm_interface.c @@ -175,7 +175,6 @@ static void xfrmi_dev_uninit(struct net_device *dev) struct xfrmi_net *xfrmn = net_generic(xi->net, xfrmi_net_id); xfrmi_unlink(xfrmn, xi); - dev_put(xi->phydev); dev_put(dev); } @@ -362,7 +361,7 @@ static netdev_tx_t xfrmi_xmit(struct sk_buff *skb, struct net_device *dev) goto tx_err; } - fl.flowi_oif = xi->phydev->ifindex; + fl.flowi_oif = xi->p.link; ret = xfrmi_xmit2(skb, dev, &fl); if (ret < 0) @@ -548,7 +547,7 @@ static int xfrmi_get_iflink(const struct net_device *dev) { struct xfrm_if *xi = netdev_priv(dev); - return xi->phydev->ifindex; + return xi->p.link; } @@ -574,12 +573,14 @@ static void xfrmi_dev_setup(struct net_device *dev) dev->needs_free_netdev = true; dev->priv_destructor = xfrmi_dev_free; netif_keep_dst(dev); + + eth_broadcast_addr(dev->broadcast); } static int xfrmi_dev_init(struct net_device *dev) { struct xfrm_if *xi = netdev_priv(dev); - struct net_device *phydev = xi->phydev; + struct net_device *phydev = __dev_get_by_index(xi->net, xi->p.link); int err; dev->tstats = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats); @@ -594,13 +595,19 @@ static int xfrmi_dev_init(struct net_device *dev) dev->features |= NETIF_F_LLTX; - dev->needed_headroom = phydev->needed_headroom; - dev->needed_tailroom = phydev->needed_tailroom; + if (phydev) { + dev->needed_headroom = phydev->needed_headroom; + dev->needed_tailroom = phydev->needed_tailroom; - if (is_zero_ether_addr(dev->dev_addr)) - eth_hw_addr_inherit(dev, phydev); - if (is_zero_ether_addr(dev->broadcast)) - memcpy(dev->broadcast, phydev->broadcast, dev->addr_len); + if (is_zero_ether_addr(dev->dev_addr)) + eth_hw_addr_inherit(dev, phydev); + if (is_zero_ether_addr(dev->broadcast)) + memcpy(dev->broadcast, phydev->broadcast, + dev->addr_len); + } else { + eth_hw_addr_random(dev); + eth_broadcast_addr(dev->broadcast); + } return 0; } @@ -644,13 +651,8 @@ static int xfrmi_newlink(struct net *src_net, struct net_device *dev, xi->p = p; xi->net = net; xi->dev = dev; - xi->phydev = dev_get_by_index(net, p.link); - if (!xi->phydev) - return -ENODEV; err = xfrmi_create(dev); - if (err < 0) - dev_put(xi->phydev); return err; }