Make async callback param use the memory on heap rather than stack, or other async related functions may modify the address of cb param and cause unknown error.
Signed-off-by: Zhiqi Song songzhiqi1@huawei.com Signed-off-by: JiangShui Yang yangjiangshui@h-partners.com --- src/uadk_dh.c | 121 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 74 insertions(+), 47 deletions(-)
diff --git a/src/uadk_dh.c b/src/uadk_dh.c index 28aa452..582cc95 100644 --- a/src/uadk_dh.c +++ b/src/uadk_dh.c @@ -712,66 +712,93 @@ free_ag: return UADK_E_FAIL; }
-static int dh_do_crypto(struct uadk_dh_sess *dh_sess) +static int dh_do_sync(struct uadk_dh_sess *dh_sess) { - struct uadk_e_cb_info cb_param; - struct async_op op; - int idx, ret, cnt; + int ret;
- ret = async_setup_async_event_notification(&op); - if (!ret) { - printf("failed to setup async event notification.\n"); + ret = wd_do_dh_sync(dh_sess->sess, &dh_sess->req); + if (ret) { + if (ret == -WD_HW_EACCESS) + uadk_e_dh_set_status(); return UADK_E_FAIL; }
- if (!op.job) { - ret = wd_do_dh_sync(dh_sess->sess, &dh_sess->req); - if (ret) { - if (ret == -WD_HW_EACCESS) + return UADK_E_SUCCESS; +} + +static int dh_do_async(struct uadk_dh_sess *dh_sess, struct async_op *op) +{ + struct uadk_e_cb_info *cb_param; + int ret = 0; + int cnt = 0; + int idx; + + cb_param = malloc(sizeof(struct uadk_e_cb_info)); + if (!cb_param) { + fprintf(stderr, "failed to alloc cb_param.\n"); + return ret; + } + + cb_param->op = op; + cb_param->priv = &dh_sess->req; + dh_sess->req.cb = uadk_e_dh_cb; + dh_sess->req.cb_param = cb_param; + dh_sess->req.status = -1; + ret = async_get_free_task(&idx); + if (!ret) + goto free_cb_param; + + op->idx = idx; + do { + ret = wd_do_dh_async(dh_sess->sess, &dh_sess->req); + if (unlikely(ret < 0)) { + if (unlikely(ret == -WD_HW_EACCESS)) uadk_e_dh_set_status(); - return UADK_E_FAIL; + else if (unlikely(cnt++ > ENGINE_SEND_MAX_CNT)) + fprintf(stderr, "do dh async operation timeout.\n"); + else + continue; + + async_free_poll_task(op->idx, 0); + ret = UADK_E_FAIL; + goto free_cb_param; } - } else { - cb_param.op = &op; - cb_param.priv = &dh_sess->req; - dh_sess->req.cb = uadk_e_dh_cb; - dh_sess->req.cb_param = &cb_param; - dh_sess->req.status = -1; - ret = async_get_free_task(&idx); - if (!ret) - goto err; + } while (ret == -EBUSY);
- op.idx = idx; - cnt = 0; - do { - ret = wd_do_dh_async(dh_sess->sess, &dh_sess->req); - if (unlikely(ret < 0)) { - if (unlikely(ret == -WD_HW_EACCESS)) - uadk_e_dh_set_status(); - else if (unlikely(cnt++ > ENGINE_SEND_MAX_CNT)) - fprintf(stderr, "do dh async operation timeout.\n"); - else - continue; - - async_free_poll_task(op.idx, 0); - goto err; - } - } while (ret == -EBUSY); - - ret = async_pause_job(dh_sess, &op, ASYNC_TASK_DH); - if (!ret) - goto err; + ret = async_pause_job(dh_sess, op, ASYNC_TASK_DH); + if (!ret) + goto free_cb_param;
- ret = dh_sess->req.status; - if (ret) - goto err; + if (dh_sess->req.status) { + ret = UADK_E_FAIL; + goto free_cb_param; }
- return UADK_E_SUCCESS; +free_cb_param: + free(cb_param); + return ret; +}
-err: +static int dh_do_crypto(struct uadk_dh_sess *dh_sess) +{ + struct async_op op; + int ret = 0; + + ret = async_setup_async_event_notification(&op); + if (!ret) { + printf("failed to setup async event notification.\n"); + return ret; + } + + if (!op.job) { + ret = dh_do_sync(dh_sess); + return ret; + } + + ret = dh_do_async(dh_sess, &op); (void)async_clear_async_event_notification(); - return UADK_E_FAIL; + + return ret; }
static int dh_soft_set_pkey(DH *dh, BIGNUM *pub_key, BIGNUM *priv_key)