From: Chenghai Huang huangchenghai2@huawei.com
Add the input pointer checking.
Signed-off-by: Chenghai Huang huangchenghai2@huawei.com --- include/wd_util.h | 12 ++++++++++++ wd.c | 2 +- wd_aead.c | 11 +++++++++++ wd_cipher.c | 11 +++++++++++ wd_digest.c | 8 +++++++- wd_sched.c | 14 ++++++++++++-- wd_util.c | 8 ++++++++ 7 files changed, 62 insertions(+), 4 deletions(-)
diff --git a/include/wd_util.h b/include/wd_util.h index 78c5d23..3059ac1 100644 --- a/include/wd_util.h +++ b/include/wd_util.h @@ -235,6 +235,18 @@ void wd_put_msg_to_pool(struct wd_async_msg_pool *pool, int ctx_idx, void *wd_find_msg_in_pool(struct wd_async_msg_pool *pool, int ctx_idx, __u32 tag);
+/* + * wd_check_src_dst() - Check the request input and output + * @src: input data pointer. + * @in_bytes: input data length. + * @dst: output data pointer. + * @out_bytes: output data length. + * + * Return -WD_EINVAL when in_bytes or out_bytes is non-zero, the + * corresponding input or output pointers is NULL, otherwise return 0. + */ +int wd_check_src_dst(void *src, __u32 in_bytes, void *dst, __u32 out_bytes); + /* * wd_check_datalist() - Check the data list length * @head: Data list's head pointer. diff --git a/wd.c b/wd.c index e88c993..998c9be 100644 --- a/wd.c +++ b/wd.c @@ -756,7 +756,7 @@ struct uacce_dev *wd_find_dev_by_numa(struct uacce_dev_list *list, int numa_id) }
while (p) { - if (numa_id != p->dev->numa_id) { + if (p->dev && numa_id != p->dev->numa_id) { p = p->next; continue; } diff --git a/wd_aead.c b/wd_aead.c index ff43086..6d49d76 100644 --- a/wd_aead.c +++ b/wd_aead.c @@ -361,6 +361,11 @@ static int wd_aead_param_check(struct wd_aead_sess *sess, return -WD_EINVAL; }
+ if (unlikely(!req->iv || !req->mac)) { + WD_ERR("invalid: aead input iv or mac is NULL!\n"); + return -WD_EINVAL; + } + if (unlikely(sess->cmode == WD_CIPHER_CBC && req->in_bytes == 0)) { WD_ERR("aead input data length is zero!\n"); return -WD_EINVAL; @@ -384,6 +389,12 @@ static int wd_aead_param_check(struct wd_aead_sess *sess, return -WD_EINVAL; }
+ ret = wd_check_src_dst(req->src, req->in_bytes, req->dst, req->out_bytes); + if (unlikely(ret)) { + WD_ERR("invalid: src/dst addr is NULL when src/dst size is non-zero!\n"); + return -WD_EINVAL; + } + if (req->data_fmt == WD_SGL_BUF) { len = req->in_bytes + req->assoc_bytes; ret = wd_check_datalist(req->list_src, len); diff --git a/wd_cipher.c b/wd_cipher.c index 0187c9c..47c0bf8 100644 --- a/wd_cipher.c +++ b/wd_cipher.c @@ -542,6 +542,11 @@ static int cipher_iv_len_check(struct wd_cipher_req *req, if (sess->mode == WD_CIPHER_ECB) return 0;
+ if (!req->iv) { + WD_ERR("invalid: cipher input iv is NULL!\n"); + ret = -WD_EINVAL; + } + switch (sess->alg) { case WD_CIPHER_AES: case WD_CIPHER_SM4: @@ -589,6 +594,12 @@ static int wd_cipher_check_params(handle_t h_sess, return -WD_EINVAL; }
+ ret = wd_check_src_dst(req->src, req->in_bytes, req->dst, req->out_bytes); + if (unlikely(ret)) { + WD_ERR("invalid: src/dst addr is NULL when src/dst size is non-zero!\n"); + return -WD_EINVAL; + } + if (req->data_fmt == WD_SGL_BUF) { ret = wd_check_datalist(req->list_src, req->in_bytes); if (unlikely(ret)) { diff --git a/wd_digest.c b/wd_digest.c index 1f2b3b2..9008bcb 100644 --- a/wd_digest.c +++ b/wd_digest.c @@ -514,12 +514,18 @@ static int wd_digest_param_check(struct wd_digest_sess *sess, return ret;
if (unlikely(sess->alg == WD_DIGEST_AES_GMAC && - req->iv_bytes != GMAC_IV_LEN)) { + (!req->iv || req->iv_bytes != GMAC_IV_LEN))) { WD_ERR("failed to check digest aes_gmac iv length, iv_bytes = %u\n", req->iv_bytes); return -WD_EINVAL; }
+ ret = wd_check_src_dst(req->in, req->in_bytes, req->out, req->out_bytes); + if (unlikely(ret)) { + WD_ERR("invalid: in/out addr is NULL when in/out size is non-zero!\n"); + return -WD_EINVAL; + } + if (req->data_fmt == WD_SGL_BUF) { ret = wd_check_datalist(req->list_in, req->in_bytes); if (unlikely(ret)) { diff --git a/wd_sched.c b/wd_sched.c index d1c829f..7aeea73 100644 --- a/wd_sched.c +++ b/wd_sched.c @@ -311,8 +311,8 @@ static int session_sched_poll_policy(handle_t h_sched_ctx, __u32 expect, __u32 * __u16 i; int ret;
- if (unlikely(!count || !sched_ctx)) { - WD_ERR("invalid: sched ctx is NULL or count is zero!\n"); + if (unlikely(!count || !sched_ctx || !sched_ctx->poll_func)) { + WD_ERR("invalid: sched ctx or poll_func is NULL or count is zero!\n"); return -WD_EINVAL; }
@@ -375,6 +375,11 @@ static int sched_none_poll_policy(handle_t h_sched_ctx, __u32 poll_num = 0; int ret;
+ if (!sched_ctx || !sched_ctx->poll_func) { + WD_ERR("invalid: sched ctx or poll_func is NULL!\n"); + return -WD_EINVAL; + } + while (loop_times > 0) { /* Default use ctx 0 */ loop_times--; @@ -417,6 +422,11 @@ static int sched_single_poll_policy(handle_t h_sched_ctx, __u32 poll_num = 0; int ret;
+ if (!sched_ctx || !sched_ctx->poll_func) { + WD_ERR("invalid: sched ctx or poll_func is NULL!\n"); + return -WD_EINVAL; + } + while (loop_times > 0) { /* Default async mode use ctx 0 */ loop_times--; diff --git a/wd_util.c b/wd_util.c index 409a8c8..91f1d73 100644 --- a/wd_util.c +++ b/wd_util.c @@ -459,6 +459,14 @@ void wd_put_msg_to_pool(struct wd_async_msg_pool *pool, int ctx_idx, __u32 tag) __atomic_clear(&p->used[tag - 1], __ATOMIC_RELEASE); }
+int wd_check_src_dst(void *src, __u32 in_bytes, void *dst, __u32 out_bytes) +{ + if ((in_bytes && !src) || (out_bytes && !dst)) + return -WD_EINVAL; + + return 0; +} + int wd_check_datalist(struct wd_datalist *head, __u32 size) { struct wd_datalist *tmp = head;