On Wed, Sep 11, 2019 at 08:10:00AM -0400, Michael S. Tsirkin wrote: > iovec addresses coming from vhost are assumed to be > pre-validated, but in fact can be speculated to a value > out of range. > > Userspace address are later validated with array_index_nospec so we can > be sure kernel info does not leak through these addresses, but vhost > must also not leak userspace info outside the allowed memory table to > guests. > > Following the defence in depth principle, make sure > the address is not validated out of node range. > > Signed-off-by: Michael S. Tsirkin <mst@xxxxxxxxxx> > Acked-by: Jason Wang <jasowang@xxxxxxxxxx> > Tested-by: Jason Wang <jasowang@xxxxxxxxxx> > --- Cc: security@xxxxxxxxxx Pls advise on whether you'd like me to merge this directly, Cc stable, or handle it in some other way. > changes from v1: fix build on 32 bit > > drivers/vhost/vhost.c | 6 ++++-- > 1 file changed, 4 insertions(+), 2 deletions(-) > > diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c > index 5dc174ac8cac..34ea219936e3 100644 > --- a/drivers/vhost/vhost.c > +++ b/drivers/vhost/vhost.c > @@ -2071,8 +2071,10 @@ static int translate_desc(struct vhost_virtqueue *vq, u64 addr, u32 len, > _iov = iov + ret; > size = node->size - addr + node->start; > _iov->iov_len = min((u64)len - s, size); > - _iov->iov_base = (void __user *)(unsigned long) > - (node->userspace_addr + addr - node->start); > + _iov->iov_base = (void __user *) > + ((unsigned long)node->userspace_addr + > + array_index_nospec((unsigned long)(addr - node->start), > + node->size)); > s += size; > addr += size; > ++ret; > -- > MST