Borislav Petkov 9ab9ee
From: Jens Wiklander <jens.wiklander@linaro.org>
Borislav Petkov 9ab9ee
Date: Thu, 7 Nov 2019 11:42:56 +0100
Borislav Petkov 9ab9ee
Subject: tee: don't assign shm id for private shms
Borislav Petkov 9ab9ee
Git-commit: f1bbacedb0af640a93e47799203e556be2825da3
Borislav Petkov 9ab9ee
Patch-mainline: v5.7-rc1
Borislav Petkov 9ab9ee
References: bsc#1193767 CVE-2021-44733
Borislav Petkov 9ab9ee
Borislav Petkov 9ab9ee
Private shared memory object must not be referenced from user space. To
Borislav Petkov 9ab9ee
guarantee that, don't assign an id to shared memory objects which are
Borislav Petkov 9ab9ee
driver private.
Borislav Petkov 9ab9ee
Borislav Petkov 9ab9ee
Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org>
Borislav Petkov 9ab9ee
Acked-by: Borislav Petkov <bp@suse.de>
Borislav Petkov 9ab9ee
---
Borislav Petkov 9ab9ee
 drivers/tee/tee_private.h |  3 ++-
Borislav Petkov 9ab9ee
 drivers/tee/tee_shm.c     | 31 ++++++++++++++++++-------------
Borislav Petkov 9ab9ee
 2 files changed, 20 insertions(+), 14 deletions(-)
