mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-06-22 21:47:22 +00:00
dm: virtio: check for paddr_guest2host return value
paddr_guest2host can return NULL, but code paths in virtio are not checking the return value. _vq_record() initializes iov_base pointer using paddr_guest2host() but there is nothing in the flow that checks for NULL. Chane _vq_record to return -1 in case the address translation has failed. Tracked-On: #5452 Signed-off-by: Tomas Winkler <tomas.winkler@intel.com> Acked-by: Wang, Yu1 <yu1.wang@intel.com>
This commit is contained in:
parent
a2167ae93a
commit
188ab4f85b
@ -296,6 +296,8 @@ virtio_vq_init(struct virtio_base *base, uint32_t pfn)
|
|||||||
phys = (uint64_t)pfn << VRING_PAGE_BITS;
|
phys = (uint64_t)pfn << VRING_PAGE_BITS;
|
||||||
size = vring_size(vq->qsize, VIRTIO_PCI_VRING_ALIGN);
|
size = vring_size(vq->qsize, VIRTIO_PCI_VRING_ALIGN);
|
||||||
vb = paddr_guest2host(base->dev->vmctx, phys, size);
|
vb = paddr_guest2host(base->dev->vmctx, phys, size);
|
||||||
|
if (!vb)
|
||||||
|
goto error;
|
||||||
|
|
||||||
/* First page(s) are descriptors... */
|
/* First page(s) are descriptors... */
|
||||||
vq->desc = (struct vring_desc *)vb;
|
vq->desc = (struct vring_desc *)vb;
|
||||||
@ -318,6 +320,12 @@ virtio_vq_init(struct virtio_base *base, uint32_t pfn)
|
|||||||
/* Mark queue as allocated after initialization is complete. */
|
/* Mark queue as allocated after initialization is complete. */
|
||||||
mb();
|
mb();
|
||||||
vq->flags = VQ_ALLOC;
|
vq->flags = VQ_ALLOC;
|
||||||
|
|
||||||
|
return;
|
||||||
|
|
||||||
|
error:
|
||||||
|
vq->flags = 0;
|
||||||
|
pr_err("%s: vq enable failed\n", __func__);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -382,17 +390,25 @@ virtio_vq_enable(struct virtio_base *base)
|
|||||||
/*
|
/*
|
||||||
* Helper inline for vq_getchain(): record the i'th "real"
|
* Helper inline for vq_getchain(): record the i'th "real"
|
||||||
* descriptor.
|
* descriptor.
|
||||||
|
* Return 0 on success and -1 when i is out of range or mapping
|
||||||
|
* fails.
|
||||||
*/
|
*/
|
||||||
static inline void
|
static inline int
|
||||||
_vq_record(int i, volatile struct vring_desc *vd, struct vmctx *ctx,
|
_vq_record(int i, volatile struct vring_desc *vd, struct vmctx *ctx,
|
||||||
struct iovec *iov, int n_iov, uint16_t *flags) {
|
struct iovec *iov, int n_iov, uint16_t *flags) {
|
||||||
|
|
||||||
|
void *host_addr;
|
||||||
|
|
||||||
if (i >= n_iov)
|
if (i >= n_iov)
|
||||||
return;
|
return -1;
|
||||||
iov[i].iov_base = paddr_guest2host(ctx, vd->addr, vd->len);
|
host_addr = paddr_guest2host(ctx, vd->addr, vd->len);
|
||||||
|
if (!host_addr)
|
||||||
|
return -1;
|
||||||
|
iov[i].iov_base = host_addr;
|
||||||
iov[i].iov_len = vd->len;
|
iov[i].iov_len = vd->len;
|
||||||
if (flags != NULL)
|
if (flags != NULL)
|
||||||
flags[i] = vd->flags;
|
flags[i] = vd->flags;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
#define VQ_MAX_DESCRIPTORS 512 /* see below */
|
#define VQ_MAX_DESCRIPTORS 512 /* see below */
|
||||||
|
|
||||||
@ -495,7 +511,10 @@ vq_getchain(struct virtio_vq_info *vq, uint16_t *pidx,
|
|||||||
}
|
}
|
||||||
vdir = &vq->desc[next];
|
vdir = &vq->desc[next];
|
||||||
if ((vdir->flags & VRING_DESC_F_INDIRECT) == 0) {
|
if ((vdir->flags & VRING_DESC_F_INDIRECT) == 0) {
|
||||||
_vq_record(i, vdir, ctx, iov, n_iov, flags);
|
if (_vq_record(i, vdir, ctx, iov, n_iov, flags)) {
|
||||||
|
pr_err("%s: mapping to host failed\r\n", name);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
i++;
|
i++;
|
||||||
} else if ((base->device_caps &
|
} else if ((base->device_caps &
|
||||||
(1 << VIRTIO_RING_F_INDIRECT_DESC)) == 0) {
|
(1 << VIRTIO_RING_F_INDIRECT_DESC)) == 0) {
|
||||||
@ -513,6 +532,11 @@ vq_getchain(struct virtio_vq_info *vq, uint16_t *pidx,
|
|||||||
}
|
}
|
||||||
vindir = paddr_guest2host(ctx,
|
vindir = paddr_guest2host(ctx,
|
||||||
vdir->addr, vdir->len);
|
vdir->addr, vdir->len);
|
||||||
|
|
||||||
|
if (!vindir) {
|
||||||
|
pr_err("%s cannot get host memory\r\n", name);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
* Indirects start at the 0th, then follow
|
* Indirects start at the 0th, then follow
|
||||||
* their own embedded "next"s until those run
|
* their own embedded "next"s until those run
|
||||||
@ -529,7 +553,10 @@ vq_getchain(struct virtio_vq_info *vq, uint16_t *pidx,
|
|||||||
name);
|
name);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
_vq_record(i, vp, ctx, iov, n_iov, flags);
|
if (_vq_record(i, vp, ctx, iov, n_iov, flags)) {
|
||||||
|
pr_err("%s: mapping to host failed\r\n", name);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
if (++i > VQ_MAX_DESCRIPTORS)
|
if (++i > VQ_MAX_DESCRIPTORS)
|
||||||
goto loopy;
|
goto loopy;
|
||||||
if ((vp->flags & VRING_DESC_F_NEXT) == 0)
|
if ((vp->flags & VRING_DESC_F_NEXT) == 0)
|
||||||
|
Loading…
Reference in New Issue
Block a user