From df86cdc52c36aa162b47cc6c6815d1e209cc48b5 Mon Sep 17 00:00:00 2001 From: JiangShui Yang Date: Mon, 9 Oct 2023 15:48:38 +0800 Subject: [PATCH 1/2] Revert "uacce: use filep->f_mapping to replace inode->i_mapping" driver inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I87RJC CVE: NA ---------------------------------------------------------------------- This reverts commit f29efbf31be2eefdbc2c22c38c139da788d7ea3f. Use q->mapping instead of q->private_date to transfer parameters Signed-off-by: JiangShui Yang --- drivers/misc/uacce/uacce.c | 16 +++++++--------- include/linux/uacce.h | 4 ++-- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/drivers/misc/uacce/uacce.c b/drivers/misc/uacce/uacce.c index 20340825cc4d..d7c3eec6edc1 100644 --- a/drivers/misc/uacce/uacce.c +++ b/drivers/misc/uacce/uacce.c @@ -349,8 +349,8 @@ static int uacce_fops_open(struct inode *inode, struct file *filep) init_waitqueue_head(&q->wait); filep->private_data = q; + uacce->inode = inode; q->state = UACCE_Q_INIT; - q->private_data = filep; mutex_init(&q->mutex); list_add(&q->list, &uacce->queues); mutex_unlock(&uacce->mutex); @@ -1038,6 +1038,12 @@ void uacce_remove(struct uacce_device *uacce) if (!uacce) return; + /* + * unmap remaining mapping from user space, preventing user still + * access the mmaped area while parent device is already removed + */ + if (uacce->inode) + unmap_mapping_range(uacce->inode->i_mapping, 0, 0, 1); /* * uacce_fops_open() may be running concurrently, even after we remove @@ -1047,8 +1053,6 @@ void uacce_remove(struct uacce_device *uacce) mutex_lock(&uacce->mutex); /* ensure no open queue remains */ list_for_each_entry_safe(q, next_q, &uacce->queues, list) { - struct file *filep = q->private_data; - /* * Taking q->mutex ensures that fops do not use the defunct * uacce->ops after the queue is disabled. @@ -1057,12 +1061,6 @@ void uacce_remove(struct uacce_device *uacce) uacce_put_queue(q); mutex_unlock(&q->mutex); uacce_unbind_queue(q); - - /* - * unmap remaining mapping from user space, preventing user still - * access the mmaped area while parent device is already removed - */ - unmap_mapping_range(filep->f_mapping, 0, 0, 1); } /* disable sva now since no opened queues */ diff --git a/include/linux/uacce.h b/include/linux/uacce.h index 9b0c04a9cff7..553b0692df76 100644 --- a/include/linux/uacce.h +++ b/include/linux/uacce.h @@ -115,7 +115,6 @@ enum uacce_q_state { * @state: queue state machine * @pasid: pasid associated to the mm * @handle: iommu_sva handle returned by iommu_sva_bind_device() - * @private_data: private data for saving filep */ struct uacce_queue { struct uacce_device *uacce; @@ -130,7 +129,6 @@ struct uacce_queue { enum uacce_q_state state; u32 pasid; struct iommu_sva *handle; - void *private_data; }; /** @@ -148,6 +146,7 @@ struct uacce_queue { * @mutex: protects uacce operation * @priv: private pointer of the uacce * @queues: list of queues + * @inode: core vfs */ struct uacce_device { const char *algs; @@ -165,6 +164,7 @@ struct uacce_device { void *priv; struct uacce_err_isolate *isolate; struct list_head queues; + struct inode *inode; }; #if IS_ENABLED(CONFIG_UACCE) -- Gitee From aa609da59fe090fdd4698d8a7c4dcc2903cde109 Mon Sep 17 00:00:00 2001 From: Zhangfei Gao Date: Thu, 11 May 2023 17:59:20 +0800 Subject: [PATCH 2/2] uacce: use q->mapping to replace inode->i_mapping mainline inclusion from mainline-v6.5-rc1 commit df1b056d489d98c7c45fa89627102dd34b44496f category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I87RJC CVE: NA Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=df1b056d489d98c7c45fa89627102dd34b44496f ---------------------------------------------------------------------- The inode can be different in a container, for example, a docker and host both open the same uacce parent device, which uses the same uacce struct but different inode, so uacce->inode is not enough. What's worse, when docker stops, the inode will be destroyed as well, causing use-after-free in uacce_remove. So use q->mapping to replace uacce->inode->i_mapping. Signed-off-by: Weili Qian Signed-off-by: Zhangfei Gao Link: https://lore.kernel.org/r/20230511095921.9331-2-zhangfei.gao@linaro.org Signed-off-by: Greg Kroah-Hartman Signed-off-by: JiangShui Yang --- drivers/misc/uacce/uacce.c | 14 +++++++------- include/linux/uacce.h | 4 ++-- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/misc/uacce/uacce.c b/drivers/misc/uacce/uacce.c index d7c3eec6edc1..bb4af54c0386 100644 --- a/drivers/misc/uacce/uacce.c +++ b/drivers/misc/uacce/uacce.c @@ -349,8 +349,8 @@ static int uacce_fops_open(struct inode *inode, struct file *filep) init_waitqueue_head(&q->wait); filep->private_data = q; - uacce->inode = inode; q->state = UACCE_Q_INIT; + q->mapping = filep->f_mapping; mutex_init(&q->mutex); list_add(&q->list, &uacce->queues); mutex_unlock(&uacce->mutex); @@ -1038,12 +1038,6 @@ void uacce_remove(struct uacce_device *uacce) if (!uacce) return; - /* - * unmap remaining mapping from user space, preventing user still - * access the mmaped area while parent device is already removed - */ - if (uacce->inode) - unmap_mapping_range(uacce->inode->i_mapping, 0, 0, 1); /* * uacce_fops_open() may be running concurrently, even after we remove @@ -1061,6 +1055,12 @@ void uacce_remove(struct uacce_device *uacce) uacce_put_queue(q); mutex_unlock(&q->mutex); uacce_unbind_queue(q); + + /* + * unmap remaining mapping from user space, preventing user still + * access the mmaped area while parent device is already removed + */ + unmap_mapping_range(q->mapping, 0, 0, 1); } /* disable sva now since no opened queues */ diff --git a/include/linux/uacce.h b/include/linux/uacce.h index 553b0692df76..8a4bb77b1bc8 100644 --- a/include/linux/uacce.h +++ b/include/linux/uacce.h @@ -115,6 +115,7 @@ enum uacce_q_state { * @state: queue state machine * @pasid: pasid associated to the mm * @handle: iommu_sva handle returned by iommu_sva_bind_device() + * @mapping: user space mapping of the queue */ struct uacce_queue { struct uacce_device *uacce; @@ -129,6 +130,7 @@ struct uacce_queue { enum uacce_q_state state; u32 pasid; struct iommu_sva *handle; + struct address_space *mapping; }; /** @@ -146,7 +148,6 @@ struct uacce_queue { * @mutex: protects uacce operation * @priv: private pointer of the uacce * @queues: list of queues - * @inode: core vfs */ struct uacce_device { const char *algs; @@ -164,7 +165,6 @@ struct uacce_device { void *priv; struct uacce_err_isolate *isolate; struct list_head queues; - struct inode *inode; }; #if IS_ENABLED(CONFIG_UACCE) -- Gitee