From: Weili Qian <qianweili@huawei.com> Drop redundant priv sentinel field from all algorithm modules (aead, cipher, comp, dh, digest, ecc, rsa) and replace with wd_alg_get_init() status guard. Clear comp drv_count on uninit to prevent use-after-free. Fix build errors Signed-off-by: Weili Qian <qianweili@huawei.com> --- drv/hisi_hpre.c | 3 --- drv/hisi_sec.c | 1 - drv/wd_drv.c | 20 ++----------------- include/wd_internal.h | 2 +- wd.c | 3 ++- wd_aead.c | 46 +++++++++++++++++++++---------------------- wd_sched.c | 3 ++- 7 files changed, 30 insertions(+), 48 deletions(-) diff --git a/drv/hisi_hpre.c b/drv/hisi_hpre.c index 9e46d77..0fa6978 100644 --- a/drv/hisi_hpre.c +++ b/drv/hisi_hpre.c @@ -2964,7 +2964,6 @@ static int hpre_ecc_get_extend_ops(void *ops) .drv_data = NULL, \ .extend_ops = NULL, \ .fallback = 0,\ - .init_state = 0,\ .init = hpre_ecc_init,\ .exit = hpre_exit,\ .send = ecc_send,\ @@ -2993,7 +2992,6 @@ static struct wd_alg_driver hpre_rsa_driver = { .op_type_num = 1, .drv_data = NULL, .fallback = 0, - .init_state = 0, .init = hpre_rsa_dh_init, .exit = hpre_exit, .send = rsa_send, @@ -3013,7 +3011,6 @@ static struct wd_alg_driver hpre_dh_driver = { .op_type_num = 1, .drv_data = NULL, .fallback = 0, - .init_state = 0, .init = hpre_rsa_dh_init, .exit = hpre_exit, .send = dh_send, diff --git a/drv/hisi_sec.c b/drv/hisi_sec.c index 91fa4ce..10bb34e 100644 --- a/drv/hisi_sec.c +++ b/drv/hisi_sec.c @@ -793,7 +793,6 @@ static int sec_aead_get_extend_ops(void *ops) .op_type_num = 1,\ .drv_data = NULL,\ .fallback = 0,\ - .init_state = 0,\ .init = hisi_sec_init,\ .exit = hisi_sec_exit,\ .send = alg_type##_send,\ diff --git a/drv/wd_drv.c b/drv/wd_drv.c index d6a7626..9290c8c 100644 --- a/drv/wd_drv.c +++ b/drv/wd_drv.c @@ -10,7 +10,6 @@ int wd_soft_alloc_ctx(char *alg_name, void *params, handle_t *ctx) { - struct wd_drv_ctx_params *ctx_params = (struct wd_drv_ctx_params *)params; struct wd_soft_ctx *sfctx; if (!params || !ctx) { @@ -163,21 +162,6 @@ out_free_list: return ret; } -static int wd_get_alg_class_type(const char *alg_name, char *alg_type) -{ - int ret; - - ret = wd_get_alg_type(alg_name, alg_type); - if (ret) - return -WD_EINVAL; - - /* all ECC types use sm2 to find device. */ - if (!strcmp(alg_type, "ecc")) - strcpy(alg_type, "sm2"); - - return WD_SUCCESS; -} - /** * wd_hw_alloc_ctx() - HW driver's alloc_ctx callback. * @@ -210,8 +194,8 @@ int wd_hw_alloc_ctx(char *alg_name, void *params, handle_t *ctx) } target_numa = ctx_params->numa_id; - /* Get algorithm class type and device list */ - ret = wd_get_alg_class_type(alg_name, alg_type); + /* Get algorithm type and device list */ + ret = wd_get_alg_type(alg_name, alg_type); if (ret) { WD_ERR("invalid: alg_name is NULL!\n"); return -WD_EINVAL; diff --git a/include/wd_internal.h b/include/wd_internal.h index 95ceaa2..38fb29e 100644 --- a/include/wd_internal.h +++ b/include/wd_internal.h @@ -49,7 +49,7 @@ struct wd_ctx_config_internal { void *priv; bool epoll_en; unsigned long *msg_cnt; - char *alg_name; + const char *alg_name; struct wd_alg_driver **drv_array; __u32 drv_count; diff --git a/wd.c b/wd.c index ede0bf2..f973c70 100644 --- a/wd.c +++ b/wd.c @@ -1165,7 +1165,8 @@ int wd_get_dev_usage(struct uacce_dev *dev, const char *alg_name, __u8 alg_op_ty { char *dev_name; int ret; - if (!dev || !alg_name) { + + if (!dev || !alg_name || !strlen(dev->algs)) { WD_ERR("invalid: dev or alg name is NULL!\n"); return -WD_EINVAL; } diff --git a/wd_aead.c b/wd_aead.c index ba3c116..4e25e21 100644 --- a/wd_aead.c +++ b/wd_aead.c @@ -625,13 +625,13 @@ static int wd_aead_param_check(struct wd_aead_sess *sess, return 0; } +static bool wd_aead_atfork_registered; + static void wd_aead_clear_status(void) { wd_alg_clear_init(&wd_aead_setting.status); } -static bool wd_aead_atfork_registered; - static int wd_aead_init_nolock(struct wd_ctx_config *config, struct wd_sched *sched) { int ret; @@ -657,15 +657,8 @@ static int wd_aead_init_nolock(struct wd_ctx_config *config, struct wd_sched *sc if (ret < 0) goto out_clear_sched; - ret = wd_alg_init_driver(&wd_aead_setting.config, - wd_aead_setting.driver); - if (ret) - goto out_clear_pool; - return 0; -out_clear_pool: - wd_uninit_async_request_pool(&wd_aead_setting.pool); out_clear_sched: wd_clear_sched(&wd_aead_setting.sched); out_clear_ctx_config: @@ -674,6 +667,12 @@ out_clear_ctx_config: return ret; } +static void wd_aead_uninit_nolock(void) +{ + wd_uninit_async_request_pool(&wd_aead_setting.pool); + wd_clear_sched(&wd_aead_setting.sched); +} + int wd_aead_init(struct wd_ctx_config *config, struct wd_sched *sched) { __u32 drv_count; @@ -684,13 +683,6 @@ int wd_aead_init(struct wd_ctx_config *config, struct wd_sched *sched) wd_aead_atfork_registered = true; } - /* init1 path is HW-only; CE/SVE drivers require init2 */ - if (sched->sched_policy == SCHED_POLICY_NONE || - sched->sched_policy == SCHED_POLICY_SINGLE) { - WD_ERR("init1 does not support NONE/SINGLE schedulers, use init2\n"); - return -WD_EINVAL; - } - ret = wd_alg_try_init(&wd_aead_setting.status); if (ret) return ret; @@ -699,10 +691,22 @@ int wd_aead_init(struct wd_ctx_config *config, struct wd_sched *sched) if (ret) goto out_clear_init; + /* init1 path is HW-only; CE/SVE drivers require init2 */ + if (sched->sched_policy == SCHED_POLICY_NONE || + sched->sched_policy == SCHED_POLICY_SINGLE) { + WD_ERR("init1 does not support NONE/SINGLE schedulers, use init2\n"); + ret = -WD_EINVAL; + goto out_clear_init; + } + ret = wd_aead_open_driver(WD_TYPE_V1); if (ret) goto out_clear_init; + ret = wd_aead_init_nolock(config, sched); + if (ret) + goto out_close_driver; + /* Driver discovery */ ret = wd_get_drv_array("aead", TASK_HW, "hisi_sec2", &wd_aead_setting.config.drv_array, &drv_count); @@ -744,12 +748,6 @@ out_clear_init: return ret; } -static void wd_aead_uninit_nolock(void) -{ - wd_uninit_async_request_pool(&wd_aead_setting.pool); - wd_clear_sched(&wd_aead_setting.sched); -} - void wd_aead_uninit(void) { enum wd_status status; @@ -798,7 +796,7 @@ int wd_aead_init2_(char *alg, __u32 sched_type, int task_type, state = wd_alg_try_init(&wd_aead_setting.status); if (state) - goto out_uninit; + return state; if (!alg || sched_type >= SCHED_POLICY_BUTT || task_type < 0 || task_type >= TASK_MAX_TYPE) { @@ -895,6 +893,8 @@ void wd_aead_uninit2(void) wd_alg_uninit_driver(&wd_aead_setting.config); wd_ctx_unbind_drivers(&wd_aead_setting.config); + wd_aead_setting.config.drv_array = NULL; + wd_aead_setting.config.drv_count = 0; wd_aead_uninit_nolock(); wd_alg_attrs_uninit(&wd_aead_init_attrs); diff --git a/wd_sched.c b/wd_sched.c index f704d59..95072ea 100644 --- a/wd_sched.c +++ b/wd_sched.c @@ -2035,6 +2035,7 @@ static void wd_sched_set_param(handle_t h_sched_ctx, { struct wd_sched_params *params = (struct wd_sched_params *)sched_param; struct wd_sched_key *skey = (struct wd_sched_key *)sched_key; + struct wd_sched_ctx *sched_ctx = (struct wd_sched_ctx *)h_sched_ctx; if (unlikely(!params || !skey)) { WD_INFO("info: sched parmas or skey is NULL!\n"); @@ -2051,7 +2052,7 @@ static void wd_sched_set_param(handle_t h_sched_ctx, /* If compat info provided, fix up pre-fetched ctxs */ if (skey->alg_name && skey->ctxs) { - wd_sched_skey_compat_filter(h_sched_ctx, skey, + wd_sched_skey_compat_filter(sched_ctx, skey, &skey->sync_domain, SCHED_MODE_SYNC); wd_sched_skey_compat_filter(sched_ctx, skey, &skey->async_domain, SCHED_MODE_ASYNC); -- 2.43.0