aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Beulich <JBeulich@suse.com>2018-09-25 04:12:30 -0400
committerDavid S. Miller <davem@davemloft.net>2018-09-25 13:39:34 -0400
commit780e83c259fc33e8959fed8dfdad17e378d72b62 (patch)
treefaf5822faa8818ae642a80b29c7d7ea05c23bf5a
parente1e5d8a9fe737d94ccc0ccbaf0c97f69a8f3e000 (diff)
xen-netback: fix input validation in xenvif_set_hash_mapping()
Both len and off are frontend specified values, so we need to make sure there's no overflow when adding the two for the bounds check. We also want to avoid undefined behavior and hence use off to index into ->hash.mapping[] only after bounds checking. This at the same time allows to take care of not applying off twice for the bounds checking against vif->num_queues. It is also insufficient to bounds check copy_op.len, as this is len truncated to 16 bits. This is XSA-270 / CVE-2018-15471. Reported-by: Felix Wilhelm <fwilhelm@google.com> Signed-off-by: Jan Beulich <jbeulich@suse.com> Reviewed-by: Paul Durrant <paul.durrant@citrix.com> Tested-by: Paul Durrant <paul.durrant@citrix.com> Cc: stable@vger.kernel.org [4.7 onwards] Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/xen-netback/hash.c12
1 files changed, 7 insertions, 5 deletions
diff --git a/drivers/net/xen-netback/hash.c b/drivers/net/xen-netback/hash.c
index 3c4c58b9fe76..3b6fb5b3bdb2 100644
--- a/drivers/net/xen-netback/hash.c
+++ b/drivers/net/xen-netback/hash.c
@@ -332,20 +332,22 @@ u32 xenvif_set_hash_mapping_size(struct xenvif *vif, u32 size)
332u32 xenvif_set_hash_mapping(struct xenvif *vif, u32 gref, u32 len, 332u32 xenvif_set_hash_mapping(struct xenvif *vif, u32 gref, u32 len,
333 u32 off) 333 u32 off)
334{ 334{
335 u32 *mapping = &vif->hash.mapping[off]; 335 u32 *mapping = vif->hash.mapping;
336 struct gnttab_copy copy_op = { 336 struct gnttab_copy copy_op = {
337 .source.u.ref = gref, 337 .source.u.ref = gref,
338 .source.domid = vif->domid, 338 .source.domid = vif->domid,
339 .dest.u.gmfn = virt_to_gfn(mapping),
340 .dest.domid = DOMID_SELF, 339 .dest.domid = DOMID_SELF,
341 .dest.offset = xen_offset_in_page(mapping), 340 .len = len * sizeof(*mapping),
342 .len = len * sizeof(u32),
343 .flags = GNTCOPY_source_gref 341 .flags = GNTCOPY_source_gref
344 }; 342 };
345 343
346 if ((off + len > vif->hash.size) || copy_op.len > XEN_PAGE_SIZE) 344 if ((off + len < off) || (off + len > vif->hash.size) ||
345 len > XEN_PAGE_SIZE / sizeof(*mapping))
347 return XEN_NETIF_CTRL_STATUS_INVALID_PARAMETER; 346 return XEN_NETIF_CTRL_STATUS_INVALID_PARAMETER;
348 347
348 copy_op.dest.u.gmfn = virt_to_gfn(mapping + off);
349 copy_op.dest.offset = xen_offset_in_page(mapping + off);
350
349 while (len-- != 0) 351 while (len-- != 0)
350 if (mapping[off++] >= vif->num_queues) 352 if (mapping[off++] >= vif->num_queues)
351 return XEN_NETIF_CTRL_STATUS_INVALID_PARAMETER; 353 return XEN_NETIF_CTRL_STATUS_INVALID_PARAMETER;