From 9571d232c9cfee710c556f7717e67e135eb547a9 Mon Sep 17 00:00:00 2001 From: chxssg Date: Tue, 20 Oct 2020 17:17:17 +0800 Subject: [PATCH] fix CVE-2020-14376 CVE-2020-14377 CVE-2020-14378 --- CVE-2020-14376-CVE-2020-14377.patch | 163 ++++++++++++++++++++++++++++ CVE-2020-14378.patch | 42 +++++++ dpdk.spec | 11 +- fix-pool-allocation.patch | 45 ++++++++ 4 files changed, 260 insertions(+), 1 deletion(-) create mode 100644 CVE-2020-14376-CVE-2020-14377.patch create mode 100644 CVE-2020-14378.patch create mode 100644 fix-pool-allocation.patch diff --git a/CVE-2020-14376-CVE-2020-14377.patch b/CVE-2020-14376-CVE-2020-14377.patch new file mode 100644 index 0000000..c28e251 --- /dev/null +++ b/CVE-2020-14376-CVE-2020-14377.patch @@ -0,0 +1,163 @@ +From e4a7c14f02480a41992414afb5e011f8ff8f02f3 Mon Sep 17 00:00:00 2001 +From: Fan Zhang +Date: Tue, 14 Apr 2020 17:26:48 +0100 +Subject: vhost/crypto: fix missed request check for copy mode + +This patch fixes the missed request check to vhost crypto +copy mode. + +CVE-2020-14376 +CVE-2020-14377 +Fixes: 3bb595ecd682 ("vhost/crypto: add request handler") +Cc: stable@dpdk.org + +Signed-off-by: Fan Zhang +Acked-by: Chenbo Xia + +reference:https://git.dpdk.org/dpdk-stable/commit/?h=19.11&id=e4a7c14f0248 +Signed-off-by: gaoxingwang +--- + lib/librte_vhost/vhost_crypto.c | 68 ++++++++++++++++++++++++++++------------- + 1 file changed, 47 insertions(+), 21 deletions(-) + +diff --git a/lib/librte_vhost/vhost_crypto.c b/lib/librte_vhost/vhost_crypto.c +index 86747dd..494f490 100644 +--- a/lib/librte_vhost/vhost_crypto.c ++++ b/lib/librte_vhost/vhost_crypto.c +@@ -756,7 +756,7 @@ prepare_write_back_data(struct vhost_crypto_data_req *vc_req, + } + + wb_data->dst = dst; +- wb_data->len = desc->len - offset; ++ wb_data->len = RTE_MIN(desc->len - offset, write_back_len); + write_back_len -= wb_data->len; + src += offset + wb_data->len; + offset = 0; +@@ -840,6 +840,17 @@ error_exit: + return NULL; + } + ++static __rte_always_inline uint8_t ++vhost_crypto_check_cipher_request(struct virtio_crypto_cipher_data_req *req) ++{ ++ if (likely((req->para.iv_len <= VHOST_CRYPTO_MAX_IV_LEN) && ++ (req->para.src_data_len <= RTE_MBUF_DEFAULT_BUF_SIZE) && ++ (req->para.dst_data_len >= req->para.src_data_len) && ++ (req->para.dst_data_len <= RTE_MBUF_DEFAULT_BUF_SIZE))) ++ return VIRTIO_CRYPTO_OK; ++ return VIRTIO_CRYPTO_BADMSG; ++} ++ + static uint8_t + prepare_sym_cipher_op(struct vhost_crypto *vcrypto, struct rte_crypto_op *op, + struct vhost_crypto_data_req *vc_req, +@@ -851,7 +862,10 @@ prepare_sym_cipher_op(struct vhost_crypto *vcrypto, struct rte_crypto_op *op, + struct vhost_crypto_writeback_data *ewb = NULL; + struct rte_mbuf *m_src = op->sym->m_src, *m_dst = op->sym->m_dst; + uint8_t *iv_data = rte_crypto_op_ctod_offset(op, uint8_t *, IV_OFFSET); +- uint8_t ret = 0; ++ uint8_t ret = vhost_crypto_check_cipher_request(cipher); ++ ++ if (unlikely(ret != VIRTIO_CRYPTO_OK)) ++ goto error_exit; + + /* prepare */ + /* iv */ +@@ -861,10 +875,9 @@ prepare_sym_cipher_op(struct vhost_crypto *vcrypto, struct rte_crypto_op *op, + goto error_exit; + } + +- m_src->data_len = cipher->para.src_data_len; +- + switch (vcrypto->option) { + case RTE_VHOST_CRYPTO_ZERO_COPY_ENABLE: ++ m_src->data_len = cipher->para.src_data_len; + m_src->buf_iova = gpa_to_hpa(vcrypto->dev, desc->addr, + cipher->para.src_data_len); + m_src->buf_addr = get_data_ptr(vc_req, desc, VHOST_ACCESS_RO); +@@ -886,13 +899,7 @@ prepare_sym_cipher_op(struct vhost_crypto *vcrypto, struct rte_crypto_op *op, + break; + case RTE_VHOST_CRYPTO_ZERO_COPY_DISABLE: + vc_req->wb_pool = vcrypto->wb_pool; +- +- if (unlikely(cipher->para.src_data_len > +- RTE_MBUF_DEFAULT_BUF_SIZE)) { +- VC_LOG_ERR("Not enough space to do data copy"); +- ret = VIRTIO_CRYPTO_ERR; +- goto error_exit; +- } ++ m_src->data_len = cipher->para.src_data_len; + if (unlikely(copy_data(rte_pktmbuf_mtod(m_src, uint8_t *), + vc_req, &desc, cipher->para.src_data_len, + nb_descs, vq_size) < 0)) { +@@ -975,6 +982,29 @@ error_exit: + return ret; + } + ++static __rte_always_inline uint8_t ++vhost_crypto_check_chain_request(struct virtio_crypto_alg_chain_data_req *req) ++{ ++ if (likely((req->para.iv_len <= VHOST_CRYPTO_MAX_IV_LEN) && ++ (req->para.src_data_len <= RTE_MBUF_DEFAULT_DATAROOM) && ++ (req->para.dst_data_len >= req->para.src_data_len) && ++ (req->para.dst_data_len <= RTE_MBUF_DEFAULT_DATAROOM) && ++ (req->para.cipher_start_src_offset < ++ RTE_MBUF_DEFAULT_DATAROOM) && ++ (req->para.len_to_cipher < RTE_MBUF_DEFAULT_DATAROOM) && ++ (req->para.hash_start_src_offset < ++ RTE_MBUF_DEFAULT_DATAROOM) && ++ (req->para.len_to_hash < RTE_MBUF_DEFAULT_DATAROOM) && ++ (req->para.cipher_start_src_offset + req->para.len_to_cipher <= ++ req->para.src_data_len) && ++ (req->para.hash_start_src_offset + req->para.len_to_hash <= ++ req->para.src_data_len) && ++ (req->para.dst_data_len + req->para.hash_result_len <= ++ RTE_MBUF_DEFAULT_DATAROOM))) ++ return VIRTIO_CRYPTO_OK; ++ return VIRTIO_CRYPTO_BADMSG; ++} ++ + static uint8_t + prepare_sym_chain_op(struct vhost_crypto *vcrypto, struct rte_crypto_op *op, + struct vhost_crypto_data_req *vc_req, +@@ -988,7 +1018,10 @@ prepare_sym_chain_op(struct vhost_crypto *vcrypto, struct rte_crypto_op *op, + uint8_t *iv_data = rte_crypto_op_ctod_offset(op, uint8_t *, IV_OFFSET); + uint32_t digest_offset; + void *digest_addr; +- uint8_t ret = 0; ++ uint8_t ret = vhost_crypto_check_chain_request(chain); ++ ++ if (unlikely(ret != VIRTIO_CRYPTO_OK)) ++ goto error_exit; + + /* prepare */ + /* iv */ +@@ -998,10 +1031,9 @@ prepare_sym_chain_op(struct vhost_crypto *vcrypto, struct rte_crypto_op *op, + goto error_exit; + } + +- m_src->data_len = chain->para.src_data_len; +- + switch (vcrypto->option) { + case RTE_VHOST_CRYPTO_ZERO_COPY_ENABLE: ++ m_src->data_len = chain->para.src_data_len; + m_dst->data_len = chain->para.dst_data_len; + + m_src->buf_iova = gpa_to_hpa(vcrypto->dev, desc->addr, +@@ -1023,13 +1055,7 @@ prepare_sym_chain_op(struct vhost_crypto *vcrypto, struct rte_crypto_op *op, + break; + case RTE_VHOST_CRYPTO_ZERO_COPY_DISABLE: + vc_req->wb_pool = vcrypto->wb_pool; +- +- if (unlikely(chain->para.src_data_len > +- RTE_MBUF_DEFAULT_BUF_SIZE)) { +- VC_LOG_ERR("Not enough space to do data copy"); +- ret = VIRTIO_CRYPTO_ERR; +- goto error_exit; +- } ++ m_src->data_len = chain->para.src_data_len; + if (unlikely(copy_data(rte_pktmbuf_mtod(m_src, uint8_t *), + vc_req, &desc, chain->para.src_data_len, + nb_descs, vq_size) < 0)) { +-- +cgit v1.0 diff --git a/CVE-2020-14378.patch b/CVE-2020-14378.patch new file mode 100644 index 0000000..902dc04 --- /dev/null +++ b/CVE-2020-14378.patch @@ -0,0 +1,42 @@ +From 81e9694830209207cbba599b62858c97c3ed5cfe Mon Sep 17 00:00:00 2001 +From: Fan Zhang +Date: Tue, 14 Apr 2020 16:52:47 +0100 +Subject: vhost/crypto: fix incorrect descriptor deduction + +This patch fixes the incorrect descriptor deduction for vhost crypto. + +CVE-2020-14378 +Fixes: 16d2e718b8ce ("vhost/crypto: fix possible out of bound access") +Cc: stable@dpdk.org + +Signed-off-by: Fan Zhang +Acked-by: Chenbo Xia + +reference:https://git.dpdk.org/dpdk-stable/commit/?h=19.11&id=81e969483020 +Signed-off-by: gaoxingwang +--- + lib/librte_vhost/vhost_crypto.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/lib/librte_vhost/vhost_crypto.c b/lib/librte_vhost/vhost_crypto.c +index 0f9df40..86747dd 100644 +--- a/lib/librte_vhost/vhost_crypto.c ++++ b/lib/librte_vhost/vhost_crypto.c +@@ -530,13 +530,14 @@ move_desc(struct vring_desc *head, struct vring_desc **cur_desc, + int left = size - desc->len; + + while ((desc->flags & VRING_DESC_F_NEXT) && left > 0) { +- (*nb_descs)--; + if (unlikely(*nb_descs == 0 || desc->next >= vq_size)) + return -1; + + desc = &head[desc->next]; + rte_prefetch0(&head[desc->next]); + left -= desc->len; ++ if (left > 0) ++ (*nb_descs)--; + } + + if (unlikely(left > 0)) +-- +cgit v1.0 diff --git a/dpdk.spec b/dpdk.spec index 83994da..407eb96 100644 --- a/dpdk.spec +++ b/dpdk.spec @@ -1,6 +1,6 @@ Name: dpdk Version: 19.11 -Release: 3 +Release: 4 Packager: packaging@6wind.com URL: http://dpdk.org %global source_version 19.11 @@ -11,6 +11,9 @@ Patch1: CVE-2020-10722.patch Patch2: CVE-2020-10723.patch Patch3: CVE-2020-10724.patch Patch4: CVE-2020-10726.patch +Patch5: CVE-2020-14378.patch +Patch6: CVE-2020-14376-CVE-2020-14377.patch +Patch7: fix-pool-allocation.patch Summary: Data Plane Development Kit core Group: System Environment/Libraries @@ -72,6 +75,9 @@ This package contains the pdump tool for capture the dpdk network packets. %patch2 -p1 %patch3 -p1 %patch4 -p1 +%patch5 -p1 +%patch6 -p1 +%patch7 -p1 %build namer=%{kern_devel_ver} @@ -173,6 +179,9 @@ strip -g $RPM_BUILD_ROOT/lib/modules/${namer}/extra/dpdk/rte_kni.ko /usr/sbin/depmod %changelog +* Tue Oct 20 2020 chenxiang - 19.11-4 +-fix CVE-2020-14376 CVE-2020-14377 CVE-2020-14378 + * Wed Sep 23 2020 hubble_zhu - 19.11-3 -Add requires for dpdk-pmdinfo diff --git a/fix-pool-allocation.patch b/fix-pool-allocation.patch new file mode 100644 index 0000000..648bbee --- /dev/null +++ b/fix-pool-allocation.patch @@ -0,0 +1,45 @@ +From 3f2635c5a9c3df4ba7cc0d6598a2023569ca3d39 Mon Sep 17 00:00:00 2001 +From: Fan Zhang +Date: Tue, 14 Apr 2020 16:19:51 +0100 +Subject: vhost/crypto: fix pool allocation + +This patch fixes the missing iv space allocation in crypto +operation mempool. + +Fixes: 709521f4c2cd ("examples/vhost_crypto: support multi-core") +Cc: stable@dpdk.org + +Signed-off-by: Fan Zhang +Acked-by: Chenbo Xia +--- + examples/vhost_crypto/main.c | 2 +- + lib/librte_vhost/rte_vhost_crypto.h | 1 + + 2 files changed, 2 insertions(+), 1 deletion(-) + +diff --git a/examples/vhost_crypto/main.c b/examples/vhost_crypto/main.c +index 1d7ba94..11b022e 100644 +--- a/examples/vhost_crypto/main.c ++++ b/examples/vhost_crypto/main.c +@@ -544,7 +544,7 @@ main(int argc, char *argv[]) + snprintf(name, 127, "COPPOOL_%u", lo->lcore_id); + info->cop_pool = rte_crypto_op_pool_create(name, + RTE_CRYPTO_OP_TYPE_SYMMETRIC, NB_MEMPOOL_OBJS, +- NB_CACHE_OBJS, 0, ++ NB_CACHE_OBJS, VHOST_CRYPTO_MAX_IV_LEN, + rte_lcore_to_socket_id(lo->lcore_id)); + + if (!info->cop_pool) { +diff --git a/lib/librte_vhost/rte_vhost_crypto.h b/lib/librte_vhost/rte_vhost_crypto.h +index d29871c..866a592 100644 +--- a/lib/librte_vhost/rte_vhost_crypto.h ++++ b/lib/librte_vhost/rte_vhost_crypto.h +@@ -10,6 +10,7 @@ + #define VHOST_CRYPTO_SESSION_MAP_ENTRIES (1024) /**< Max nb sessions */ + /** max nb virtual queues in a burst for finalizing*/ + #define VIRTIO_CRYPTO_MAX_NUM_BURST_VQS (64) ++#define VHOST_CRYPTO_MAX_IV_LEN (32) + + enum rte_vhost_crypto_zero_copy { + RTE_VHOST_CRYPTO_ZERO_COPY_DISABLE = 0, +-- +cgit v1.0 -- Gitee