mirror of
git://nv-tegra.nvidia.com/linux-nv-oot.git
synced 2025-12-23 09:42:19 +03:00
nvvse: handle failure case gracefully
Observing the crash in failure path when already freed memory is being used. handling the failure scenario gracefully with this patch. Bug 4355159 Change-Id: Ie39dab2572067eab0c139323ed86bae9490a8878 Signed-off-by: Manish Bhardwaj <mbhardwaj@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/3008896 GVS: Gerrit_Virtual_Submit <buildbot_gerritrpt@nvidia.com> Reviewed-by: Advaya Andhare <aandhare@nvidia.com> Reviewed-by: Sandeep Trasi <strasi@nvidia.com>
This commit is contained in:
committed by
mobile promotions
parent
84443ed555
commit
558dc30461
@@ -85,6 +85,12 @@ struct tnvvse_crypto_completion {
|
|||||||
int req_err;
|
int req_err;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
SHA_OP_INIT = 1,
|
||||||
|
SHA_OP_SUCCESS = 2,
|
||||||
|
SHA_OP_FAIL = 3,
|
||||||
|
} sha_op_state;
|
||||||
|
|
||||||
struct crypto_sha_state {
|
struct crypto_sha_state {
|
||||||
uint32_t sha_type;
|
uint32_t sha_type;
|
||||||
uint32_t digest_size;
|
uint32_t digest_size;
|
||||||
@@ -95,7 +101,7 @@ struct crypto_sha_state {
|
|||||||
struct ahash_request *req;
|
struct ahash_request *req;
|
||||||
struct crypto_ahash *tfm;
|
struct crypto_ahash *tfm;
|
||||||
char *result_buff;
|
char *result_buff;
|
||||||
bool sha_done_success;
|
sha_op_state sha_done_success;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Tegra NVVSE crypt context */
|
/* Tegra NVVSE crypt context */
|
||||||
@@ -286,7 +292,7 @@ static int tnvvse_crypto_sha_init(struct tnvvse_crypto_ctx *ctx,
|
|||||||
sha_state->total_bytes = init_ctl->total_msg_size;
|
sha_state->total_bytes = init_ctl->total_msg_size;
|
||||||
sha_state->digest_size = init_ctl->digest_size;
|
sha_state->digest_size = init_ctl->digest_size;
|
||||||
sha_state->remaining_bytes = init_ctl->total_msg_size;
|
sha_state->remaining_bytes = init_ctl->total_msg_size;
|
||||||
sha_state->sha_done_success = false;
|
sha_state->sha_done_success = SHA_OP_INIT;
|
||||||
nvvse_devnode[ctx->node_id].sha_init_done = true;
|
nvvse_devnode[ctx->node_id].sha_init_done = true;
|
||||||
|
|
||||||
memset(sha_state->result_buff , 0, 64);
|
memset(sha_state->result_buff , 0, 64);
|
||||||
@@ -312,12 +318,13 @@ static int tnvvse_crypto_sha_update(struct tnvvse_crypto_ctx *ctx,
|
|||||||
struct ahash_request *req;
|
struct ahash_request *req;
|
||||||
char *input_buffer = update_ctl->in_buff;
|
char *input_buffer = update_ctl->in_buff;
|
||||||
struct scatterlist sg;
|
struct scatterlist sg;
|
||||||
int ret;
|
int ret = 0;
|
||||||
|
|
||||||
if (update_ctl->input_buffer_size > ivc_database.max_buffer_size[ctx->node_id]) {
|
if (update_ctl->input_buffer_size > ivc_database.max_buffer_size[ctx->node_id]) {
|
||||||
pr_err("%s: Msg size is greater than supported size of %d Bytes\n", __func__,
|
pr_err("%s: Msg size is greater than supported size of %d Bytes\n", __func__,
|
||||||
ivc_database.max_buffer_size[ctx->node_id]);
|
ivc_database.max_buffer_size[ctx->node_id]);
|
||||||
return -EINVAL;
|
ret = -EINVAL;
|
||||||
|
goto stop_sha;
|
||||||
}
|
}
|
||||||
|
|
||||||
result_buff = sha_state->result_buff;
|
result_buff = sha_state->result_buff;
|
||||||
@@ -332,6 +339,7 @@ static int tnvvse_crypto_sha_update(struct tnvvse_crypto_ctx *ctx,
|
|||||||
/* copy input buffer */
|
/* copy input buffer */
|
||||||
if (copy_from_user((void *)sha_state->in_buf, input_buffer, update_ctl->input_buffer_size)) {
|
if (copy_from_user((void *)sha_state->in_buf, input_buffer, update_ctl->input_buffer_size)) {
|
||||||
pr_err("%s(): Failed to copy_from_user input data\n", __func__);
|
pr_err("%s(): Failed to copy_from_user input data\n", __func__);
|
||||||
|
ret = -EFAULT;
|
||||||
goto stop_sha;
|
goto stop_sha;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -351,28 +359,13 @@ static int tnvvse_crypto_sha_update(struct tnvvse_crypto_ctx *ctx,
|
|||||||
__func__, sha_alg_names[sha_state->sha_type], ret);
|
__func__, sha_alg_names[sha_state->sha_type], ret);
|
||||||
goto stop_sha;
|
goto stop_sha;
|
||||||
}
|
}
|
||||||
sha_state->sha_done_success = true;
|
sha_state->sha_done_success = SHA_OP_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
stop_sha:
|
stop_sha:
|
||||||
if (sha_state->in_buf) {
|
sha_state->sha_done_success = SHA_OP_FAIL;
|
||||||
kfree(sha_state->in_buf);
|
|
||||||
sha_state->in_buf = NULL;
|
|
||||||
}
|
|
||||||
ahash_request_free(sha_state->req);
|
|
||||||
crypto_free_ahash(sha_state->tfm);
|
|
||||||
sha_state->req = NULL;
|
|
||||||
sha_state->tfm = NULL;
|
|
||||||
if (sha_state->result_buff != ctx->sha_result) {
|
|
||||||
kfree(sha_state->result_buff);
|
|
||||||
sha_state->result_buff = NULL;
|
|
||||||
}
|
|
||||||
sha_state->result_buff = NULL;
|
|
||||||
sha_state->total_bytes = 0;
|
|
||||||
sha_state->digest_size = 0;
|
|
||||||
sha_state->remaining_bytes = 0;
|
|
||||||
|
|
||||||
done:
|
done:
|
||||||
return ret;
|
return ret;
|
||||||
@@ -389,7 +382,7 @@ static int tnvvse_crypto_sha_final(struct tnvvse_crypto_ctx *ctx,
|
|||||||
char *result_buff;
|
char *result_buff;
|
||||||
int ret = -ENOMEM;
|
int ret = -ENOMEM;
|
||||||
|
|
||||||
if (!sha_state->sha_done_success) {
|
if (sha_state->sha_done_success == SHA_OP_INIT) {
|
||||||
result_buff = sha_state->result_buff;
|
result_buff = sha_state->result_buff;
|
||||||
req = sha_state->req;
|
req = sha_state->req;
|
||||||
|
|
||||||
@@ -407,7 +400,7 @@ static int tnvvse_crypto_sha_final(struct tnvvse_crypto_ctx *ctx,
|
|||||||
goto stop_sha;
|
goto stop_sha;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sha_state->result_buff == NULL) {
|
if (sha_state->sha_done_success == SHA_OP_FAIL) {
|
||||||
pr_err("%s(): SHA is either aborted or not initialized\n", __func__);
|
pr_err("%s(): SHA is either aborted or not initialized\n", __func__);
|
||||||
ret = -EFAULT;
|
ret = -EFAULT;
|
||||||
goto stop_sha;
|
goto stop_sha;
|
||||||
|
|||||||
Reference in New Issue
Block a user