Skip to content

Commit 93f3aff

Browse files
djbwgregkh
authored andcommitted
mpls, nospec: Sanitize array index in mpls_label_ok()
commit 3968523 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>
1 parent d77763d commit 93f3aff

1 file changed

Lines changed: 13 additions & 9 deletions

File tree

net/mpls/af_mpls.c

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include <linux/if_arp.h>
88
#include <linux/ipv6.h>
99
#include <linux/mpls.h>
10+
#include <linux/nospec.h>
1011
#include <linux/vmalloc.h>
1112
#include <net/ip.h>
1213
#include <net/dst.h>
@@ -756,17 +757,20 @@ static int mpls_nh_build_multi(struct mpls_route_config *cfg,
756757
return err;
757758
}
758759

759-
static bool mpls_label_ok(struct net *net, unsigned int index)
760+
static bool mpls_label_ok(struct net *net, unsigned int *index)
760761
{
762+
bool is_ok = true;
763+
761764
/* Reserved labels may not be set */
762-
if (index < MPLS_LABEL_FIRST_UNRESERVED)
763-
return false;
765+
if (*index < MPLS_LABEL_FIRST_UNRESERVED)
766+
is_ok = false;
764767

765768
/* The full 20 bit range may not be supported. */
766-
if (index >= net->mpls.platform_labels)
767-
return false;
769+
if (is_ok && *index >= net->mpls.platform_labels)
770+
is_ok = false;
768771

769-
return true;
772+
*index = array_index_nospec(*index, net->mpls.platform_labels);
773+
return is_ok;
770774
}
771775

772776
static int mpls_route_add(struct mpls_route_config *cfg)
@@ -787,7 +791,7 @@ static int mpls_route_add(struct mpls_route_config *cfg)
787791
index = find_free_label(net);
788792
}
789793

790-
if (!mpls_label_ok(net, index))
794+
if (!mpls_label_ok(net, &index))
791795
goto errout;
792796

793797
/* Append makes no sense with mpls */
@@ -848,7 +852,7 @@ static int mpls_route_del(struct mpls_route_config *cfg)
848852

849853
index = cfg->rc_label;
850854

851-
if (!mpls_label_ok(net, index))
855+
if (!mpls_label_ok(net, &index))
852856
goto errout;
853857

854858
mpls_route_update(net, index, NULL, &cfg->rc_nlinfo);
@@ -1283,7 +1287,7 @@ static int rtm_to_route_config(struct sk_buff *skb, struct nlmsghdr *nlh,
12831287
goto errout;
12841288

12851289
if (!mpls_label_ok(cfg->rc_nlinfo.nl_net,
1286-
cfg->rc_label))
1290+
&cfg->rc_label))
12871291
goto errout;
12881292
break;
12891293
}

0 commit comments

Comments
 (0)