1 From 780e83c259fc33e8959fed8dfdad17e378d72b62 Mon Sep 17 00:00:00 2001
2 From: Jan Beulich <JBeulich@suse.com>
3 Date: Tue, 25 Sep 2018 02:12:30 -0600
4 Subject: xen-netback: fix input validation in xenvif_set_hash_mapping()
6 From: Jan Beulich <JBeulich@suse.com>
8 commit 780e83c259fc33e8959fed8dfdad17e378d72b62 upstream.
10 Both len and off are frontend specified values, so we need to make
11 sure there's no overflow when adding the two for the bounds check. We
12 also want to avoid undefined behavior and hence use off to index into
13 ->hash.mapping[] only after bounds checking. This at the same time
14 allows to take care of not applying off twice for the bounds checking
15 against vif->num_queues.
17 It is also insufficient to bounds check copy_op.len, as this is len
20 This is XSA-270 / CVE-2018-15471.
22 Reported-by: Felix Wilhelm <fwilhelm@google.com>
23 Signed-off-by: Jan Beulich <jbeulich@suse.com>
24 Reviewed-by: Paul Durrant <paul.durrant@citrix.com>
25 Tested-by: Paul Durrant <paul.durrant@citrix.com>
26 Cc: stable@vger.kernel.org [4.7 onwards]
27 Signed-off-by: David S. Miller <davem@davemloft.net>
28 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
31 drivers/net/xen-netback/hash.c | 12 +++++++-----
32 1 file changed, 7 insertions(+), 5 deletions(-)
34 --- a/drivers/net/xen-netback/hash.c
35 +++ b/drivers/net/xen-netback/hash.c
36 @@ -332,20 +332,22 @@ u32 xenvif_set_hash_mapping_size(struct
37 u32 xenvif_set_hash_mapping(struct xenvif *vif, u32 gref, u32 len,
40 - u32 *mapping = &vif->hash.mapping[off];
41 + u32 *mapping = vif->hash.mapping;
42 struct gnttab_copy copy_op = {
44 .source.domid = vif->domid,
45 - .dest.u.gmfn = virt_to_gfn(mapping),
46 .dest.domid = DOMID_SELF,
47 - .dest.offset = xen_offset_in_page(mapping),
48 - .len = len * sizeof(u32),
49 + .len = len * sizeof(*mapping),
50 .flags = GNTCOPY_source_gref
53 - if ((off + len > vif->hash.size) || copy_op.len > XEN_PAGE_SIZE)
54 + if ((off + len < off) || (off + len > vif->hash.size) ||
55 + len > XEN_PAGE_SIZE / sizeof(*mapping))
56 return XEN_NETIF_CTRL_STATUS_INVALID_PARAMETER;
58 + copy_op.dest.u.gmfn = virt_to_gfn(mapping + off);
59 + copy_op.dest.offset = xen_offset_in_page(mapping + off);
62 if (mapping[off++] >= vif->num_queues)
63 return XEN_NETIF_CTRL_STATUS_INVALID_PARAMETER;