--- /dev/null
+From ben.hutchings@codethink.co.uk Thu Mar 8 17:18:02 2018
+From: Ben Hutchings <ben.hutchings@codethink.co.uk>
+Date: Thu, 8 Mar 2018 18:39:24 +0000
+Subject: mpls, nospec: Sanitize array index in mpls_label_ok()
+To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Cc: Dan Williams <dan.j.williams@intel.com>, "David S. Miller" <davem@davemloft.net>, "Eric W. Biederman" <ebiederm@xmission.com>, stable@vger.kernel.org
+Message-ID: <20180308183924.wvu2reoicwgmzerx@xylophone.i.decadent.org.uk>
+Content-Disposition: inline
+
+From: Dan Williams <dan.j.williams@intel.com>
+
+commit 3968523f855050b8195134da951b87c20bd66130 upstream.
+
+mpls_label_ok() validates that the 'platform_label' array index from a
+userspace netlink message payload is valid. Under speculation the
+mpls_label_ok() result may not resolve in the CPU pipeline until after
+the index is used to access an array element. Sanitize the index to zero
+to prevent userspace-controlled arbitrary out-of-bounds speculation, a
+precursor for a speculative execution side channel vulnerability.
+
+Cc: "David S. Miller" <davem@davemloft.net>
+Cc: Eric W. Biederman <ebiederm@xmission.com>
+Signed-off-by: Dan Williams <dan.j.williams@intel.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+[bwh: Backported to 4.4:
+ - mpls_label_ok() doesn't take an extack parameter
+ - Drop change in mpls_getroute()]
+Signed-off-by: Ben Hutchings <ben.hutchings@codethink.co.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/mpls/af_mpls.c | 22 +++++++++++++---------
+ 1 file changed, 13 insertions(+), 9 deletions(-)
+
+--- a/net/mpls/af_mpls.c
++++ b/net/mpls/af_mpls.c
+@@ -7,6 +7,7 @@
+ #include <linux/if_arp.h>
+ #include <linux/ipv6.h>
+ #include <linux/mpls.h>
++#include <linux/nospec.h>
+ #include <linux/vmalloc.h>
+ #include <net/ip.h>
+ #include <net/dst.h>
+@@ -756,17 +757,20 @@ errout:
+ return err;
+ }
+
+-static bool mpls_label_ok(struct net *net, unsigned int index)
++static bool mpls_label_ok(struct net *net, unsigned int *index)
+ {
++ bool is_ok = true;
++
+ /* Reserved labels may not be set */
+- if (index < MPLS_LABEL_FIRST_UNRESERVED)
+- return false;
++ if (*index < MPLS_LABEL_FIRST_UNRESERVED)
++ is_ok = false;
+
+ /* The full 20 bit range may not be supported. */
+- if (index >= net->mpls.platform_labels)
+- return false;
++ if (is_ok && *index >= net->mpls.platform_labels)
++ is_ok = false;
+
+- return true;
++ *index = array_index_nospec(*index, net->mpls.platform_labels);
++ return is_ok;
+ }
+
+ static int mpls_route_add(struct mpls_route_config *cfg)
+@@ -787,7 +791,7 @@ static int mpls_route_add(struct mpls_ro
+ index = find_free_label(net);
+ }
+
+- if (!mpls_label_ok(net, index))
++ if (!mpls_label_ok(net, &index))
+ goto errout;
+
+ /* Append makes no sense with mpls */
+@@ -848,7 +852,7 @@ static int mpls_route_del(struct mpls_ro
+
+ index = cfg->rc_label;
+
+- if (!mpls_label_ok(net, index))
++ if (!mpls_label_ok(net, &index))
+ goto errout;
+
+ mpls_route_update(net, index, NULL, &cfg->rc_nlinfo);
+@@ -1283,7 +1287,7 @@ static int rtm_to_route_config(struct sk
+ goto errout;
+
+ if (!mpls_label_ok(cfg->rc_nlinfo.nl_net,
+- cfg->rc_label))
++ &cfg->rc_label))
+ goto errout;
+ break;
+ }
--- /dev/null
+From ben.hutchings@codethink.co.uk Thu Mar 8 17:17:46 2018
+From: Ben Hutchings <ben.hutchings@codethink.co.uk>
+Date: Thu, 8 Mar 2018 18:36:16 +0000
+Subject: net: mpls: Pull common label check into helper
+To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Cc: David Ahern <dsahern@gmail.com>, "David S. Miller" <davem@davemloft.net>, stable@vger.kernel.org
+Message-ID: <20180308183616.f67hvcpphsu3oao2@xylophone.i.decadent.org.uk>
+Content-Disposition: inline
+
+From: David Ahern <dsahern@gmail.com>
+
+commit b7b386f42f079b25b942c756820e36c6bd09b2ca upstream.
+
+mpls_route_add and mpls_route_del have the same checks on the label.
+Move to a helper. Avoid duplicate extack messages in the next patch.
+
+Signed-off-by: David Ahern <dsahern@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Ben Hutchings <ben.hutchings@codethink.co.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/mpls/af_mpls.c | 32 +++++++++++++++++---------------
+ 1 file changed, 17 insertions(+), 15 deletions(-)
+
+--- a/net/mpls/af_mpls.c
++++ b/net/mpls/af_mpls.c
+@@ -756,6 +756,19 @@ errout:
+ return err;
+ }
+
++static bool mpls_label_ok(struct net *net, unsigned int index)
++{
++ /* Reserved labels may not be set */
++ if (index < MPLS_LABEL_FIRST_UNRESERVED)
++ return false;
++
++ /* The full 20 bit range may not be supported. */
++ if (index >= net->mpls.platform_labels)
++ return false;
++
++ return true;
++}
++
+ static int mpls_route_add(struct mpls_route_config *cfg)
+ {
+ struct mpls_route __rcu **platform_label;
+@@ -774,12 +787,7 @@ static int mpls_route_add(struct mpls_ro
+ index = find_free_label(net);
+ }
+
+- /* Reserved labels may not be set */
+- if (index < MPLS_LABEL_FIRST_UNRESERVED)
+- goto errout;
+-
+- /* The full 20 bit range may not be supported. */
+- if (index >= net->mpls.platform_labels)
++ if (!mpls_label_ok(net, index))
+ goto errout;
+
+ /* Append makes no sense with mpls */
+@@ -840,12 +848,7 @@ static int mpls_route_del(struct mpls_ro
+
+ index = cfg->rc_label;
+
+- /* Reserved labels may not be removed */
+- if (index < MPLS_LABEL_FIRST_UNRESERVED)
+- goto errout;
+-
+- /* The full 20 bit range may not be supported */
+- if (index >= net->mpls.platform_labels)
++ if (!mpls_label_ok(net, index))
+ goto errout;
+
+ mpls_route_update(net, index, NULL, &cfg->rc_nlinfo);
+@@ -1279,10 +1282,9 @@ static int rtm_to_route_config(struct sk
+ &cfg->rc_label))
+ goto errout;
+
+- /* Reserved labels may not be set */
+- if (cfg->rc_label < MPLS_LABEL_FIRST_UNRESERVED)
++ if (!mpls_label_ok(cfg->rc_nlinfo.nl_net,
++ cfg->rc_label))
+ goto errout;
+-
+ break;
+ }
+ case RTA_VIA: