Several functions return on error without freeing allocated resources: uadk_e_digest_soft_work() and uadk_e_digest_copy() skip cleanup labels, leaking the soft ctx; uadk_prov_aead_dupctx() jumps to the wrong label, leaking the WD session; uadk_prov_rsa_private_sign() does not free from_buf on error from rsa_create_pri_bn_ctx or is_valid_rsa_input. Fix by redirecting errors to the appropriate cleanup labels. Signed-off-by: Weili Qian <qianweili@huawei.com> --- src/uadk_digest.c | 11 +++++------ src/uadk_prov_aead.c | 3 +-- src/uadk_prov_rsa_sign.c | 9 +++++---- 3 files changed, 11 insertions(+), 12 deletions(-) diff --git a/src/uadk_digest.c b/src/uadk_digest.c index efdc9b8..72d96b3 100644 --- a/src/uadk_digest.c +++ b/src/uadk_digest.c @@ -314,7 +314,7 @@ static int uadk_e_digest_soft_work(struct digest_priv_ctx *md_ctx, int len, ret = digest_soft_init(md_ctx); if (unlikely(!ret)) - return 0; + goto out; if (len != 0) { ret = digest_soft_update(md_ctx, md_ctx->data, len); @@ -632,8 +632,6 @@ static int uadk_e_digest_init(EVP_MD_CTX *ctx) if (unlikely(!priv->sess)) { priv->switch_flag = UADK_DO_SOFT; priv->data = NULL; - priv->soft_md = NULL; - priv->soft_ctx = NULL; return digest_soft_init(priv); } @@ -739,7 +737,7 @@ do_soft_digest: priv->switch_flag = UADK_DO_SOFT; ret = digest_soft_init(priv); if (!ret) - return ret; + goto out; /* filling buf has been executed */ if (processing_len < DIGEST_BLOCK_SIZE) { ret = digest_soft_update(priv, priv->data, DIGEST_BLOCK_SIZE); @@ -1015,7 +1013,7 @@ static int uadk_e_digest_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from) t->soft_ctx = NULL; if (!digest_soft_init(t)) { fprintf(stderr, "failed to init soft for digest ctx copy.\n"); - return 0; + goto free_data; } if (f->soft_ctx) { memcpy(t->soft_ctx->md_data, f->soft_ctx->md_data, @@ -1023,7 +1021,7 @@ static int uadk_e_digest_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from) } else if (f->last_update_bufflen) { if (!digest_soft_update(t, f->data, f->last_update_bufflen)) { fprintf(stderr, "failed to update for digest ctx copy.\n"); - return 0; + goto free_data; } t->last_update_bufflen = 0; } @@ -1058,6 +1056,7 @@ static int uadk_e_digest_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from) return 1; free_data: + digest_soft_cleanup(t); if (t->data) { free(t->data); t->data = NULL; diff --git a/src/uadk_prov_aead.c b/src/uadk_prov_aead.c index 1919d47..83a7510 100644 --- a/src/uadk_prov_aead.c +++ b/src/uadk_prov_aead.c @@ -1680,7 +1680,7 @@ static void *uadk_prov_aead_dupctx(void *ctx) ret = uadk_prov_aead_copy_sess(dst_ctx); if (ret == UADK_OSSL_FAIL) - goto free_ctx; + goto free_sess; if (dst_ctx->sw_ctx) { dst_ctx->sw_ctx = EVP_CIPHER_CTX_dup(src_ctx->sw_ctx); @@ -1701,7 +1701,6 @@ free_dup: EVP_CIPHER_CTX_free(dst_ctx->sw_ctx); free_sess: uadk_prov_aead_free_sess(dst_ctx); -free_ctx: OPENSSL_clear_free(dst_ctx, sizeof(*dst_ctx)); return NULL; } diff --git a/src/uadk_prov_rsa_sign.c b/src/uadk_prov_rsa_sign.c index 5f309f3..e9f9651 100644 --- a/src/uadk_prov_rsa_sign.c +++ b/src/uadk_prov_rsa_sign.c @@ -295,7 +295,7 @@ static int uadk_prov_rsa_private_sign(int flen, const unsigned char *from, ret = rsa_create_pri_bn_ctx(rsa, prik, &from_buf, &num_bytes); if (ret <= 0 || flen > num_bytes) { ret = UADK_P_FAIL; - goto free_sess; + goto free_buf; } ret = add_rsa_prienc_padding(flen, from, from_buf, num_bytes, padding); @@ -305,8 +305,10 @@ static int uadk_prov_rsa_private_sign(int flen, const unsigned char *from, } ret = is_valid_rsa_input(from_buf, num_bytes, rsa); - if (!ret) - return UADK_P_FAIL; + if (!ret) { + ret = UADK_P_FAIL; + goto free_buf; + } ret = rsa_fill_prikey(rsa, rsa_sess, prik, from_buf, to); if (!ret) { @@ -324,7 +326,6 @@ static int uadk_prov_rsa_private_sign(int flen, const unsigned char *from, free_buf: rsa_free_pri_bn_ctx(from_buf); -free_sess: rsa_free_eng_session(rsa_sess); free_pkey: rsa_pkey_param_free(NULL, &prik); -- 2.43.0