From acd4c92fa693bbea695f2bb42bb93fb8567c3ca5 Mon Sep 17 00:00:00 2001 From: Maxime Coquelin Date: Mon, 18 May 2020 14:17:01 +0100 Subject: [PATCH] vhost/crypto: validate keys lengths transform_cipher_param() and transform_chain_param() handle the payload data for the VHOST_USER_CRYPTO_CREATE_SESS message. These payloads have to be validated, since it could come from untrusted sources. Two buffers and their lengths are defined in this payload, one the the auth key and one for the cipher key. But above functions do not validate the key length inputs, which could lead to read out of bounds, as buffers have static sizes of 64 bytes for the cipher key and 512 bytes for the auth key. This patch adds necessary checks on the key length field before being used. CVE-2020-10724 Fixes: e80a98708166 ("vhost/crypto: add session message handler") Cc: stable@dpdk.org Reported-by: Ilja Van Sprundel Signed-off-by: Maxime Coquelin Reviewed-by: Xiaolong Ye Reviewed-by: Ilja Van Sprundel --- lib/librte_vhost/vhost_crypto.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/lib/librte_vhost/vhost_crypto.c b/lib/librte_vhost/vhost_crypto.c index 2e52ecae87..0f9df4059d 100644 --- a/lib/librte_vhost/vhost_crypto.c +++ b/lib/librte_vhost/vhost_crypto.c @@ -238,6 +238,11 @@ transform_cipher_param(struct rte_crypto_sym_xform *xform, if (unlikely(ret < 0)) return ret; + if (param->cipher_key_len > VHOST_USER_CRYPTO_MAX_CIPHER_KEY_LENGTH) { + VC_LOG_DBG("Invalid cipher key length\n"); + return -VIRTIO_CRYPTO_BADMSG; + } + xform->type = RTE_CRYPTO_SYM_XFORM_CIPHER; xform->cipher.key.length = param->cipher_key_len; if (xform->cipher.key.length > 0) @@ -288,6 +293,12 @@ transform_chain_param(struct rte_crypto_sym_xform *xforms, &xform_cipher->cipher.algo); if (unlikely(ret < 0)) return ret; + + if (param->cipher_key_len > VHOST_USER_CRYPTO_MAX_CIPHER_KEY_LENGTH) { + VC_LOG_DBG("Invalid cipher key length\n"); + return -VIRTIO_CRYPTO_BADMSG; + } + xform_cipher->type = RTE_CRYPTO_SYM_XFORM_CIPHER; xform_cipher->cipher.key.length = param->cipher_key_len; xform_cipher->cipher.key.data = param->cipher_key_buf; @@ -302,6 +313,12 @@ transform_chain_param(struct rte_crypto_sym_xform *xforms, ret = auth_algo_transform(param->hash_algo, &xform_auth->auth.algo); if (unlikely(ret < 0)) return ret; + + if (param->auth_key_len > VHOST_USER_CRYPTO_MAX_HMAC_KEY_LENGTH) { + VC_LOG_DBG("Invalid auth key length\n"); + return -VIRTIO_CRYPTO_BADMSG; + } + xform_auth->auth.digest_length = param->digest_len; xform_auth->auth.key.length = param->auth_key_len; xform_auth->auth.key.data = param->auth_key_buf; -- 2.20.1