summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--net/mpls/af_mpls.c22
1 files changed, 13 insertions, 9 deletions
diff --git a/net/mpls/af_mpls.c b/net/mpls/af_mpls.c
index ff7f7f05523a..c2ce7dec5198 100644
--- 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>
@@ -714,17 +715,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)
@@ -745,7 +749,7 @@ static int mpls_route_add(struct mpls_route_config *cfg)
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 */
@@ -806,7 +810,7 @@ static int mpls_route_del(struct mpls_route_config *cfg)
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);
@@ -1166,7 +1170,7 @@ static int rtm_to_route_config(struct sk_buff *skb, struct nlmsghdr *nlh,
goto errout;
if (!mpls_label_ok(cfg->rc_nlinfo.nl_net,
- cfg->rc_label))
+ &cfg->rc_label))
goto errout;
break;
}