From: Jens Wiklander jens.wiklander@linaro.org
mainline inclusion from mainline-v5.7-rc1 commit f1bbacedb0af640a93e47799203e556be2825da3 category: cleanup bugzilla: NA CVE: NA
Prepare for fixing CVE-2021-44733. --------------------------------
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 Signed-off-by: Yang Yingliang yangyingliang@huawei.com --- drivers/tee/tee_private.h | 3 ++- drivers/tee/tee_shm.c | 31 ++++++++++++++++++------------- 2 files changed, 20 insertions(+), 14 deletions(-)
diff --git a/drivers/tee/tee_private.h b/drivers/tee/tee_private.h index 85d99d621603d..e3d62a21cd53b 100644 --- a/drivers/tee/tee_private.h +++ b/drivers/tee/tee_private.h @@ -46,7 +46,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 { diff --git a/drivers/tee/tee_shm.c b/drivers/tee/tee_shm.c index 8984158483463..4010817765ef1 100644 --- a/drivers/tee/tee_shm.c +++ b/drivers/tee/tee_shm.c @@ -24,9 +24,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; @@ -158,17 +160,18 @@ static struct tee_shm *__tee_shm_alloc(struct tee_context *ctx, 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; @@ -186,9 +189,11 @@ static struct tee_shm *__tee_shm_alloc(struct tee_context *ctx,
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: