diff options
-rw-r--r-- | net/mpls/af_mpls.c | 22 |
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; } |