summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaxime Coquelin <maxime.coquelin@redhat.com>2019-08-23 15:17:05 +0200
committerDavid Marchand <david.marchand@redhat.com>2019-11-12 12:21:17 +0100
commit612e17cf6d7b2bf05a687d8a9ba7be582a744e50 (patch)
tree33485ef4ae769e816c8f86d3bbd7fbcc0236ce33
parent31aa07759ecd151967b568b1f1aa12b7794217c8 (diff)
downloaddpdk-612e17cf6d7b2bf05a687d8a9ba7be582a744e50.zip
dpdk-612e17cf6d7b2bf05a687d8a9ba7be582a744e50.tar.gz
dpdk-612e17cf6d7b2bf05a687d8a9ba7be582a744e50.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 cc660e0..d4c9cd3 100644
--- a/lib/librte_vhost/vhost_user.c
+++ b/lib/librte_vhost/vhost_user.c
@@ -386,6 +386,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) {
@@ -398,6 +400,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),
@@ -409,6 +413,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);
@@ -419,6 +425,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);