mirror of
https://git.freebsd.org/src.git
synced 2026-01-16 23:02:24 +00:00
bhyve: avoid TOCTOU on iov_len in virtio_vq_recordon()
Avoid a race condition when accessing guest memory, by reading memory contents only once. This has also been applied to _vq_record() in sys/dev/beri/virtio/virtio.c, as per markj@'s suggestion. Reported by: Synacktiv Reviewed by: markj Security: HYP-10 Sponsored by: The Alpha-Omega Project Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D45735
This commit is contained in:
parent
94693ec7c8
commit
869d760cb9
2 changed files with 15 additions and 5 deletions
|
|
@ -106,12 +106,17 @@ paddr_unmap(void *phys, uint32_t size)
|
|||
static inline void
|
||||
_vq_record(uint32_t offs, int i, volatile struct vring_desc *vd,
|
||||
struct iovec *iov, int n_iov, uint16_t *flags) {
|
||||
uint32_t len;
|
||||
uint64_t addr;
|
||||
|
||||
if (i >= n_iov)
|
||||
return;
|
||||
|
||||
iov[i].iov_base = paddr_map(offs, be64toh(vd->addr),
|
||||
be32toh(vd->len));
|
||||
iov[i].iov_len = be32toh(vd->len);
|
||||
len = atomic_load_32(&vd->len);
|
||||
addr = atomic_load_64(&vd->addr);
|
||||
iov[i].iov_base = paddr_map(offs, be64toh(addr),
|
||||
be32toh(len));
|
||||
iov[i].iov_len = be32toh(len);
|
||||
if (flags != NULL)
|
||||
flags[i] = be16toh(vd->flags);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -216,10 +216,15 @@ static inline void
|
|||
_vq_record(int i, struct vring_desc *vd, struct vmctx *ctx, struct iovec *iov,
|
||||
int n_iov, struct vi_req *reqp)
|
||||
{
|
||||
uint32_t len;
|
||||
uint64_t addr;
|
||||
|
||||
if (i >= n_iov)
|
||||
return;
|
||||
iov[i].iov_base = paddr_guest2host(ctx, vd->addr, vd->len);
|
||||
iov[i].iov_len = vd->len;
|
||||
len = atomic_load_32(&vd->len);
|
||||
addr = atomic_load_64(&vd->addr);
|
||||
iov[i].iov_len = len;
|
||||
iov[i].iov_base = paddr_guest2host(ctx, addr, len);
|
||||
if ((vd->flags & VRING_DESC_F_WRITE) == 0)
|
||||
reqp->readable++;
|
||||
else
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue