Skip to content

Commit 3968523

Browse files
djbwdavem330
authored andcommitted
mpls, nospec: Sanitize array index in mpls_label_ok()
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: <[email protected]> Cc: "David S. Miller" <[email protected]> Cc: Eric W. Biederman <[email protected]> Signed-off-by: Dan Williams <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent ebeeb1a commit 3968523

File tree

1 file changed

+14
-10
lines changed

1 file changed

+14
-10
lines changed

net/mpls/af_mpls.c

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include <linux/ipv6.h>
99
#include <linux/mpls.h>
1010
#include <linux/netconf.h>
11+
#include <linux/nospec.h>
1112
#include <linux/vmalloc.h>
1213
#include <linux/percpu.h>
1314
#include <net/ip.h>
@@ -935,24 +936,27 @@ static int mpls_nh_build_multi(struct mpls_route_config *cfg,
935936
return err;
936937
}
937938

938-
static bool mpls_label_ok(struct net *net, unsigned int index,
939+
static bool mpls_label_ok(struct net *net, unsigned int *index,
939940
struct netlink_ext_ack *extack)
940941
{
942+
bool is_ok = true;
943+
941944
/* Reserved labels may not be set */
942-
if (index < MPLS_LABEL_FIRST_UNRESERVED) {
945+
if (*index < MPLS_LABEL_FIRST_UNRESERVED) {
943946
NL_SET_ERR_MSG(extack,
944947
"Invalid label - must be MPLS_LABEL_FIRST_UNRESERVED or higher");
945-
return false;
948+
is_ok = false;
946949
}
947950

948951
/* The full 20 bit range may not be supported. */
949-
if (index >= net->mpls.platform_labels) {
952+
if (is_ok && *index >= net->mpls.platform_labels) {
950953
NL_SET_ERR_MSG(extack,
951954
"Label >= configured maximum in platform_labels");
952-
return false;
955+
is_ok = false;
953956
}
954957

955-
return true;
958+
*index = array_index_nospec(*index, net->mpls.platform_labels);
959+
return is_ok;
956960
}
957961

958962
static int mpls_route_add(struct mpls_route_config *cfg,
@@ -975,7 +979,7 @@ static int mpls_route_add(struct mpls_route_config *cfg,
975979
index = find_free_label(net);
976980
}
977981

978-
if (!mpls_label_ok(net, index, extack))
982+
if (!mpls_label_ok(net, &index, extack))
979983
goto errout;
980984

981985
/* Append makes no sense with mpls */
@@ -1052,7 +1056,7 @@ static int mpls_route_del(struct mpls_route_config *cfg,
10521056

10531057
index = cfg->rc_label;
10541058

1055-
if (!mpls_label_ok(net, index, extack))
1059+
if (!mpls_label_ok(net, &index, extack))
10561060
goto errout;
10571061

10581062
mpls_route_update(net, index, NULL, &cfg->rc_nlinfo);
@@ -1810,7 +1814,7 @@ static int rtm_to_route_config(struct sk_buff *skb,
18101814
goto errout;
18111815

18121816
if (!mpls_label_ok(cfg->rc_nlinfo.nl_net,
1813-
cfg->rc_label, extack))
1817+
&cfg->rc_label, extack))
18141818
goto errout;
18151819
break;
18161820
}
@@ -2137,7 +2141,7 @@ static int mpls_getroute(struct sk_buff *in_skb, struct nlmsghdr *in_nlh,
21372141
goto errout;
21382142
}
21392143

2140-
if (!mpls_label_ok(net, in_label, extack)) {
2144+
if (!mpls_label_ok(net, &in_label, extack)) {
21412145
err = -EINVAL;
21422146
goto errout;
21432147
}

0 commit comments

Comments
 (0)