When call uadk_engine by gmssl: gmssl speed -elapsed -engine uadk_engine -async_jobs 16
There is a core dump, the call stack is: | read | async_pause_job | do_digest_async | uadk_e_digest_final | EVP_DigestFinal_ex | rand_bytes | rand_nopseudo_bytes | RAND_bytes | bnrand | BN_pseudo_rand | bn_rand_range | BN_priv_rand_range | uadk_ecc_get_rand | generate_random | new_sign_in | wd_sm2_new_sign_in | sm2_sign_init_iot After finishing uadk_e_digest_final(), EVP_DigestFinal_ex() will continue calling cleanup() function, the address of async job will be changed. As the address is on stack, if the async thread happens to use this async job, the core dump will occur: | ASYNC_WAIT_CTX_get_fd | async_wake_job | async_cb | wd_digest_poll_ctx | uadk_e_digest_poll | async_poll_process_func So the address of op should be on heap to save the async job, or it will be released by digest cleaup process, and affects the following async task.
Signed-off-by: Zhiqi Song songzhiqi1@huawei.com --- src/uadk_digest.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-)
diff --git a/src/uadk_digest.c b/src/uadk_digest.c index fa96e57..0aa90f3 100644 --- a/src/uadk_digest.c +++ b/src/uadk_digest.c @@ -767,7 +767,7 @@ static int uadk_e_digest_final(EVP_MD_CTX *ctx, unsigned char *digest) { struct digest_priv_ctx *priv = (struct digest_priv_ctx *)EVP_MD_CTX_md_data(ctx); - struct async_op op; + struct async_op *op; int ret = 1;
digest_set_msg_state(priv, true); @@ -782,13 +782,18 @@ static int uadk_e_digest_final(EVP_MD_CTX *ctx, unsigned char *digest) if (priv->e_nid == NID_sha384) priv->req.out_bytes = WD_DIGEST_SHA384_LEN;
- ret = async_setup_async_event_notification(&op); + op = malloc(sizeof(struct async_op)); + if (!op) + return 0; + + ret = async_setup_async_event_notification(op); if (unlikely(!ret)) { fprintf(stderr, "failed to setup async event notification.\n"); + free(op); return 0; }
- if (op.job == NULL) { + if (!op->job) { /* Synchronous, only the synchronous mode supports soft computing */ if (unlikely(priv->switch_flag == UADK_DO_SOFT)) { ret = digest_soft_final(priv, digest); @@ -800,12 +805,13 @@ static int uadk_e_digest_final(EVP_MD_CTX *ctx, unsigned char *digest) if (!ret) goto sync_err; } else { - ret = do_digest_async(priv, &op); + ret = do_digest_async(priv, op); if (!ret) goto clear; } memcpy(digest, priv->req.out, priv->req.out_bytes);
+ free(op); return 1;
sync_err: @@ -817,6 +823,7 @@ sync_err: } clear: async_clear_async_event_notification(); + free(op); return ret; }