On Fri, Jul 17, 2020 at 8:21 AM Raphael Norwitz <raphael.norw...@nutanix.com> wrote: > > The VHOST_USER_PROTOCOL_F_CONFIGURE_MEM_SLOTS vhost-user protocol > feature introduced a shadow-table, used by the backend to dynamically > determine how a vdev's memory regions have changed since the last > vhost_user_set_mem_table() call. On hot-remove, a memmove() operation > is used to overwrite the removed shadow region descriptor(s). The size > parameter of this memmove was off by 1 such that if a VM with a backend > supporting the VHOST_USER_PROTOCOL_F_CONFIGURE_MEM_SLOTS filled it's > shadow-table (by performing the maximum number of supported hot-add > operatons) and attempted to remove the last region, Qemu would read an > out of bounds value and potentially crash. > > This change fixes the memmove() bounds such that this erroneous read can > never happen. > > Signed-off-by: Peter Turschmid <peter.turs...@nutanix.com> > Signed-off-by: Raphael Norwitz <raphael.norw...@nutanix.com>
Fixes: f1aeb14b0809 ("Transmit vhost-user memory regions individually") Reviewed-by: Marc-André Lureau <marcandre.lur...@redhat.com> > --- > hw/virtio/vhost-user.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c > index 3123121..d7e2423 100644 > --- a/hw/virtio/vhost-user.c > +++ b/hw/virtio/vhost-user.c > @@ -672,7 +672,7 @@ static int send_remove_regions(struct vhost_dev *dev, > memmove(&u->shadow_regions[shadow_reg_idx], > &u->shadow_regions[shadow_reg_idx + 1], > sizeof(struct vhost_memory_region) * > - (u->num_shadow_regions - shadow_reg_idx)); > + (u->num_shadow_regions - shadow_reg_idx - 1)); > u->num_shadow_regions--; > } > > -- > 1.8.3.1 >