Borislav Petkov 9ab9ee
Borislav Petkov 9ab9ee
diff --git a/drivers/tee/tee_private.h b/drivers/tee/tee_private.h
Borislav Petkov 9ab9ee
index f797171f0434..e55204df31ce 100644
Borislav Petkov 9ab9ee
--- a/drivers/tee/tee_private.h
Borislav Petkov 9ab9ee
+++ b/drivers/tee/tee_private.h
Borislav Petkov 9ab9ee
@@ -37,7 +37,8 @@ struct tee_shm_pool {
Borislav Petkov 9ab9ee
  * @num_users:	number of active users of this device
Borislav Petkov 9ab9ee
  * @c_no_user:	completion used when unregistering the device
Borislav Petkov 9ab9ee
  * @mutex:	mutex protecting @num_users and @idr
Borislav Petkov 9ab9ee
- * @idr:	register of shared memory object allocated on this device
Borislav Petkov 9ab9ee
+ * @idr:	register of user space shared memory objects allocated or
Borislav Petkov 9ab9ee
+ *		registered on this device
Borislav Petkov 9ab9ee
  * @pool:	shared memory pool
Borislav Petkov 9ab9ee
  */
Borislav Petkov 9ab9ee
 struct tee_device {
Borislav Petkov 9ab9ee
diff --git a/drivers/tee/tee_shm.c b/drivers/tee/tee_shm.c
Borislav Petkov 9ab9ee
index b666854c2491..02210f179ae3 100644
Borislav Petkov 9ab9ee
--- a/drivers/tee/tee_shm.c
Borislav Petkov 9ab9ee
+++ b/drivers/tee/tee_shm.c
Borislav Petkov 9ab9ee
@@ -15,9 +15,11 @@ static void tee_shm_release(struct tee_shm *shm)
Borislav Petkov 9ab9ee
 {
Borislav Petkov 9ab9ee
 	struct tee_device *teedev = shm->teedev;
Borislav Petkov 9ab9ee
 
Borislav Petkov 9ab9ee
-	mutex_lock(&teedev->mutex);
Borislav Petkov 9ab9ee
-	idr_remove(&teedev->idr, shm->id);
Borislav Petkov 9ab9ee
-	mutex_unlock(&teedev->mutex);
Borislav Petkov 9ab9ee
+	if (shm->flags & TEE_SHM_DMA_BUF) {
Borislav Petkov 9ab9ee
+		mutex_lock(&teedev->mutex);
Borislav Petkov 9ab9ee
+		idr_remove(&teedev->idr, shm->id);
Borislav Petkov 9ab9ee
+		mutex_unlock(&teedev->mutex);
Borislav Petkov 9ab9ee
+	}
Borislav Petkov 9ab9ee
 
Borislav Petkov 9ab9ee
 	if (shm->flags & TEE_SHM_POOL) {
Borislav Petkov 9ab9ee
 		struct tee_shm_pool_mgr *poolm;
Borislav Petkov 9ab9ee
@@ -137,17 +139,18 @@ struct tee_shm *tee_shm_alloc(struct tee_context *ctx, size_t size, u32 flags)
Borislav Petkov 9ab9ee
 		goto err_kfree;
Borislav Petkov 9ab9ee
 	}
Borislav Petkov 9ab9ee
 
Borislav Petkov 9ab9ee
-	mutex_lock(&teedev->mutex);
Borislav Petkov 9ab9ee
-	shm->id = idr_alloc(&teedev->idr, shm, 1, 0, GFP_KERNEL);
Borislav Petkov 9ab9ee
-	mutex_unlock(&teedev->mutex);
Borislav Petkov 9ab9ee
-	if (shm->id < 0) {
Borislav Petkov 9ab9ee
-		ret = ERR_PTR(shm->id);
Borislav Petkov 9ab9ee
-		goto err_pool_free;
Borislav Petkov 9ab9ee
-	}
Borislav Petkov 9ab9ee
 
Borislav Petkov 9ab9ee
 	if (flags & TEE_SHM_DMA_BUF) {
Borislav Petkov 9ab9ee
 		DEFINE_DMA_BUF_EXPORT_INFO(exp_info);
Borislav Petkov 9ab9ee
 
Borislav Petkov 9ab9ee
+		mutex_lock(&teedev->mutex);
Borislav Petkov 9ab9ee
+		shm->id = idr_alloc(&teedev->idr, shm, 1, 0, GFP_KERNEL);
Borislav Petkov 9ab9ee
+		mutex_unlock(&teedev->mutex);
Borislav Petkov 9ab9ee
+		if (shm->id < 0) {
Borislav Petkov 9ab9ee
+			ret = ERR_PTR(shm->id);
Borislav Petkov 9ab9ee
+			goto err_pool_free;
Borislav Petkov 9ab9ee
+		}
Borislav Petkov 9ab9ee
+
Borislav Petkov 9ab9ee
 		exp_info.ops = &tee_shm_dma_buf_ops;
Borislav Petkov 9ab9ee
 		exp_info.size = shm->size;
Borislav Petkov 9ab9ee
 		exp_info.flags = O_RDWR;
Borislav Petkov 9ab9ee
@@ -165,9 +168,11 @@ struct tee_shm *tee_shm_alloc(struct tee_context *ctx, size_t size, u32 flags)
Borislav Petkov 9ab9ee
 
Borislav Petkov 9ab9ee
 	return shm;
Borislav Petkov 9ab9ee
 err_rem:
Borislav Petkov 9ab9ee
-	mutex_lock(&teedev->mutex);
Borislav Petkov 9ab9ee
-	idr_remove(&teedev->idr, shm->id);
Borislav Petkov 9ab9ee
-	mutex_unlock(&teedev->mutex);
Borislav Petkov 9ab9ee
+	if (flags & TEE_SHM_DMA_BUF) {
Borislav Petkov 9ab9ee
+		mutex_lock(&teedev->mutex);
Borislav Petkov 9ab9ee
+		idr_remove(&teedev->idr, shm->id);
Borislav Petkov 9ab9ee
+		mutex_unlock(&teedev->mutex);
Borislav Petkov 9ab9ee
+	}
Borislav Petkov 9ab9ee
 err_pool_free:
Borislav Petkov 9ab9ee
 	poolm->ops->free(poolm, shm);
Borislav Petkov 9ab9ee
 err_kfree:
Borislav Petkov 9ab9ee