linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: linux-kernel@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	stable@vger.kernel.org, David Ahern <dsa@cumulusnetworks.com>,
	"David S. Miller" <davem@davemloft.net>
Subject: [PATCH 4.9 21/51] lwtunnel: fix autoload of lwt modules
Date: Thu,  2 Feb 2017 19:37:40 +0100	[thread overview]
Message-ID: <20170202183346.152885054@linuxfoundation.org> (raw)
In-Reply-To: <20170202183345.067336143@linuxfoundation.org>

4.9-stable review patch.  If anyone has any objections, please let me know.

------------------

From: David Ahern <dsa@cumulusnetworks.com>


[ Upstream commit 9ed59592e3e379b2e9557dc1d9e9ec8fcbb33f16]

Trying to add an mpls encap route when the MPLS modules are not loaded
hangs. For example:

    CONFIG_MPLS=y
    CONFIG_NET_MPLS_GSO=m
    CONFIG_MPLS_ROUTING=m
    CONFIG_MPLS_IPTUNNEL=m

    $ ip route add 10.10.10.10/32 encap mpls 100 via inet 10.100.1.2

The ip command hangs:
root       880   826  0 21:25 pts/0    00:00:00 ip route add 10.10.10.10/32 encap mpls 100 via inet 10.100.1.2

    $ cat /proc/880/stack
    [<ffffffff81065a9b>] call_usermodehelper_exec+0xd6/0x134
    [<ffffffff81065efc>] __request_module+0x27b/0x30a
    [<ffffffff814542f6>] lwtunnel_build_state+0xe4/0x178
    [<ffffffff814aa1e4>] fib_create_info+0x47f/0xdd4
    [<ffffffff814ae451>] fib_table_insert+0x90/0x41f
    [<ffffffff814a8010>] inet_rtm_newroute+0x4b/0x52
    ...

modprobe is trying to load rtnl-lwt-MPLS:

root       881     5  0 21:25 ?        00:00:00 /sbin/modprobe -q -- rtnl-lwt-MPLS

and it hangs after loading mpls_router:

    $ cat /proc/881/stack
    [<ffffffff81441537>] rtnl_lock+0x12/0x14
    [<ffffffff8142ca2a>] register_netdevice_notifier+0x16/0x179
    [<ffffffffa0033025>] mpls_init+0x25/0x1000 [mpls_router]
    [<ffffffff81000471>] do_one_initcall+0x8e/0x13f
    [<ffffffff81119961>] do_init_module+0x5a/0x1e5
    [<ffffffff810bd070>] load_module+0x13bd/0x17d6
    ...

The problem is that lwtunnel_build_state is called with rtnl lock
held preventing mpls_init from registering.

Given the potential references held by the time lwtunnel_build_state it
can not drop the rtnl lock to the load module. So, extract the module
loading code from lwtunnel_build_state into a new function to validate
the encap type. The new function is called while converting the user
request into a fib_config which is well before any table, device or
fib entries are examined.

Fixes: 745041e2aaf1 ("lwtunnel: autoload of lwt modules")
Signed-off-by: David Ahern <dsa@cumulusnetworks.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 include/net/lwtunnel.h  |   11 ++++++++
 net/core/lwtunnel.c     |   62 +++++++++++++++++++++++++++++++++++++++++++-----
 net/ipv4/fib_frontend.c |    8 ++++++
 net/ipv6/route.c        |   12 ++++++++-
 4 files changed, 86 insertions(+), 7 deletions(-)

--- a/include/net/lwtunnel.h
+++ b/include/net/lwtunnel.h
@@ -106,6 +106,8 @@ int lwtunnel_encap_add_ops(const struct
 			   unsigned int num);
 int lwtunnel_encap_del_ops(const struct lwtunnel_encap_ops *op,
 			   unsigned int num);
