aboutsummaryrefslogtreecommitdiffstats
path: root/net/mpls
diff options
context:
space:
mode:
authorDan Williams <dan.j.williams@intel.com>2018-02-08 01:34:24 -0500
committerDavid S. Miller <davem@davemloft.net>2018-02-08 15:24:12 -0500
commit3968523f855050b8195134da951b87c20bd66130 (patch)
tree1bf66a780a1e70748dcbd036281015a1d510c564 /net/mpls
parentebeeb1ad9b8adcc37c2ec21a96f39e9d35199b46 (diff)
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: <stable@vger.kernel.org> 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>
Diffstat (limited to 'net/mpls')
-rw-r--r--net/mpls/af_mpls.c24
1 files changed, 14 insertions, 10 deletions
diff --git a/net/mpls/af_mpls.c b/net/mpls/af_mpls.c
index 5dce8336d33f..e545a3c9365f 100644
--- a/net/mpls/af_mpls.c
+++ b/net/mpls/af_mpls.c
@@ -8,6 +8,7 @@
8#include <linux/ipv6.h> 8#include <linux/ipv6.h>
9#include <linux/mpls.h> 9#include <linux/mpls.h>
10#include <linux/netconf.h> 10#include <linux/netconf.h>
11#include <linux/nospec.h>
11#include <linux/vmalloc.h> 12#include <linux/vmalloc.h>
12#include <linux/percpu.h> 13#include <linux/percpu.h>
13#include <net/ip.h> 14#include <net/ip.h>
@@ -935,24 +936,27 @@ errout:
935 return err; 936 return err;
936} 937}
937 938
938static bool mpls_label_ok(struct net *net, unsigned int index, 939static bool mpls_label_ok(struct net *net, unsigned int *index,
939 struct netlink_ext_ack *extack) 940 struct netlink_ext_ack *extack)
940{ 941{
942 bool is_ok = true;
943
941 /* Reserved labels may not be set */ 944 /* Reserved labels may not be set */
942 if (index < MPLS_LABEL_FIRST_UNRESERVED) { 945 if (*index < MPLS_LABEL_FIRST_UNRESERVED) {
943 NL_SET_ERR_MSG(extack, 946 NL_SET_ERR_MSG(extack,
944 "Invalid label - must be MPLS_LABEL_FIRST_UNRESERVED or higher"); 947 "Invalid label - must be MPLS_LABEL_FIRST_UNRESERVED or higher");
945 return false; 948 is_ok = false;
946 } 949 }
947 950
948 /* The full 20 bit range may not be supported. */ 951 /* 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) {
950 NL_SET_ERR_MSG(extack, 953 NL_SET_ERR_MSG(extack,
951 "Label >= configured maximum in platform_labels"); 954 "Label >= configured maximum in platform_labels");
952 return false; 955 is_ok = false;
953 } 956 }
954 957
955 return true; 958 *index = array_index_nospec(*index, net->mpls.platform_labels);
959 return is_ok;
956} 960}
957 961
958static int mpls_route_add(struct mpls_route_config *cfg, 962static int mpls_route_add(struct mpls_route_config *cfg,
@@ -975,7 +979,7 @@ static int mpls_route_add(struct mpls_route_config *cfg,
975 index = find_free_label(net); 979 index = find_free_label(net);
976 } 980 }
977 981
978 if (!mpls_label_ok(net, index, extack)) 982 if (!mpls_label_ok(net, &index, extack))
979 goto errout; 983 goto errout;
980 984
981 /* Append makes no sense with mpls */ 985 /* Append makes no sense with mpls */
@@ -1052,7 +1056,7 @@ static int mpls_route_del(struct mpls_route_config *cfg,
1052 1056
1053 index = cfg->rc_label; 1057 index = cfg->rc_label;
1054 1058
1055 if (!mpls_label_ok(net, index, extack)) 1059 if (!mpls_label_ok(net, &index, extack))
1056 goto errout; 1060 goto errout;
1057 1061
1058 mpls_route_update(net, index, NULL, &cfg->rc_nlinfo); 1062 mpls_route_update(net, index, NULL, &cfg->rc_nlinfo);
@@ -1810,7 +1814,7 @@ static int rtm_to_route_config(struct sk_buff *skb,
1810 goto errout; 1814 goto errout;
1811 1815
1812 if (!mpls_label_ok(cfg->rc_nlinfo.nl_net, 1816 if (!mpls_label_ok(cfg->rc_nlinfo.nl_net,
1813 cfg->rc_label, extack)) 1817 &cfg->rc_label, extack))
1814 goto errout; 1818 goto errout;
1815 break; 1819 break;
1816 } 1820 }
@@ -2137,7 +2141,7 @@ static int mpls_getroute(struct sk_buff *in_skb, struct nlmsghdr *in_nlh,
2137 goto errout; 2141 goto errout;
2138 } 2142 }
2139 2143
2140 if (!mpls_label_ok(net, in_label, extack)) { 2144 if (!mpls_label_ok(net, &in_label, extack)) {
2141 err = -EINVAL; 2145 err = -EINVAL;
2142 goto errout; 2146 goto errout;
2143 } 2147 }