tee: don't assign shm id for private shms
authorJens Wiklander <jens.wiklander@linaro.org>
Thu, 7 Nov 2019 10:42:56 +0000 (11:42 +0100)
committerJens Wiklander <jens.wiklander@linaro.org>
Fri, 28 Feb 2020 12:37:42 +0000 (13:37 +0100)
Private shared memory object must not be referenced from user space. To
guarantee that, don't assign an id to shared memory objects which are
driver private.

Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org>
drivers/tee/tee_private.h
drivers/tee/tee_shm.c

index f797171f0434f48787bcb50828c3160aafc0cd19..e55204df31ce8eab9d454b85b5806719ac9378da 100644 (file)
@@ -37,7 +37,8 @@ struct tee_shm_pool {
  * @num_users: number of active users of this device
  * @c_no_user: completion used when unregistering the device
  * @mutex:     mutex protecting @num_users and @idr
- * @idr:       register of shared memory object allocated on this device
+ * @idr:       register of user space shared memory objects allocated or
+ *             registered on this device
  * @pool:      shared memory pool
  */
 struct tee_device {
index b666854c249193c7c32127d0f08cd6de11b4d1b2..02210f179ae36898aa4d537ab8c55e30fca24737 100644 (file)
@@ -15,9 +15,11 @@ static void tee_shm_release(struct tee_shm *shm)
 {
        struct tee_device *teedev = shm->teedev;
 
-       mutex_lock(&teedev->mutex);
-       idr_remove(&teedev->idr, shm->id);
-       mutex_unlock(&teedev->mutex);
+       if (shm->flags & TEE_SHM_DMA_BUF) {
+               mutex_lock(&teedev->mutex);
+               idr_remove(&teedev->idr, shm->id);
+               mutex_unlock(&teedev->mutex);
+       }
 
        if (shm->flags & TEE_SHM_POOL) {
                struct tee_shm_pool_mgr *poolm;
@@ -137,17 +139,18 @@ struct tee_shm *tee_shm_alloc(struct tee_context *ctx, size_t size, u32 flags)
                goto err_kfree;
        }
 
-       mutex_lock(&teedev->mutex);
-       shm->id = idr_alloc(&teedev->idr, shm, 1, 0, GFP_KERNEL);
-       mutex_unlock(&teedev->mutex);
-       if (shm->id < 0) {
-               ret = ERR_PTR(shm->id);
-               goto err_pool_free;
-       }
 
        if (flags & TEE_SHM_DMA_BUF) {
                DEFINE_DMA_BUF_EXPORT_INFO(exp_info);
 
+               mutex_lock(&teedev->mutex);
+               shm->id = idr_alloc(&teedev->idr, shm, 1, 0, GFP_KERNEL);
+               mutex_unlock(&teedev->mutex);
+               if (shm->id < 0) {
+                       ret = ERR_PTR(shm->id);
+                       goto err_pool_free;
+               }
+
                exp_info.ops = &tee_shm_dma_buf_ops;
                exp_info.size = shm->size;
                exp_info.flags = O_RDWR;
@@ -165,9 +168,11 @@ struct tee_shm *tee_shm_alloc(struct tee_context *ctx, size_t size, u32 flags)
 
        return shm;
 err_rem:
-       mutex_lock(&teedev->mutex);
-       idr_remove(&teedev->idr, shm->id);
-       mutex_unlock(&teedev->mutex);
+       if (flags & TEE_SHM_DMA_BUF) {
+               mutex_lock(&teedev->mutex);
+               idr_remove(&teedev->idr, shm->id);
+               mutex_unlock(&teedev->mutex);
+       }
 err_pool_free:
        poolm->ops->free(poolm, shm);
 err_kfree: