summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaxime Coquelin <maxime.coquelin@redhat.com>2019-08-23 15:17:05 +0200
committerKevin Traynor <ktraynor@redhat.com>2019-11-05 18:19:08 +0000
commitfa674d08985f394ba4af9d25e36acf5a7802d1eb (patch)
tree6859d3699a9692b4a8bdf26e65d94c42c5f7c61c
parentb81660d09e9caa928ab1c683cd0fbfbe2439ac3d (diff)
downloaddpdk-stable-fa674d08985f.zip
dpdk-stable-fa674d08985f.tar.gz
dpdk-stable-fa674d08985f.tar.xz
vhost: fix possible denial of service on SET_VRING_NUM
vhost_user_set_vring_num() performs multiple allocations without checking whether data were previously allocated. It may cause a denial of service because of the memory leaks that happen if a malicious vhost-user master keeps sending VHOST_USER_SET_VRING_NUM request until the slave runs out of memory. This issue has been assigned CVE-2019-14818 Fixes: b0a985d1f340 ("vhost: add dequeue zero copy") Reported-by: Jason Wang <jasowang@redhat.com> Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
-rw-r--r--lib/librte_vhost/vhost_user.c8
1 files changed, 8 insertions, 0 deletions
diff --git a/lib/librte_vhost/vhost_user.c b/lib/librte_vhost/vhost_user.c
index 0b72648..f4ad3a0 100644
--- a/lib/librte_vhost/vhost_user.c
+++ b/lib/librte_vhost/vhost_user.c
@@ -348,6 +348,8 @@ vhost_user_set_vring_num(struct virtio_net **pdev,
vq->nr_zmbuf = 0;
vq->last_zmbuf_idx = 0;
vq->zmbuf_size = vq->size;
+ if (vq->zmbufs)
+ rte_free(vq->zmbufs);
vq->zmbufs = rte_zmalloc(NULL, vq->zmbuf_size *
sizeof(struct zcopy_mbuf), 0);
if (vq->zmbufs == NULL) {
@@ -360,6 +362,8 @@ vhost_user_set_vring_num(struct virtio_net **pdev,
}
if (vq_is_packed(dev)) {
+ if (vq->shadow_used_packed)
+ rte_free(vq->shadow_used_packed);
vq->shadow_used_packed = rte_malloc(NULL,
vq->size *
sizeof(struct vring_used_elem_packed),
@@ -371,6 +375,8 @@ vhost_user_set_vring_num(struct virtio_net **pdev,
}
} else {
+ if (vq->shadow_used_split)
+ rte_free(vq->shadow_used_split);
vq->shadow_used_split = rte_malloc(NULL,
vq->size * sizeof(struct vring_used_elem),
RTE_CACHE_LINE_SIZE);
@@ -381,6 +387,8 @@ vhost_user_set_vring_num(struct virtio_net **pdev,
}
}
+ if (vq->batch_copy_elems)
+ rte_free(vq->batch_copy_elems);
vq->batch_copy_elems = rte_malloc(NULL,
vq->size * sizeof(struct batch_copy_elem),
RTE_CACHE_LINE_SIZE);