Commit b83685bc authored by Dan Carpenter's avatar Dan Carpenter Committed by Jens Wiklander

tee: amdtee: fix memory leak in amdtee_open_session()

On these error paths the "sess" variable isn't freed.  It's a refcounted
pointer so we need to call kref_put().  I re-arranged the code a bit so
the error case is always handled before the success case and the error
paths are indented two tabs.

Fixes: 757cc3e9 ("tee: add AMD-TEE driver")
Reviewed-by: default avatarRijo Thomas <Rijo-john.Thomas@amd.com>
Signed-off-by: default avatarDan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: default avatarJens Wiklander <jens.wiklander@linaro.org>
parent 11a48a5a
...@@ -212,6 +212,19 @@ static int copy_ta_binary(struct tee_context *ctx, void *ptr, void **ta, ...@@ -212,6 +212,19 @@ static int copy_ta_binary(struct tee_context *ctx, void *ptr, void **ta,
return rc; return rc;
} }
static void destroy_session(struct kref *ref)
{
struct amdtee_session *sess = container_of(ref, struct amdtee_session,
refcount);
/* Unload the TA from TEE */
handle_unload_ta(sess->ta_handle);
mutex_lock(&session_list_mutex);
list_del(&sess->list_node);
mutex_unlock(&session_list_mutex);
kfree(sess);
}
int amdtee_open_session(struct tee_context *ctx, int amdtee_open_session(struct tee_context *ctx,
struct tee_ioctl_open_session_arg *arg, struct tee_ioctl_open_session_arg *arg,
struct tee_param *param) struct tee_param *param)
...@@ -236,14 +249,12 @@ int amdtee_open_session(struct tee_context *ctx, ...@@ -236,14 +249,12 @@ int amdtee_open_session(struct tee_context *ctx,
/* Load the TA binary into TEE environment */ /* Load the TA binary into TEE environment */
handle_load_ta(ta, ta_size, arg); handle_load_ta(ta, ta_size, arg);
if (arg->ret == TEEC_SUCCESS) { if (arg->ret != TEEC_SUCCESS)
goto out;
mutex_lock(&session_list_mutex); mutex_lock(&session_list_mutex);
sess = alloc_session(ctxdata, arg->session); sess = alloc_session(ctxdata, arg->session);
mutex_unlock(&session_list_mutex); mutex_unlock(&session_list_mutex);
}
if (arg->ret != TEEC_SUCCESS)
goto out;
if (!sess) { if (!sess) {
rc = -ENOMEM; rc = -ENOMEM;
...@@ -259,40 +270,29 @@ int amdtee_open_session(struct tee_context *ctx, ...@@ -259,40 +270,29 @@ int amdtee_open_session(struct tee_context *ctx,
if (i >= TEE_NUM_SESSIONS) { if (i >= TEE_NUM_SESSIONS) {
pr_err("reached maximum session count %d\n", TEE_NUM_SESSIONS); pr_err("reached maximum session count %d\n", TEE_NUM_SESSIONS);
kref_put(&sess->refcount, destroy_session);
rc = -ENOMEM; rc = -ENOMEM;
goto out; goto out;
} }
/* Open session with loaded TA */ /* Open session with loaded TA */
handle_open_session(arg, &session_info, param); handle_open_session(arg, &session_info, param);
if (arg->ret != TEEC_SUCCESS) {
if (arg->ret == TEEC_SUCCESS) {
sess->session_info[i] = session_info;
set_session_id(sess->ta_handle, i, &arg->session);
} else {
pr_err("open_session failed %d\n", arg->ret); pr_err("open_session failed %d\n", arg->ret);
spin_lock(&sess->lock); spin_lock(&sess->lock);
clear_bit(i, sess->sess_mask); clear_bit(i, sess->sess_mask);
spin_unlock(&sess->lock); spin_unlock(&sess->lock);
kref_put(&sess->refcount, destroy_session);
goto out;
} }
sess->session_info[i] = session_info;
set_session_id(sess->ta_handle, i, &arg->session);
out: out:
free_pages((u64)ta, get_order(ta_size)); free_pages((u64)ta, get_order(ta_size));
return rc; return rc;
} }
static void destroy_session(struct kref *ref)
{
struct amdtee_session *sess = container_of(ref, struct amdtee_session,
refcount);
/* Unload the TA from TEE */
handle_unload_ta(sess->ta_handle);
mutex_lock(&session_list_mutex);
list_del(&sess->list_node);
mutex_unlock(&session_list_mutex);
kfree(sess);
}
int amdtee_close_session(struct tee_context *ctx, u32 session) int amdtee_close_session(struct tee_context *ctx, u32 session)
{ {
struct amdtee_context_data *ctxdata = ctx->data; struct amdtee_context_data *ctxdata = ctx->data;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment