]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
tee: amdtee: fix memory leak in amdtee_open_session()
authorDan Carpenter <dan.carpenter@oracle.com>
Mon, 24 Feb 2020 10:51:39 +0000 (13:51 +0300)
committerJens Wiklander <jens.wiklander@linaro.org>
Thu, 27 Feb 2020 15:22:05 +0000 (16:22 +0100)
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: 757cc3e9ff1d ("tee: add AMD-TEE driver")
Reviewed-by: Rijo Thomas <Rijo-john.Thomas@amd.com>
Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org>
drivers/tee/amdtee/core.c

index 6370bb55f51230fda81a60661d2f6a2530df0f18..0026eb6f13cee46a2898f3a44b08c8b5a4c3ee0b 100644 (file)
@@ -212,6 +212,19 @@ static int copy_ta_binary(struct tee_context *ctx, void *ptr, void **ta,
        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,
                        struct tee_ioctl_open_session_arg *arg,
                        struct tee_param *param)
@@ -236,15 +249,13 @@ int amdtee_open_session(struct tee_context *ctx,
 
        /* Load the TA binary into TEE environment */
        handle_load_ta(ta, ta_size, arg);
-       if (arg->ret == TEEC_SUCCESS) {
-               mutex_lock(&session_list_mutex);
-               sess = alloc_session(ctxdata, arg->session);
-               mutex_unlock(&session_list_mutex);
-       }
-
        if (arg->ret != TEEC_SUCCESS)
                goto out;
 
+       mutex_lock(&session_list_mutex);
+       sess = alloc_session(ctxdata, arg->session);
+       mutex_unlock(&session_list_mutex);
+
        if (!sess) {
                rc = -ENOMEM;
                goto out;
@@ -259,40 +270,29 @@ int amdtee_open_session(struct tee_context *ctx,
 
        if (i >= TEE_NUM_SESSIONS) {
                pr_err("reached maximum session count %d\n", TEE_NUM_SESSIONS);
+               kref_put(&sess->refcount, destroy_session);
                rc = -ENOMEM;
                goto out;
        }
 
        /* Open session with loaded TA */
        handle_open_session(arg, &session_info, param);
-
-       if (arg->ret == TEEC_SUCCESS) {
-               sess->session_info[i] = session_info;
-               set_session_id(sess->ta_handle, i, &arg->session);
-       } else {
+       if (arg->ret != TEEC_SUCCESS) {
                pr_err("open_session failed %d\n", arg->ret);
                spin_lock(&sess->lock);
                clear_bit(i, sess->sess_mask);
                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:
        free_pages((u64)ta, get_order(ta_size));
        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)
 {
        struct amdtee_context_data *ctxdata = ctx->data;