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 --- src/uadk_dh.c | 100 +++++++++++++++++++++++++++++++------------------- 1 file changed, 63 insertions(+), 37 deletions(-)
diff --git a/src/uadk_dh.c b/src/uadk_dh.c index acb5b8a..c0b58ef 100644 --- a/src/uadk_dh.c +++ b/src/uadk_dh.c @@ -692,56 +692,82 @@ free_ag: return UADK_E_FAIL; }
+static int dh_do_sync(struct uadk_dh_sess *dh_sess) +{ + int ret; + + ret = wd_do_dh_sync(dh_sess->sess, &dh_sess->req); + if (ret) + return UADK_E_FAIL; + + 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 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 (ret < 0 && ret != -EBUSY) { + async_free_poll_task(idx, 0); + ret = UADK_E_FAIL; + goto free_cb_param; + } + } while (ret == -EBUSY); + + ret = async_pause_job(dh_sess, op, ASYNC_TASK_DH, idx); + if (!ret) + goto free_cb_param; + + if (dh_sess->req.status) { + ret = UADK_E_FAIL; + goto free_cb_param; + } + +free_cb_param: + free(cb_param); + return ret; +} + static int dh_do_crypto(struct uadk_dh_sess *dh_sess) { - struct uadk_e_cb_info cb_param; struct async_op op; - int idx, ret; + int ret = 0;
ret = async_setup_async_event_notification(&op); if (!ret) { printf("failed to setup async event notification.\n"); - return UADK_E_FAIL; + return ret; }
if (!op.job) { - ret = wd_do_dh_sync(dh_sess->sess, &dh_sess->req); - if (ret) - return UADK_E_FAIL; - } 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; - - op.idx = idx; - - do { - ret = wd_do_dh_async(dh_sess->sess, &dh_sess->req); - if (ret < 0 && ret != -EBUSY) { - async_free_poll_task(idx, 0); - goto err; - } - } while (ret == -EBUSY); - - ret = async_pause_job(dh_sess, &op, ASYNC_TASK_DH, idx); - if (!ret) - goto err; - - ret = dh_sess->req.status; - if (ret) - goto err; + ret = dh_do_sync(dh_sess); + return ret; }
- return UADK_E_SUCCESS; - -err: + 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)