git: ed03c3099086 - stable/14 - bhyve: avoid TOCTOU on iov_len in virtio_vq_recordon()
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Wed, 02 Oct 2024 20:37:22 UTC
The branch stable/14 has been updated by emaste: URL: https://cgit.FreeBSD.org/src/commit/?id=ed03c309908687bdb9f71dc6d9c9c8a92c54fc20 commit ed03c309908687bdb9f71dc6d9c9c8a92c54fc20 Author: Pierre Pronchery <pierre@freebsdfoundation.org> AuthorDate: 2024-08-27 13:57:32 +0000 Commit: Ed Maste <emaste@FreeBSD.org> CommitDate: 2024-10-02 20:37:09 +0000 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 (cherry picked from commit 869d760cb9d7a307faa2fbe8c1c2b238a81b74d4) --- sys/dev/beri/virtio/virtio.c | 11 ++++++++--- usr.sbin/bhyve/virtio.c | 9 +++++++-- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/sys/dev/beri/virtio/virtio.c b/sys/dev/beri/virtio/virtio.c index c249d1c9d37b..7302bc39d799 100644 --- a/sys/dev/beri/virtio/virtio.c +++ b/sys/dev/beri/virtio/virtio.c @@ -107,12 +107,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); } diff --git a/usr.sbin/bhyve/virtio.c b/usr.sbin/bhyve/virtio.c index 0aeafa011bbc..5e8f8a8d322a 100644 --- a/usr.sbin/bhyve/virtio.c +++ b/usr.sbin/bhyve/virtio.c @@ -217,10 +217,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