vu_check_queue_inflights uses last_batch_head from the frontend-controlled inflight shared memory as an index into desc[] without bounds checking. A malicious or buggy frontend can set last_batch_head >= desc_num, causing an out-of-bounds write.
Validate last_batch_head before using it. Note: the value is not guest-accessible so not a security vulnerability. Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3974 Fixes: 5f9ff1eff3 ("libvhost-user: Support tracking inflight I/O in shared memory") Cc: Xie Yongji <[email protected]> Cc: Stefano Garzarella <[email protected]> Signed-off-by: Michael S. Tsirkin <[email protected]> --- subprojects/libvhost-user/libvhost-user.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/subprojects/libvhost-user/libvhost-user.c b/subprojects/libvhost-user/libvhost-user.c index 42a5e2f1f5..c1c13dbc90 100644 --- a/subprojects/libvhost-user/libvhost-user.c +++ b/subprojects/libvhost-user/libvhost-user.c @@ -1379,6 +1379,12 @@ vu_check_queue_inflights(VuDev *dev, VuVirtq *vq) vq->counter = 0; if (unlikely(vq->inflight->used_idx != vq->used_idx)) { + if (vq->inflight->last_batch_head >= vq->inflight->desc_num) { + vu_panic(dev, "vu_check_queue_inflights: last_batch_head %u " + "out of range (desc_num %u)", + vq->inflight->last_batch_head, vq->inflight->desc_num); + return -1; + } vq->inflight->desc[vq->inflight->last_batch_head].inflight = 0; barrier(); -- MST