+int lwtunnel_valid_encap_type(u16 encap_type);
+int lwtunnel_valid_encap_type_attr(struct nlattr *attr, int len);
 int lwtunnel_build_state(struct net_device *dev, u16 encap_type,
 			 struct nlattr *encap,
 			 unsigned int family, const void *cfg,
@@ -168,6 +170,15 @@ static inline int lwtunnel_encap_del_ops
 {
 	return -EOPNOTSUPP;
 }
+
+static inline int lwtunnel_valid_encap_type(u16 encap_type)
+{
+	return -EOPNOTSUPP;
+}
+static inline int lwtunnel_valid_encap_type_attr(struct nlattr *attr, int len)
+{
+	return -EOPNOTSUPP;
+}
 
 static inline int lwtunnel_build_state(struct net_device *dev, u16 encap_type,
 				       struct nlattr *encap,
--- a/net/core/lwtunnel.c
+++ b/net/core/lwtunnel.c
@@ -26,6 +26,7 @@
 #include <net/lwtunnel.h>
 #include <net/rtnetlink.h>
 #include <net/ip6_fib.h>
+#include <net/nexthop.h>
 
 #ifdef CONFIG_MODULES
 
@@ -110,25 +111,74 @@ int lwtunnel_build_state(struct net_devi
 	ret = -EOPNOTSUPP;
 	rcu_read_lock();
 	ops = rcu_dereference(lwtun_encaps[encap_type]);
+	if (likely(ops && ops->build_state))
+		ret = ops->build_state(dev, encap, family, cfg, lws);
+	rcu_read_unlock();
+
+	return ret;
+}
+EXPORT_SYMBOL(lwtunnel_build_state);
+
+int lwtunnel_valid_encap_type(u16 encap_type)
+{
+	const struct lwtunnel_encap_ops *ops;
+	int ret = -EINVAL;
+
+	if (encap_type == LWTUNNEL_ENCAP_NONE ||
+	    encap_type > LWTUNNEL_ENCAP_MAX)
+		return ret;
+
+	rcu_read_lock();
+	ops = rcu_dereference(lwtun_encaps[encap_type]);
+	rcu_read_unlock();
 #ifdef CONFIG_MODULES
 	if (!ops) {
 		const char *encap_type_str = lwtunnel_encap_str(encap_type);
 
 		if (encap_type_str) {
-			rcu_read_unlock();
+			__rtnl_unlock();
 			request_module("rtnl-lwt-%s", encap_type_str);
+			rtnl_lock();
+
 			rcu_read_lock();
 			ops = rcu_dereference(lwtun_encaps[encap_type]);
+			rcu_read_unlock();
 		}
 	}
 #endif
-	if (likely(ops && ops->build_state))
-		ret = ops->build_state(dev, encap, family, cfg, lws);
-	rcu_read_unlock();
+	return ops ? 0 : -EOPNOTSUPP;
+}
+EXPORT_SYMBOL(lwtunnel_valid_encap_type);
 
-	return ret;
+int lwtunnel_valid_encap_type_attr(struct nlattr *attr, int remaining)
+{
+	struct rtnexthop *rtnh = (struct rtnexthop *)attr;
+	struct nlattr *nla_entype;
+	struct nlattr *attrs;
+	struct nlattr *nla;
+	u16 encap_type;
+	int attrlen;
+
+	while (rtnh_ok(rtnh, remaining)) {
+		attrlen = rtnh_attrlen(rtnh);
+		if (attrlen > 0) {
+			attrs = rtnh_attrs(rtnh);
+			nla = nla_find(attrs, attrlen, RTA_ENCAP);
+			nla_entype = nla_find(attrs, attrlen, RTA_ENCAP_TYPE);
+
+			if (nla_entype) {
+				encap_type = nla_get_u16(nla_entype);
+
+				if (lwtunnel_valid_encap_type(encap_type) != 0)
+					return -EOPNOTSUPP;
+			}
+		}
+		rtnh = rtnh_next(rtnh, &remaining);
+	}
+
+	return 0;
 }
-EXPORT_SYMBOL(lwtunnel_build_state);
+EXPORT_SYMBOL(lwtunnel_valid_encap_type_attr);
 
 int lwtunnel_fill_encap(struct sk_buff *skb, struct lwtunnel_state *lwtstate)
 {
--- a/net/ipv4/fib_frontend.c
+++ b/net/ipv4/fib_frontend.c
@@ -46,6 +46,7 @@
 #include <net/rtnetlink.h>
 #include <net/xfrm.h>
 #include <net/l3mdev.h>
+#include <net/lwtunnel.h>
 #include <trace/events/fib.h>
 
 #ifndef CONFIG_IP_MULTIPLE_TABLES
@@ -676,6 +677,10 @@ static int rtm_to_fib_config(struct net
 			cfg->fc_mx_len = nla_len(attr);
 			break;
 		case RTA_MULTIPATH:
+			err = lwtunnel_valid_encap_type_attr(nla_data(attr),
+							     nla_len(attr));
+			if (err < 0)
+				goto errout;
 			cfg->fc_mp = nla_data(attr);
 			cfg->fc_mp_len = nla_len(attr);
 			break;
@@ -690,6 +695,9 @@ static int rtm_to_fib_config(struct net
 			break;
 		case RTA_ENCAP_TYPE:
 			cfg->fc_encap_type = nla_get_u16(attr);
+			err = lwtunnel_valid_encap_type(cfg->fc_encap_type);
+			if (err < 0)
+				goto errout;
 			break;
 		}
 	}
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -2885,6 +2885,11 @@ static int rtm_to_fib6_config(struct sk_
 	if (tb[RTA_MULTIPATH]) {
 		cfg->fc_mp = nla_data(tb[RTA_MULTIPATH]);
 		cfg->fc_mp_len = nla_len(tb[RTA_MULTIPATH]);
+
+		err = lwtunnel_valid_encap_type_attr(cfg->fc_mp,
+						     cfg->fc_mp_len);
+		if (err < 0)
+			goto errout;
 	}
 
 	if (tb[RTA_PREF]) {
@@ -2898,9 +2903,14 @@ static int rtm_to_fib6_config(struct sk_
 	if (tb[RTA_ENCAP])
 		cfg->fc_encap = tb[RTA_ENCAP];
 
-	if (tb[RTA_ENCAP_TYPE])
+	if (tb[RTA_ENCAP_TYPE]) {
 		cfg->fc_encap_type = nla_get_u16(tb[RTA_ENCAP_TYPE]);
 
+		err = lwtunnel_valid_encap_type(cfg->fc_encap_type);
+		if (err < 0)
+			goto errout;
+	}
+
 	if (tb[RTA_EXPIRES]) {
 		unsigned long timeout = addrconf_timeout_fixup(nla_get_u32(tb[RTA_EXPIRES]), HZ);
 

  parent reply	other threads:[~2017-02-02 18:38 UTC|newest]

Thread overview: 55+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-02-02 18:37 [PATCH 4.9 00/51] 4.9.8-stable review Greg Kroah-Hartman
2017-02-02 18:37 ` [PATCH 4.9 01/51] r8152: fix the sw rx checksum is unavailable Greg Kroah-Hartman
2017-02-02 18:37 ` [PATCH 4.9 02/51] netvsc: add rcu_read locking to netvsc callback Greg Kroah-Hartman
2017-02-02 18:37 ` [PATCH 4.9 03/51] mlxsw: spectrum: Fix memory leak at skb reallocation Greg Kroah-Hartman
2017-02-02 18:37 ` [PATCH 4.9 04/51] mlxsw: switchx2: " Greg Kroah-Hartman
2017-02-02 18:37 ` [PATCH 4.9 05/51] mlxsw: pci: Fix EQE structure definition Greg Kroah-Hartman
2017-02-02 18:37 ` [PATCH 4.9 06/51] net: lwtunnel: Handle lwtunnel_fill_encap failure Greg Kroah-Hartman
2017-02-02 18:37 ` [PATCH 4.9 07/51] net: ipv4: fix table id in getroute response Greg Kroah-Hartman
2017-02-02 18:37 ` [PATCH 4.9 08/51] net: systemport: Decouple flow control from __bcm_sysport_tx_reclaim Greg Kroah-Hartman
2017-02-02 18:37 ` [PATCH 4.9 09/51] tcp: fix tcp_fastopen unaligned access complaints on sparc Greg Kroah-Hartman
2017-02-02 18:37 ` [PATCH 4.9 10/51] openvswitch: maintain correct checksum state in conntrack actions Greg Kroah-Hartman
2017-02-02 18:37 ` [PATCH 4.9 11/51] mlx4: do not call napi_schedule() without care Greg Kroah-Hartman
2017-02-02 18:37 ` [PATCH 4.9 12/51] ravb: do not use zero-length alignment DMA descriptor Greg Kroah-Hartman
2017-02-02 18:37 ` [PATCH 4.9 13/51] ip6_tunnel: Account for tunnel header in tunnel MTU Greg Kroah-Hartman
2017-02-02 18:37 ` [PATCH 4.9 14/51] ax25: Fix segfault after sock connection timeout Greg Kroah-Hartman
2017-02-02 18:37 ` [PATCH 4.9 15/51] net sched actions: fix refcnt when GETing of action after bind Greg Kroah-Hartman
2017-02-02 18:37 ` [PATCH 4.9 16/51] virtio: dont set VIRTIO_NET_HDR_F_DATA_VALID on xmit Greg Kroah-Hartman
2017-02-02 18:37 ` [PATCH 4.9 17/51] virtio-net: restore VIRTIO_HDR_F_DATA_VALID on receiving Greg Kroah-Hartman
2017-02-02 18:37 ` [PATCH 4.9 18/51] vxlan: fix byte order of vxlan-gpe port number Greg Kroah-Hartman
2017-02-02 18:37 ` [PATCH 4.9 19/51] net: fix harmonize_features() vs NETIF_F_HIGHDMA Greg Kroah-Hartman
2017-02-02 18:37 ` [PATCH 4.9 20/51] net: phy: bcm63xx: Utilize correct config_intr function Greg Kroah-Hartman
2017-02-02 18:37 ` Greg Kroah-Hartman [this message]
2017-02-02 18:37 ` [PATCH 4.9 22/51] ipv6: addrconf: Avoid addrconf_disable_change() using RCU read-side lock Greg Kroah-Hartman
2017-02-02 18:37 ` [PATCH 4.9 23/51] tcp: initialize max window for a new fastopen socket Greg Kroah-Hartman
2017-02-02 18:37 ` [PATCH 4.9 24/51] net/mlx5e: Do not recycle pages from emergency reserve Greg Kroah-Hartman
2017-02-02 18:37 ` [PATCH 4.9 25/51] bridge: netlink: call br_changelink() during br_dev_newlink() Greg Kroah-Hartman
2017-02-02 18:37 ` [PATCH 4.9 26/51] net: mpls: Fix multipath selection for LSR use case Greg Kroah-Hartman
2017-02-02 18:37 ` [PATCH 4.9 27/51] r8152: dont execute runtime suspend if the tx is not empty Greg Kroah-Hartman
2017-02-02 18:37 ` [PATCH 4.9 28/51] af_unix: move unix_mknod() out of bindlock Greg Kroah-Hartman
2017-02-02 18:37 ` [PATCH 4.9 30/51] net: Specify the owning module for lwtunnel ops Greg Kroah-Hartman
2017-02-02 18:37 ` [PATCH 4.9 31/51] lwtunnel: Fix oops on state free after encap module unload Greg Kroah-Hartman
2017-02-02 18:37 ` [PATCH 4.9 32/51] net: dsa: Bring back device detaching in dsa_slave_suspend() Greg Kroah-Hartman
2017-02-02 18:37 ` [PATCH 4.9 33/51] xfs: bump up reserved blocks in xfs_alloc_set_aside Greg Kroah-Hartman
2017-02-02 18:37 ` [PATCH 4.9 34/51] xfs: fix bogus minleft manipulations Greg Kroah-Hartman
2017-02-02 18:37 ` [PATCH 4.9 35/51] xfs: adjust allocation length in xfs_alloc_space_available Greg Kroah-Hartman
2017-02-02 18:37 ` [PATCH 4.9 36/51] xfs: dont rely on ->total " Greg Kroah-Hartman
2017-02-02 18:37 ` [PATCH 4.9 37/51] xfs: dont print warnings when xfs_log_force fails Greg Kroah-Hartman
2017-02-02 18:37 ` [PATCH 4.9 38/51] xfs: make the ASSERT() condition likely Greg Kroah-Hartman
2017-02-02 18:37 ` [PATCH 4.9 39/51] xfs: sanity check directory inode di_size Greg Kroah-Hartman
2017-02-02 18:37 ` [PATCH 4.9 40/51] xfs: add missing include dependencies to xfs_dir2.h Greg Kroah-Hartman
2017-02-02 18:38 ` [PATCH 4.9 41/51] xfs: replace xfs_mode_to_ftype table with switch statement Greg Kroah-Hartman
2017-02-02 18:38 ` [PATCH 4.9 42/51] xfs: sanity check inode mode when creating new dentry Greg Kroah-Hartman
2017-02-02 18:38 ` [PATCH 4.9 43/51] xfs: sanity check inode di_mode Greg Kroah-Hartman
2017-02-02 18:38 ` [PATCH 4.9 44/51] xfs: dont wrap ID in xfs_dq_get_next_id Greg Kroah-Hartman
2017-02-02 18:38 ` [PATCH 4.9 45/51] xfs: fix xfs_mode_to_ftype() prototype Greg Kroah-Hartman
2017-02-02 18:38 ` [PATCH 4.9 46/51] xfs: fix COW writeback race Greg Kroah-Hartman
2017-02-02 18:38 ` [PATCH 4.9 47/51] xfs: verify dirblocklog correctly Greg Kroah-Hartman
2017-02-02 18:38 ` [PATCH 4.9 48/51] xfs: remove racy hasattr check from attr ops Greg Kroah-Hartman
2017-02-02 18:38 ` [PATCH 4.9 49/51] xfs: extsize hints are not unlikely in xfs_bmap_btalloc Greg Kroah-Hartman
2017-02-02 18:38 ` [PATCH 4.9 50/51] xfs: clear _XBF_PAGES from buffers when readahead page Greg Kroah-Hartman
2017-02-02 18:38 ` [PATCH 4.9 51/51] xfs: fix bmv_count confusion w/ shared extents Greg Kroah-Hartman
2017-02-02 20:38 ` [PATCH 4.9 00/51] 4.9.8-stable review Shuah Khan
2017-02-02 20:56   ` Greg Kroah-Hartman
2017-02-03  5:14 ` Guenter Roeck
2017-02-03  7:17   ` Greg Kroah-Hartman

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20170202183346.152885054@linuxfoundation.org \
    --to=gregkh@linuxfoundation.org \
    --cc=davem@davemloft.net \
    --cc=dsa@cumulusnetworks.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=stable@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).