diff options
author | David Gibson <david@gibson.dropbear.id.au> | 2019-02-14 15:39:13 +1100 |
---|---|---|
committer | Michael S. Tsirkin <mst@redhat.com> | 2019-02-21 12:28:41 -0500 |
commit | b218a70e6ae882f52cc339ae965f515a36a9139f (patch) | |
tree | 3e3807d8cfca84234ab599774fa6f716495dcc25 /hw/virtio | |
parent | f6deb6d95aa7c29fa0047057512060ca720cad22 (diff) |
virtio-balloon: Corrections to address verification
The virtio-balloon device's verification of the address given to it by the
guest has a number of faults:
* The addresses here are guest physical addresses, which should be
'hwaddr' rather than 'ram_addr_t' (the distinction is admittedly
pretty subtle and confusing)
* We don't check for section.mr being NULL, which is the main way that
memory_region_find() reports basic failures. We really need to check
that before looking at any other section fields, because
memory_region_find() doesn't initialize them on the failure path
* We're passing a length of '1' to memory_region_find(), but really the
guest is requesting that we put the entire page into the balloon,
so it makes more sense to call it with BALLOON_PAGE_SIZE
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Reviewed-by: David Hildenbrand <david@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Message-Id: <20190214043916.22128-3-david@gibson.dropbear.id.au>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Diffstat (limited to 'hw/virtio')
-rw-r--r-- | hw/virtio/virtio-balloon.c | 17 |
1 files changed, 10 insertions, 7 deletions
diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c index 43af521884..eb357824d8 100644 --- a/hw/virtio/virtio-balloon.c +++ b/hw/virtio/virtio-balloon.c @@ -221,17 +221,20 @@ static void virtio_balloon_handle_output(VirtIODevice *vdev, VirtQueue *vq) } while (iov_to_buf(elem->out_sg, elem->out_num, offset, &pfn, 4) == 4) { - ram_addr_t pa; - ram_addr_t addr; + hwaddr pa; + hwaddr addr; int p = virtio_ldl_p(vdev, &pfn); - pa = (ram_addr_t) p << VIRTIO_BALLOON_PFN_SHIFT; + pa = (hwaddr) p << VIRTIO_BALLOON_PFN_SHIFT; offset += 4; - /* FIXME: remove get_system_memory(), but how? */ - section = memory_region_find(get_system_memory(), pa, 1); - if (!int128_nz(section.size) || - !memory_region_is_ram(section.mr) || + section = memory_region_find(get_system_memory(), pa, + BALLOON_PAGE_SIZE); + if (!section.mr) { + trace_virtio_balloon_bad_addr(pa); + continue; + } + if (!memory_region_is_ram(section.mr) || memory_region_is_rom(section.mr) || memory_region_is_romd(section.mr)) { trace_virtio_balloon_bad_addr(pa); |