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-04 11:14:25 +0000
commit70583a6b9b1cd3d46e8d39be355b80ec60a8de64 (patch)
treede00cf9cae1b851e6a13e64d8157224140dae076
parent95c897b3988681cb79dddbdd45cfe967c3f34891 (diff)
downloaddpdk-stable-70583a6b9b1cd3d46e8d39be355b80ec60a8de64.zip
dpdk-stable-70583a6b9b1cd3d46e8d39be355b80ec60a8de64.tar.gz
dpdk-stable-70583a6b9b1cd3d46e8d39be355b80ec60a8de64.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 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 5552f8b..457e62d 100644
--- a/lib/librte_vhost/vhost_user.c
+++ b/lib/librte_vhost/vhost_user.c
@@ -346,6 +346,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) {
@@ -358,6 +360,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),
@@ -369,6 +373,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);
@@ -379,6 +385,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);