410 lines
12 KiB
Diff
410 lines
12 KiB
Diff
From 79bd75212d39325f825549bb206992b912542a70 Mon Sep 17 00:00:00 2001
|
|
From: Qi Tao <taoqi10@huawei.com>
|
|
Date: Fri, 24 Nov 2023 11:57:05 +0800
|
|
Subject: [PATCH 096/123] uadk/v1: check whether the data address pointer is
|
|
not null
|
|
|
|
The data address pointers were used without address verification,
|
|
which may cause null pointer risks.
|
|
|
|
Signed-off-by: Qi Tao <taoqi10@huawei.com>
|
|
---
|
|
v1/wd_aead.c | 22 +++++++++++++++++-----
|
|
v1/wd_cipher.c | 22 +++++++++++++++++-----
|
|
v1/wd_comp.c | 10 +++++-----
|
|
v1/wd_dh.c | 6 +++---
|
|
v1/wd_digest.c | 19 +++++++++++++------
|
|
v1/wd_ecc.c | 8 ++++----
|
|
v1/wd_rng.c | 13 +++++++++----
|
|
v1/wd_rsa.c | 12 +++++++++---
|
|
v1/wd_util.c | 7 +++++++
|
|
v1/wd_util.h | 1 +
|
|
10 files changed, 85 insertions(+), 35 deletions(-)
|
|
|
|
diff --git a/v1/wd_aead.c b/v1/wd_aead.c
|
|
index a82d51d..f688309 100644
|
|
--- a/v1/wd_aead.c
|
|
+++ b/v1/wd_aead.c
|
|
@@ -124,7 +124,7 @@ static int get_iv_block_size(int mode)
|
|
static int create_ctx_para_check(struct wd_queue *q,
|
|
struct wcrypto_aead_ctx_setup *setup)
|
|
{
|
|
- if (!q || !setup) {
|
|
+ if (!q || !q->qinfo || !setup) {
|
|
WD_ERR("input param is NULL\n");
|
|
return -WD_EINVAL;
|
|
}
|
|
@@ -542,26 +542,38 @@ static int param_check(struct wcrypto_aead_ctx *a_ctx,
|
|
void **tag, __u32 num)
|
|
{
|
|
__u32 i;
|
|
+ int ret;
|
|
|
|
if (unlikely(!a_ctx || !a_opdata || !num || num > WCRYPTO_MAX_BURST_NUM)) {
|
|
- WD_ERR("input param err!\n");
|
|
+ WD_ERR("invalid: input param err!\n");
|
|
return -WD_EINVAL;
|
|
}
|
|
|
|
for (i = 0; i < num; i++) {
|
|
if (unlikely(!a_opdata[i])) {
|
|
- WD_ERR("aead opdata[%u] is NULL!\n", i);
|
|
+ WD_ERR("invalid: aead opdata[%u] is NULL\n", i);
|
|
+ return -WD_EINVAL;
|
|
+ }
|
|
+
|
|
+ ret = wd_check_src_dst(a_opdata[i]->in, a_opdata[i]->in_bytes, a_opdata[i]->out, a_opdata[i]->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 (unlikely(!a_opdata[i]->iv)) {
|
|
+ WD_ERR("invalid: aead input iv is NULL!\n");
|
|
return -WD_EINVAL;
|
|
}
|
|
|
|
if (unlikely(tag && !tag[i])) {
|
|
- WD_ERR("tag[%u] is NULL!\n", i);
|
|
+ WD_ERR("invalid: tag[%u] is NULL!\n", i);
|
|
return -WD_EINVAL;
|
|
}
|
|
}
|
|
|
|
if (unlikely(tag && !a_ctx->setup.cb)) {
|
|
- WD_ERR("aead ctx call back is NULL!\n");
|
|
+ WD_ERR("invalid: aead ctx call back is NULL!\n");
|
|
return -WD_EINVAL;
|
|
}
|
|
|
|
diff --git a/v1/wd_cipher.c b/v1/wd_cipher.c
|
|
index 3e6fb3d..60a0f25 100644
|
|
--- a/v1/wd_cipher.c
|
|
+++ b/v1/wd_cipher.c
|
|
@@ -107,7 +107,7 @@ static __u32 get_iv_block_size(int alg, int mode)
|
|
static int create_ctx_para_check(struct wd_queue *q,
|
|
struct wcrypto_cipher_ctx_setup *setup)
|
|
{
|
|
- if (!q || !setup) {
|
|
+ if (!q || !q->qinfo || !setup) {
|
|
WD_ERR("%s: input param err!\n", __func__);
|
|
return -WD_EINVAL;
|
|
}
|
|
@@ -426,26 +426,38 @@ static int param_check(struct wcrypto_cipher_ctx *c_ctx,
|
|
void **tag, __u32 num)
|
|
{
|
|
__u32 i;
|
|
+ int ret;
|
|
|
|
if (unlikely(!c_ctx || !c_opdata || !num || num > WCRYPTO_MAX_BURST_NUM)) {
|
|
- WD_ERR("input param err!\n");
|
|
+ WD_ERR("invalid: input param err!\n");
|
|
return -WD_EINVAL;
|
|
}
|
|
|
|
for (i = 0; i < num; i++) {
|
|
if (unlikely(!c_opdata[i])) {
|
|
- WD_ERR("cipher opdata[%u] is NULL!\n", i);
|
|
+ WD_ERR("invalid: cipher opdata[%u] is NULL!\n", i);
|
|
+ return -WD_EINVAL;
|
|
+ }
|
|
+
|
|
+ ret = wd_check_src_dst(c_opdata[i]->in, c_opdata[i]->in_bytes, c_opdata[i]->out, c_opdata[i]->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 (c_ctx->setup.mode != WCRYPTO_CIPHER_ECB && !c_opdata[i]->iv) {
|
|
+ WD_ERR("invalid: cipher input iv is NULL!\n");
|
|
return -WD_EINVAL;
|
|
}
|
|
|
|
if (unlikely(tag && !tag[i])) {
|
|
- WD_ERR("tag[%u] is NULL!\n", i);
|
|
+ WD_ERR("invalid: tag[%u] is NULL!\n", i);
|
|
return -WD_EINVAL;
|
|
}
|
|
}
|
|
|
|
if (unlikely(tag && !c_ctx->setup.cb)) {
|
|
- WD_ERR("cipher ctx call back is NULL!\n");
|
|
+ WD_ERR("invalid: cipher ctx call back is NULL!\n");
|
|
return -WD_EINVAL;
|
|
}
|
|
|
|
diff --git a/v1/wd_comp.c b/v1/wd_comp.c
|
|
index dd838eb..169f1b4 100644
|
|
--- a/v1/wd_comp.c
|
|
+++ b/v1/wd_comp.c
|
|
@@ -60,8 +60,8 @@ static int ctx_params_check(struct wd_queue *q, struct wcrypto_comp_ctx_setup *s
|
|
{
|
|
struct q_info *qinfo;
|
|
|
|
- if (!q || !setup) {
|
|
- WD_ERR("err: q or setup is NULL!\n");
|
|
+ if (!q || !q->qinfo || !setup) {
|
|
+ WD_ERR("%s: input param err!\n", __func__);
|
|
return -WD_EINVAL;
|
|
}
|
|
|
|
@@ -255,8 +255,8 @@ int wcrypto_do_comp(void *ctx, struct wcrypto_comp_op_data *opdata, void *tag)
|
|
__u64 recv_count = 0;
|
|
int ret;
|
|
|
|
- if (!ctx || !opdata) {
|
|
- WD_ERR("input parameter err!\n");
|
|
+ if (unlikely(!ctx || !opdata || !opdata->in || !opdata->out)) {
|
|
+ WD_ERR("invalid: comp input parameter err!\n");
|
|
return -EINVAL;
|
|
}
|
|
|
|
@@ -267,7 +267,7 @@ int wcrypto_do_comp(void *ctx, struct wcrypto_comp_op_data *opdata, void *tag)
|
|
msg = &cookie->msg;
|
|
if (tag) {
|
|
if (!cctx->cb) {
|
|
- WD_ERR("ctx call back is null!\n");
|
|
+ WD_ERR("invalid: ctx call back is null!\n");
|
|
ret = -WD_EINVAL;
|
|
goto err_put_cookie;
|
|
}
|
|
diff --git a/v1/wd_dh.c b/v1/wd_dh.c
|
|
index 9ed0e0d..27bcb5a 100644
|
|
--- a/v1/wd_dh.c
|
|
+++ b/v1/wd_dh.c
|
|
@@ -56,7 +56,7 @@ struct wcrypto_dh_ctx {
|
|
static int create_ctx_param_check(struct wd_queue *q,
|
|
struct wcrypto_dh_ctx_setup *setup)
|
|
{
|
|
- if (!q || !setup) {
|
|
+ if (!q || !q->qinfo || !setup) {
|
|
WD_ERR("%s(): input parameter err!\n", __func__);
|
|
return -WD_EINVAL;
|
|
}
|
|
@@ -299,12 +299,12 @@ static int do_dh_prepare(struct wcrypto_dh_op_data *opdata,
|
|
int ret;
|
|
|
|
if (unlikely(!ctxt || !opdata)) {
|
|
- WD_ERR("input parameter err!\n");
|
|
+ WD_ERR("invalid: dh input parameter err!\n");
|
|
return -WD_EINVAL;
|
|
}
|
|
|
|
if (unlikely(tag && !ctxt->setup.cb)) {
|
|
- WD_ERR("ctx call back is null!\n");
|
|
+ WD_ERR("invalid: ctx call back is null!\n");
|
|
return -WD_EINVAL;
|
|
}
|
|
|
|
diff --git a/v1/wd_digest.c b/v1/wd_digest.c
|
|
index f6c8b84..b617350 100644
|
|
--- a/v1/wd_digest.c
|
|
+++ b/v1/wd_digest.c
|
|
@@ -89,7 +89,7 @@ static void del_ctx_key(struct wcrypto_digest_ctx *ctx)
|
|
static int create_ctx_para_check(struct wd_queue *q,
|
|
struct wcrypto_digest_ctx_setup *setup)
|
|
{
|
|
- if (!q || !setup) {
|
|
+ if (!q || !q->qinfo || !setup) {
|
|
WD_ERR("%s: input param err!\n", __func__);
|
|
return -WD_EINVAL;
|
|
}
|
|
@@ -377,6 +377,7 @@ static int param_check(struct wcrypto_digest_ctx *d_ctx,
|
|
{
|
|
enum wcrypto_digest_alg alg;
|
|
__u32 i;
|
|
+ int ret;
|
|
|
|
if (unlikely(!d_ctx || !d_opdata || !num || num > WCRYPTO_MAX_BURST_NUM)) {
|
|
WD_ERR("input param err!\n");
|
|
@@ -387,7 +388,7 @@ static int param_check(struct wcrypto_digest_ctx *d_ctx,
|
|
|
|
for (i = 0; i < num; i++) {
|
|
if (unlikely(!d_opdata[i])) {
|
|
- WD_ERR("digest opdata[%u] is NULL!\n", i);
|
|
+ WD_ERR("invalid: digest opdata[%u] is NULL!\n", i);
|
|
return -WD_EINVAL;
|
|
}
|
|
|
|
@@ -396,6 +397,12 @@ static int param_check(struct wcrypto_digest_ctx *d_ctx,
|
|
return -WD_EINVAL;
|
|
}
|
|
|
|
+ ret = wd_check_src_dst(d_opdata[i]->in, d_opdata[i]->in_bytes, d_opdata[i]->out, d_opdata[i]->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 (d_opdata[i]->has_next) {
|
|
if (unlikely(num != 1)) {
|
|
WD_ERR("num > 1, wcrypto_burst_digest does not support stream mode!\n");
|
|
@@ -414,8 +421,8 @@ static int param_check(struct wcrypto_digest_ctx *d_ctx,
|
|
WD_ERR("failed to check digest mac length!\n");
|
|
return -WD_EINVAL;
|
|
}
|
|
- if (d_ctx->setup.alg == WCRYPTO_AES_GMAC &&
|
|
- d_opdata[i]->iv_bytes != SEC_GMAC_IV_LEN) {
|
|
+ if (unlikely(d_ctx->setup.alg == WCRYPTO_AES_GMAC &&
|
|
+ (!d_opdata[i]->iv || d_opdata[i]->iv_bytes != SEC_GMAC_IV_LEN))) {
|
|
WD_ERR("failed to check digest aes_gmac iv length, iv_bytes = %u\n",
|
|
d_opdata[i]->iv_bytes);
|
|
return -WD_EINVAL;
|
|
@@ -423,13 +430,13 @@ static int param_check(struct wcrypto_digest_ctx *d_ctx,
|
|
}
|
|
|
|
if (unlikely(tag && !tag[i])) {
|
|
- WD_ERR("tag[%u] is NULL!\n", i);
|
|
+ WD_ERR("invalid: tag[%u] is NULL!\n", i);
|
|
return -WD_EINVAL;
|
|
}
|
|
}
|
|
|
|
if (unlikely(tag && !d_ctx->setup.cb)) {
|
|
- WD_ERR("digest ctx call back is NULL!\n");
|
|
+ WD_ERR("invalid: digest ctx call back is NULL!\n");
|
|
return -WD_EINVAL;
|
|
}
|
|
|
|
diff --git a/v1/wd_ecc.c b/v1/wd_ecc.c
|
|
index c4fab63..7650b2b 100644
|
|
--- a/v1/wd_ecc.c
|
|
+++ b/v1/wd_ecc.c
|
|
@@ -1006,7 +1006,7 @@ static bool is_key_width_support(__u32 key_bits)
|
|
|
|
static int param_check(struct wd_queue *q, struct wcrypto_ecc_ctx_setup *setup)
|
|
{
|
|
- if (unlikely(!q || !setup)) {
|
|
+ if (unlikely(!q || !q->qinfo || !setup)) {
|
|
WD_ERR("input parameter error!\n");
|
|
return -WD_EINVAL;
|
|
}
|
|
@@ -1663,7 +1663,7 @@ static int ecc_poll(struct wd_queue *q, unsigned int num)
|
|
int wcrypto_do_ecxdh(void *ctx, struct wcrypto_ecc_op_data *opdata, void *tag)
|
|
{
|
|
if (unlikely(!opdata)) {
|
|
- WD_ERR("do ecxdh: opdata null!\n");
|
|
+ WD_ERR("invalid: do ecxdh: opdata null!\n");
|
|
return -WD_EINVAL;
|
|
}
|
|
|
|
@@ -2176,7 +2176,7 @@ void wcrypto_get_ecdsa_sign_in_params(struct wcrypto_ecc_in *in,
|
|
int wcrypto_do_ecdsa(void *ctx, struct wcrypto_ecc_op_data *opdata, void *tag)
|
|
{
|
|
if (unlikely(!opdata)) {
|
|
- WD_ERR("do ecdsa: opdata null!\n");
|
|
+ WD_ERR("invalid: do ecdsa: opdata null!\n");
|
|
return -WD_EINVAL;
|
|
}
|
|
|
|
@@ -2463,7 +2463,7 @@ int wcrypto_do_sm2(void *ctx, struct wcrypto_ecc_op_data *opdata, void *tag)
|
|
struct wcrypto_ecc_in *in;
|
|
|
|
if (unlikely(!opdata)) {
|
|
- WD_ERR("do sm2: opdata null!\n");
|
|
+ WD_ERR("invalid: do sm2: opdata null!\n");
|
|
return -WD_EINVAL;
|
|
}
|
|
|
|
diff --git a/v1/wd_rng.c b/v1/wd_rng.c
|
|
index cc8a594..927665f 100644
|
|
--- a/v1/wd_rng.c
|
|
+++ b/v1/wd_rng.c
|
|
@@ -48,7 +48,7 @@ static int wcrypto_setup_qinfo(struct wcrypto_rng_ctx_setup *setup,
|
|
struct q_info *qinfo;
|
|
int ret = -WD_EINVAL;
|
|
|
|
- if (!q || !setup) {
|
|
+ if (!q || !q->qinfo || !setup) {
|
|
WD_ERR("input parameter err!\n");
|
|
return ret;
|
|
}
|
|
@@ -202,8 +202,13 @@ static int wcrypto_do_prepare(struct wcrypto_rng_cookie **cookie_addr,
|
|
struct wcrypto_rng_msg *req;
|
|
int ret;
|
|
|
|
- if (!ctxt || !opdata) {
|
|
- WD_ERR("input parameter err!\n");
|
|
+ if (unlikely(!ctxt || !opdata)) {
|
|
+ WD_ERR("invalid: rng input parameter err!\n");
|
|
+ return -WD_EINVAL;
|
|
+ }
|
|
+
|
|
+ if (unlikely((opdata->in_bytes && !opdata->out))) {
|
|
+ WD_ERR("invalid: dst addr is NULL when in_bytes is non-zero!!\n");
|
|
return -WD_EINVAL;
|
|
}
|
|
|
|
@@ -213,7 +218,7 @@ static int wcrypto_do_prepare(struct wcrypto_rng_cookie **cookie_addr,
|
|
|
|
if (tag) {
|
|
if (!ctxt->setup.cb) {
|
|
- WD_ERR("ctx call back is null!\n");
|
|
+ WD_ERR("invalid: ctx call back is null!\n");
|
|
wd_put_cookies(&ctxt->pool, (void **)&cookie, 1);
|
|
return -WD_EINVAL;
|
|
}
|
|
diff --git a/v1/wd_rsa.c b/v1/wd_rsa.c
|
|
index 4a2a5b5..9e467d0 100644
|
|
--- a/v1/wd_rsa.c
|
|
+++ b/v1/wd_rsa.c
|
|
@@ -549,7 +549,7 @@ static void del_ctx(struct wcrypto_rsa_ctx *c)
|
|
|
|
static int check_q_setup(struct wd_queue *q, struct wcrypto_rsa_ctx_setup *setup)
|
|
{
|
|
- if (!q || !setup) {
|
|
+ if (!q || !q->qinfo || !setup) {
|
|
WD_ERR("create rsa ctx input parameter err!\n");
|
|
return -WD_EINVAL;
|
|
}
|
|
@@ -957,12 +957,18 @@ static int do_rsa_prepare(struct wcrypto_rsa_ctx *ctxt,
|
|
int ret;
|
|
|
|
if (unlikely(!ctxt || !opdata)) {
|
|
- WD_ERR("input parameter err!\n");
|
|
+ WD_ERR("invalid: input parameter err!\n");
|
|
+ return -WD_EINVAL;
|
|
+ }
|
|
+
|
|
+ ret = wd_check_src_dst(opdata->in, opdata->in_bytes, opdata->out, opdata->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 (unlikely(tag && !ctxt->setup.cb)) {
|
|
- WD_ERR("ctx call back is null!\n");
|
|
+ WD_ERR("invalid: ctx call back is null!\n");
|
|
return -WD_EINVAL;
|
|
}
|
|
|
|
diff --git a/v1/wd_util.c b/v1/wd_util.c
|
|
index a1d08b4..f31d138 100644
|
|
--- a/v1/wd_util.c
|
|
+++ b/v1/wd_util.c
|
|
@@ -182,3 +182,10 @@ int wd_burst_recv(struct wd_queue *q, void **resp, __u32 num)
|
|
{
|
|
return drv_recv(q, resp, num);
|
|
}
|
|
+
|
|
+int wd_check_src_dst(void *src, __u32 in_bytes, void *dst, __u32 out_bytes)
|
|
+{
|
|
+ if (unlikely((in_bytes && !src) || (out_bytes && !dst)))
|
|
+ return -WD_EINVAL;
|
|
+ return 0;
|
|
+}
|
|
diff --git a/v1/wd_util.h b/v1/wd_util.h
|
|
index a8c6b15..bf17058 100644
|
|
--- a/v1/wd_util.h
|
|
+++ b/v1/wd_util.h
|
|
@@ -404,5 +404,6 @@ void drv_set_sgl_pri(struct wd_sgl *sgl, void *priv);
|
|
void *drv_get_sgl_pri(struct wd_sgl *sgl);
|
|
struct wd_mm_br *drv_get_br(void *pool);
|
|
void wd_sgl_memset(struct wd_sgl *sgl, int ch);
|
|
+int wd_check_src_dst(void *src, __u32 in_bytes, void *dst, __u32 out_bytes);
|
|
|
|
#endif
|
|
--
|
|
2.31.1.windows.1
|
|
|