vhost: fix dead loop in enqueue path
If a malicious guest forges a dead loop desc chain (let desc->next point to itself) and desc->len is zero, this could lead to a dead loop in copy_mbuf_to_desc(following is a simplified code to show this issue clearly): while (mbuf_is_not_totally_consumed) { if (desc_avail == 0) { desc = &descs[desc->next]; desc_avail = desc->len; } COPY(desc, mbuf, desc_avail); } I have actually fixed a same issue before: commita436f53ebf
("vhost: avoid dead loop chain"); it fixes the dequeue path though, leaving the enqueue path still vulnerable. The fix is the same. Add a var nr_desc to avoid the dead loop. Fixes:f1a519ad98
("vhost: fix enqueue/dequeue to handle chained vring descriptors") Cc: stable@dpdk.org Reported-by: Xieming Katty <katty.xieming@huawei.com> Signed-off-by: Yuanhan Liu <yuanhan.liu@linux.intel.com> Reviewed-by: Maxime Coquelin <maxime.coquelin@redhat.com>
This commit is contained in:
parent
30712b214b
commit
cc7301908c
@ -195,6 +195,8 @@ copy_mbuf_to_desc(struct virtio_net *dev, struct vring_desc *descs,
|
||||
struct vring_desc *desc;
|
||||
uint64_t desc_addr;
|
||||
struct virtio_net_hdr_mrg_rxbuf virtio_hdr = {{0, 0, 0, 0, 0, 0}, 0};
|
||||
/* A counter to avoid desc dead loop chain */
|
||||
uint16_t nr_desc = 1;
|
||||
|
||||
desc = &descs[desc_idx];
|
||||
desc_addr = gpa_to_vva(dev, desc->addr);
|
||||
@ -233,7 +235,7 @@ copy_mbuf_to_desc(struct virtio_net *dev, struct vring_desc *descs,
|
||||
/* Room in vring buffer is not enough */
|
||||
return -1;
|
||||
}
|
||||
if (unlikely(desc->next >= size))
|
||||
if (unlikely(desc->next >= size || ++nr_desc > size))
|
||||
return -1;
|
||||
|
||||
desc = &descs[desc->next];
|
||||
|
Loading…
Reference in New Issue
Block a user