All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/2] Fix purging buffers in the shmem helpers
@ 2021-02-23 15:51 Neil Roberts
  2021-02-23 15:51   ` Neil Roberts
                   ` (2 more replies)
  0 siblings, 3 replies; 10+ messages in thread
From: Neil Roberts @ 2021-02-23 15:51 UTC (permalink / raw)
  To: Rob Herring, Tomeu Vizoso, Alyssa Rosenzweig, Steven Price, Robin Murphy
  Cc: dri-devel

These two patches fix a problem with the madvise purging code for the
shmem helpers where the mmaping for a purged buffer wouldn't get
invalidated correctly. This presumably ends up as a security hole
where the mapping can be accessed from user-space to read and write
random pages from other buffers. This is currently affecting Panfrost.
The second patch is a v2 from a patch that was sent standalone.

There is a WIP IGT test for Panfrost which demonstrates the bug here:

https://gitlab.freedesktop.org/nroberts/igt-gpu-tools/-/commits/panfrost-purgemap/

Neil Roberts (2):
  drm/shmem-helper: Check for purged buffers in fault handler
  drm/shmem-helper: Don't remove the offset in vm_area_struct pgoff

 drivers/gpu/drm/drm_gem_shmem_helper.c | 25 ++++++++++++++++++-------
 1 file changed, 18 insertions(+), 7 deletions(-)

-- 
2.29.2

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH 1/2] drm/shmem-helper: Check for purged buffers in fault handler
  2021-02-23 15:51 [PATCH 0/2] Fix purging buffers in the shmem helpers Neil Roberts
@ 2021-02-23 15:51   ` Neil Roberts
  2021-02-23 15:51   ` Neil Roberts
  2021-03-05 10:22 ` [PATCH 0/2] Fix purging buffers in the shmem helpers Steven Price
  2 siblings, 0 replies; 10+ messages in thread
From: Neil Roberts @ 2021-02-23 15:51 UTC (permalink / raw)
  To: Rob Herring, Tomeu Vizoso, Alyssa Rosenzweig, Steven Price, Robin Murphy
  Cc: dri-devel, stable

When a buffer is madvised as not needed and then purged, any attempts to
access the buffer from user-space should cause a bus fault. This patch
adds a check for that.

Cc: stable@vger.kernel.org
Fixes: 17acb9f35ed7 ("drm/shmem: Add madvise state and purge helpers")
Signed-off-by: Neil Roberts <nroberts@igalia.com>
---
 drivers/gpu/drm/drm_gem_shmem_helper.c | 18 ++++++++++++++----
 1 file changed, 14 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c b/drivers/gpu/drm/drm_gem_shmem_helper.c
index 9825c378dfa6..b26139b1dc35 100644
--- a/drivers/gpu/drm/drm_gem_shmem_helper.c
+++ b/drivers/gpu/drm/drm_gem_shmem_helper.c
@@ -525,14 +525,24 @@ static vm_fault_t drm_gem_shmem_fault(struct vm_fault *vmf)
 	struct drm_gem_object *obj = vma->vm_private_data;
 	struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);
 	loff_t num_pages = obj->size >> PAGE_SHIFT;
+	vm_fault_t ret;
 	struct page *page;
 
-	if (vmf->pgoff >= num_pages || WARN_ON_ONCE(!shmem->pages))
-		return VM_FAULT_SIGBUS;
+	mutex_lock(&shmem->pages_lock);
+
+	if (vmf->pgoff >= num_pages ||
+	    WARN_ON_ONCE(!shmem->pages) ||
+	    shmem->madv < 0) {
+		ret = VM_FAULT_SIGBUS;
+	} else {
+		page = shmem->pages[vmf->pgoff];
 
-	page = shmem->pages[vmf->pgoff];
+		ret = vmf_insert_page(vma, vmf->address, page);
+	}
 
-	return vmf_insert_page(vma, vmf->address, page);
+	mutex_unlock(&shmem->pages_lock);
+
+	return ret;
 }
 
 static void drm_gem_shmem_vm_open(struct vm_area_struct *vma)
-- 
2.29.2


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 1/2] drm/shmem-helper: Check for purged buffers in fault handler
@ 2021-02-23 15:51   ` Neil Roberts
  0 siblings, 0 replies; 10+ messages in thread
From: Neil Roberts @ 2021-02-23 15:51 UTC (permalink / raw)
  To: Rob Herring, Tomeu Vizoso, Alyssa Rosenzweig, Steven Price, Robin Murphy
  Cc: stable, dri-devel

When a buffer is madvised as not needed and then purged, any attempts to
access the buffer from user-space should cause a bus fault. This patch
adds a check for that.

Cc: stable@vger.kernel.org
Fixes: 17acb9f35ed7 ("drm/shmem: Add madvise state and purge helpers")
Signed-off-by: Neil Roberts <nroberts@igalia.com>
---
 drivers/gpu/drm/drm_gem_shmem_helper.c | 18 ++++++++++++++----
 1 file changed, 14 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c b/drivers/gpu/drm/drm_gem_shmem_helper.c
index 9825c378dfa6..b26139b1dc35 100644
--- a/drivers/gpu/drm/drm_gem_shmem_helper.c
+++ b/drivers/gpu/drm/drm_gem_shmem_helper.c
@@ -525,14 +525,24 @@ static vm_fault_t drm_gem_shmem_fault(struct vm_fault *vmf)
 	struct drm_gem_object *obj = vma->vm_private_data;
 	struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);
 	loff_t num_pages = obj->size >> PAGE_SHIFT;
+	vm_fault_t ret;
 	struct page *page;
 
-	if (vmf->pgoff >= num_pages || WARN_ON_ONCE(!shmem->pages))
-		return VM_FAULT_SIGBUS;
+	mutex_lock(&shmem->pages_lock);
+
+	if (vmf->pgoff >= num_pages ||
+	    WARN_ON_ONCE(!shmem->pages) ||
+	    shmem->madv < 0) {
+		ret = VM_FAULT_SIGBUS;
+	} else {
+		page = shmem->pages[vmf->pgoff];
 
-	page = shmem->pages[vmf->pgoff];
+		ret = vmf_insert_page(vma, vmf->address, page);
+	}
 
-	return vmf_insert_page(vma, vmf->address, page);
+	mutex_unlock(&shmem->pages_lock);
+
+	return ret;
 }
 
 static void drm_gem_shmem_vm_open(struct vm_area_struct *vma)
-- 
2.29.2

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH v2 2/2] drm/shmem-helper: Don't remove the offset in vm_area_struct pgoff
  2021-02-23 15:51 [PATCH 0/2] Fix purging buffers in the shmem helpers Neil Roberts
@ 2021-02-23 15:51   ` Neil Roberts
  2021-02-23 15:51   ` Neil Roberts
  2021-03-05 10:22 ` [PATCH 0/2] Fix purging buffers in the shmem helpers Steven Price
  2 siblings, 0 replies; 10+ messages in thread
From: Neil Roberts @ 2021-02-23 15:51 UTC (permalink / raw)
  To: Rob Herring, Tomeu Vizoso, Alyssa Rosenzweig, Steven Price, Robin Murphy
  Cc: dri-devel, stable

When mmapping the shmem, it would previously adjust the pgoff in the
vm_area_struct to remove the fake offset that is added to be able to
identify the buffer. This patch removes the adjustment and makes the
fault handler use the vm_fault address to calculate the page offset
instead. Although using this address is apparently discouraged, several
DRM drivers seem to be doing it anyway.

The problem with removing the pgoff is that it prevents
drm_vma_node_unmap from working because that searches the mapping tree
by address. That doesn't work because all of the mappings are at offset
0. drm_vma_node_unmap is being used by the shmem helpers when purging
the buffer.

This fixes a bug in Panfrost which is using drm_gem_shmem_purge. Without
this the mapping for the purged buffer can still be accessed which might
mean it would access random pages from other buffers

v2: Don't check whether the unsigned page_offset is less than 0.

Cc: stable@vger.kernel.org
Fixes: 17acb9f35ed7 ("drm/shmem: Add madvise state and purge helpers")
Signed-off-by: Neil Roberts <nroberts@igalia.com>
---
 drivers/gpu/drm/drm_gem_shmem_helper.c | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c b/drivers/gpu/drm/drm_gem_shmem_helper.c
index b26139b1dc35..5b5c095e86a9 100644
--- a/drivers/gpu/drm/drm_gem_shmem_helper.c
+++ b/drivers/gpu/drm/drm_gem_shmem_helper.c
@@ -527,15 +527,19 @@ static vm_fault_t drm_gem_shmem_fault(struct vm_fault *vmf)
 	loff_t num_pages = obj->size >> PAGE_SHIFT;
 	vm_fault_t ret;
 	struct page *page;
+	pgoff_t page_offset;
+
+	/* We don't use vmf->pgoff since that has the fake offset */
+	page_offset = (vmf->address - vma->vm_start) >> PAGE_SHIFT;
 
 	mutex_lock(&shmem->pages_lock);
 
-	if (vmf->pgoff >= num_pages ||
+	if (page_offset >= num_pages ||
 	    WARN_ON_ONCE(!shmem->pages) ||
 	    shmem->madv < 0) {
 		ret = VM_FAULT_SIGBUS;
 	} else {
-		page = shmem->pages[vmf->pgoff];
+		page = shmem->pages[page_offset];
 
 		ret = vmf_insert_page(vma, vmf->address, page);
 	}
@@ -591,9 +595,6 @@ int drm_gem_shmem_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma)
 	struct drm_gem_shmem_object *shmem;
 	int ret;
 
-	/* Remove the fake offset */
-	vma->vm_pgoff -= drm_vma_node_start(&obj->vma_node);
-
 	if (obj->import_attach) {
 		/* Drop the reference drm_gem_mmap_obj() acquired.*/
 		drm_gem_object_put(obj);
-- 
2.29.2


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH v2 2/2] drm/shmem-helper: Don't remove the offset in vm_area_struct pgoff
@ 2021-02-23 15:51   ` Neil Roberts
  0 siblings, 0 replies; 10+ messages in thread
From: Neil Roberts @ 2021-02-23 15:51 UTC (permalink / raw)
  To: Rob Herring, Tomeu Vizoso, Alyssa Rosenzweig, Steven Price, Robin Murphy
  Cc: stable, dri-devel

When mmapping the shmem, it would previously adjust the pgoff in the
vm_area_struct to remove the fake offset that is added to be able to
identify the buffer. This patch removes the adjustment and makes the
fault handler use the vm_fault address to calculate the page offset
instead. Although using this address is apparently discouraged, several
DRM drivers seem to be doing it anyway.

The problem with removing the pgoff is that it prevents
drm_vma_node_unmap from working because that searches the mapping tree
by address. That doesn't work because all of the mappings are at offset
0. drm_vma_node_unmap is being used by the shmem helpers when purging
the buffer.

This fixes a bug in Panfrost which is using drm_gem_shmem_purge. Without
this the mapping for the purged buffer can still be accessed which might
mean it would access random pages from other buffers

v2: Don't check whether the unsigned page_offset is less than 0.

Cc: stable@vger.kernel.org
Fixes: 17acb9f35ed7 ("drm/shmem: Add madvise state and purge helpers")
Signed-off-by: Neil Roberts <nroberts@igalia.com>
---
 drivers/gpu/drm/drm_gem_shmem_helper.c | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c b/drivers/gpu/drm/drm_gem_shmem_helper.c
index b26139b1dc35..5b5c095e86a9 100644
--- a/drivers/gpu/drm/drm_gem_shmem_helper.c
+++ b/drivers/gpu/drm/drm_gem_shmem_helper.c
@@ -527,15 +527,19 @@ static vm_fault_t drm_gem_shmem_fault(struct vm_fault *vmf)
 	loff_t num_pages = obj->size >> PAGE_SHIFT;
 	vm_fault_t ret;
 	struct page *page;
+	pgoff_t page_offset;
+
+	/* We don't use vmf->pgoff since that has the fake offset */
+	page_offset = (vmf->address - vma->vm_start) >> PAGE_SHIFT;
 
 	mutex_lock(&shmem->pages_lock);
 
-	if (vmf->pgoff >= num_pages ||
+	if (page_offset >= num_pages ||
 	    WARN_ON_ONCE(!shmem->pages) ||
 	    shmem->madv < 0) {
 		ret = VM_FAULT_SIGBUS;
 	} else {
-		page = shmem->pages[vmf->pgoff];
+		page = shmem->pages[page_offset];
 
 		ret = vmf_insert_page(vma, vmf->address, page);
 	}
@@ -591,9 +595,6 @@ int drm_gem_shmem_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma)
 	struct drm_gem_shmem_object *shmem;
 	int ret;
 
-	/* Remove the fake offset */
-	vma->vm_pgoff -= drm_vma_node_start(&obj->vma_node);
-
 	if (obj->import_attach) {
 		/* Drop the reference drm_gem_mmap_obj() acquired.*/
 		drm_gem_object_put(obj);
-- 
2.29.2

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH 1/2] drm/shmem-helper: Check for purged buffers in fault handler
  2021-02-23 15:51   ` Neil Roberts
@ 2021-02-24 16:39     ` Steven Price
  -1 siblings, 0 replies; 10+ messages in thread
From: Steven Price @ 2021-02-24 16:39 UTC (permalink / raw)
  To: Neil Roberts, Rob Herring, Tomeu Vizoso, Alyssa Rosenzweig, Robin Murphy
  Cc: dri-devel, stable

On 23/02/2021 15:51, Neil Roberts wrote:
> When a buffer is madvised as not needed and then purged, any attempts to
> access the buffer from user-space should cause a bus fault. This patch
> adds a check for that.
> 
> Cc: stable@vger.kernel.org
> Fixes: 17acb9f35ed7 ("drm/shmem: Add madvise state and purge helpers")
> Signed-off-by: Neil Roberts <nroberts@igalia.com>

Reviewed-by: Steven Price <steven.price@arm.com>

> ---
>   drivers/gpu/drm/drm_gem_shmem_helper.c | 18 ++++++++++++++----
>   1 file changed, 14 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c b/drivers/gpu/drm/drm_gem_shmem_helper.c
> index 9825c378dfa6..b26139b1dc35 100644
> --- a/drivers/gpu/drm/drm_gem_shmem_helper.c
> +++ b/drivers/gpu/drm/drm_gem_shmem_helper.c
> @@ -525,14 +525,24 @@ static vm_fault_t drm_gem_shmem_fault(struct vm_fault *vmf)
>   	struct drm_gem_object *obj = vma->vm_private_data;
>   	struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);
>   	loff_t num_pages = obj->size >> PAGE_SHIFT;
> +	vm_fault_t ret;
>   	struct page *page;
>   
> -	if (vmf->pgoff >= num_pages || WARN_ON_ONCE(!shmem->pages))
> -		return VM_FAULT_SIGBUS;
> +	mutex_lock(&shmem->pages_lock);
> +
> +	if (vmf->pgoff >= num_pages ||
> +	    WARN_ON_ONCE(!shmem->pages) ||
> +	    shmem->madv < 0) {
> +		ret = VM_FAULT_SIGBUS;
> +	} else {
> +		page = shmem->pages[vmf->pgoff];
>   
> -	page = shmem->pages[vmf->pgoff];
> +		ret = vmf_insert_page(vma, vmf->address, page);
> +	}
>   
> -	return vmf_insert_page(vma, vmf->address, page);
> +	mutex_unlock(&shmem->pages_lock);
> +
> +	return ret;
>   }
>   
>   static void drm_gem_shmem_vm_open(struct vm_area_struct *vma)
> 


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 1/2] drm/shmem-helper: Check for purged buffers in fault handler
@ 2021-02-24 16:39     ` Steven Price
  0 siblings, 0 replies; 10+ messages in thread
From: Steven Price @ 2021-02-24 16:39 UTC (permalink / raw)
  To: Neil Roberts, Rob Herring, Tomeu Vizoso, Alyssa Rosenzweig, Robin Murphy
  Cc: stable, dri-devel

On 23/02/2021 15:51, Neil Roberts wrote:
> When a buffer is madvised as not needed and then purged, any attempts to
> access the buffer from user-space should cause a bus fault. This patch
> adds a check for that.
> 
> Cc: stable@vger.kernel.org
> Fixes: 17acb9f35ed7 ("drm/shmem: Add madvise state and purge helpers")
> Signed-off-by: Neil Roberts <nroberts@igalia.com>

Reviewed-by: Steven Price <steven.price@arm.com>

> ---
>   drivers/gpu/drm/drm_gem_shmem_helper.c | 18 ++++++++++++++----
>   1 file changed, 14 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c b/drivers/gpu/drm/drm_gem_shmem_helper.c
> index 9825c378dfa6..b26139b1dc35 100644
> --- a/drivers/gpu/drm/drm_gem_shmem_helper.c
> +++ b/drivers/gpu/drm/drm_gem_shmem_helper.c
> @@ -525,14 +525,24 @@ static vm_fault_t drm_gem_shmem_fault(struct vm_fault *vmf)
>   	struct drm_gem_object *obj = vma->vm_private_data;
>   	struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);
>   	loff_t num_pages = obj->size >> PAGE_SHIFT;
> +	vm_fault_t ret;
>   	struct page *page;
>   
> -	if (vmf->pgoff >= num_pages || WARN_ON_ONCE(!shmem->pages))
> -		return VM_FAULT_SIGBUS;
> +	mutex_lock(&shmem->pages_lock);
> +
> +	if (vmf->pgoff >= num_pages ||
> +	    WARN_ON_ONCE(!shmem->pages) ||
> +	    shmem->madv < 0) {
> +		ret = VM_FAULT_SIGBUS;
> +	} else {
> +		page = shmem->pages[vmf->pgoff];
>   
> -	page = shmem->pages[vmf->pgoff];
> +		ret = vmf_insert_page(vma, vmf->address, page);
> +	}
>   
> -	return vmf_insert_page(vma, vmf->address, page);
> +	mutex_unlock(&shmem->pages_lock);
> +
> +	return ret;
>   }
>   
>   static void drm_gem_shmem_vm_open(struct vm_area_struct *vma)
> 

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v2 2/2] drm/shmem-helper: Don't remove the offset in vm_area_struct pgoff
  2021-02-23 15:51   ` Neil Roberts
@ 2021-02-24 16:41     ` Steven Price
  -1 siblings, 0 replies; 10+ messages in thread
From: Steven Price @ 2021-02-24 16:41 UTC (permalink / raw)
  To: Neil Roberts, Rob Herring, Tomeu Vizoso, Alyssa Rosenzweig, Robin Murphy
  Cc: dri-devel, stable

On 23/02/2021 15:51, Neil Roberts wrote:
> When mmapping the shmem, it would previously adjust the pgoff in the
> vm_area_struct to remove the fake offset that is added to be able to
> identify the buffer. This patch removes the adjustment and makes the
> fault handler use the vm_fault address to calculate the page offset
> instead. Although using this address is apparently discouraged, several
> DRM drivers seem to be doing it anyway.
> 
> The problem with removing the pgoff is that it prevents
> drm_vma_node_unmap from working because that searches the mapping tree
> by address. That doesn't work because all of the mappings are at offset
> 0. drm_vma_node_unmap is being used by the shmem helpers when purging
> the buffer.
> 
> This fixes a bug in Panfrost which is using drm_gem_shmem_purge. Without
> this the mapping for the purged buffer can still be accessed which might
> mean it would access random pages from other buffers
> 
> v2: Don't check whether the unsigned page_offset is less than 0.
> 
> Cc: stable@vger.kernel.org
> Fixes: 17acb9f35ed7 ("drm/shmem: Add madvise state and purge helpers")
> Signed-off-by: Neil Roberts <nroberts@igalia.com>

Reviewed-by: Steven Price <steven.price@arm.com>

> ---
>   drivers/gpu/drm/drm_gem_shmem_helper.c | 11 ++++++-----
>   1 file changed, 6 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c b/drivers/gpu/drm/drm_gem_shmem_helper.c
> index b26139b1dc35..5b5c095e86a9 100644
> --- a/drivers/gpu/drm/drm_gem_shmem_helper.c
> +++ b/drivers/gpu/drm/drm_gem_shmem_helper.c
> @@ -527,15 +527,19 @@ static vm_fault_t drm_gem_shmem_fault(struct vm_fault *vmf)
>   	loff_t num_pages = obj->size >> PAGE_SHIFT;
>   	vm_fault_t ret;
>   	struct page *page;
> +	pgoff_t page_offset;
> +
> +	/* We don't use vmf->pgoff since that has the fake offset */
> +	page_offset = (vmf->address - vma->vm_start) >> PAGE_SHIFT;
>   
>   	mutex_lock(&shmem->pages_lock);
>   
> -	if (vmf->pgoff >= num_pages ||
> +	if (page_offset >= num_pages ||
>   	    WARN_ON_ONCE(!shmem->pages) ||
>   	    shmem->madv < 0) {
>   		ret = VM_FAULT_SIGBUS;
>   	} else {
> -		page = shmem->pages[vmf->pgoff];
> +		page = shmem->pages[page_offset];
>   
>   		ret = vmf_insert_page(vma, vmf->address, page);
>   	}
> @@ -591,9 +595,6 @@ int drm_gem_shmem_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma)
>   	struct drm_gem_shmem_object *shmem;
>   	int ret;
>   
> -	/* Remove the fake offset */
> -	vma->vm_pgoff -= drm_vma_node_start(&obj->vma_node);
> -
>   	if (obj->import_attach) {
>   		/* Drop the reference drm_gem_mmap_obj() acquired.*/
>   		drm_gem_object_put(obj);
> 


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v2 2/2] drm/shmem-helper: Don't remove the offset in vm_area_struct pgoff
@ 2021-02-24 16:41     ` Steven Price
  0 siblings, 0 replies; 10+ messages in thread
From: Steven Price @ 2021-02-24 16:41 UTC (permalink / raw)
  To: Neil Roberts, Rob Herring, Tomeu Vizoso, Alyssa Rosenzweig, Robin Murphy
  Cc: stable, dri-devel

On 23/02/2021 15:51, Neil Roberts wrote:
> When mmapping the shmem, it would previously adjust the pgoff in the
> vm_area_struct to remove the fake offset that is added to be able to
> identify the buffer. This patch removes the adjustment and makes the
> fault handler use the vm_fault address to calculate the page offset
> instead. Although using this address is apparently discouraged, several
> DRM drivers seem to be doing it anyway.
> 
> The problem with removing the pgoff is that it prevents
> drm_vma_node_unmap from working because that searches the mapping tree
> by address. That doesn't work because all of the mappings are at offset
> 0. drm_vma_node_unmap is being used by the shmem helpers when purging
> the buffer.
> 
> This fixes a bug in Panfrost which is using drm_gem_shmem_purge. Without
> this the mapping for the purged buffer can still be accessed which might
> mean it would access random pages from other buffers
> 
> v2: Don't check whether the unsigned page_offset is less than 0.
> 
> Cc: stable@vger.kernel.org
> Fixes: 17acb9f35ed7 ("drm/shmem: Add madvise state and purge helpers")
> Signed-off-by: Neil Roberts <nroberts@igalia.com>

Reviewed-by: Steven Price <steven.price@arm.com>

> ---
>   drivers/gpu/drm/drm_gem_shmem_helper.c | 11 ++++++-----
>   1 file changed, 6 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c b/drivers/gpu/drm/drm_gem_shmem_helper.c
> index b26139b1dc35..5b5c095e86a9 100644
> --- a/drivers/gpu/drm/drm_gem_shmem_helper.c
> +++ b/drivers/gpu/drm/drm_gem_shmem_helper.c
> @@ -527,15 +527,19 @@ static vm_fault_t drm_gem_shmem_fault(struct vm_fault *vmf)
>   	loff_t num_pages = obj->size >> PAGE_SHIFT;
>   	vm_fault_t ret;
>   	struct page *page;
> +	pgoff_t page_offset;
> +
> +	/* We don't use vmf->pgoff since that has the fake offset */
> +	page_offset = (vmf->address - vma->vm_start) >> PAGE_SHIFT;
>   
>   	mutex_lock(&shmem->pages_lock);
>   
> -	if (vmf->pgoff >= num_pages ||
> +	if (page_offset >= num_pages ||
>   	    WARN_ON_ONCE(!shmem->pages) ||
>   	    shmem->madv < 0) {
>   		ret = VM_FAULT_SIGBUS;
>   	} else {
> -		page = shmem->pages[vmf->pgoff];
> +		page = shmem->pages[page_offset];
>   
>   		ret = vmf_insert_page(vma, vmf->address, page);
>   	}
> @@ -591,9 +595,6 @@ int drm_gem_shmem_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma)
>   	struct drm_gem_shmem_object *shmem;
>   	int ret;
>   
> -	/* Remove the fake offset */
> -	vma->vm_pgoff -= drm_vma_node_start(&obj->vma_node);
> -
>   	if (obj->import_attach) {
>   		/* Drop the reference drm_gem_mmap_obj() acquired.*/
>   		drm_gem_object_put(obj);
> 

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 0/2] Fix purging buffers in the shmem helpers
  2021-02-23 15:51 [PATCH 0/2] Fix purging buffers in the shmem helpers Neil Roberts
  2021-02-23 15:51   ` Neil Roberts
  2021-02-23 15:51   ` Neil Roberts
@ 2021-03-05 10:22 ` Steven Price
  2 siblings, 0 replies; 10+ messages in thread
From: Steven Price @ 2021-03-05 10:22 UTC (permalink / raw)
  To: Neil Roberts, Rob Herring, Tomeu Vizoso, Alyssa Rosenzweig, Robin Murphy
  Cc: dri-devel

On 23/02/2021 15:51, Neil Roberts wrote:
> These two patches fix a problem with the madvise purging code for the
> shmem helpers where the mmaping for a purged buffer wouldn't get
> invalidated correctly. This presumably ends up as a security hole
> where the mapping can be accessed from user-space to read and write
> random pages from other buffers. This is currently affecting Panfrost.
> The second patch is a v2 from a patch that was sent standalone.
> 
> There is a WIP IGT test for Panfrost which demonstrates the bug here:
> 
> https://gitlab.freedesktop.org/nroberts/igt-gpu-tools/-/commits/panfrost-purgemap/
> 
> Neil Roberts (2):
>    drm/shmem-helper: Check for purged buffers in fault handler
>    drm/shmem-helper: Don't remove the offset in vm_area_struct pgoff
> 
>   drivers/gpu/drm/drm_gem_shmem_helper.c | 25 ++++++++++++++++++-------
>   1 file changed, 18 insertions(+), 7 deletions(-)
> 

Pushed to drm-misc-fixes

Thanks,

Steve
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2021-03-05 10:21 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-02-23 15:51 [PATCH 0/2] Fix purging buffers in the shmem helpers Neil Roberts
2021-02-23 15:51 ` [PATCH 1/2] drm/shmem-helper: Check for purged buffers in fault handler Neil Roberts
2021-02-23 15:51   ` Neil Roberts
2021-02-24 16:39   ` Steven Price
2021-02-24 16:39     ` Steven Price
2021-02-23 15:51 ` [PATCH v2 2/2] drm/shmem-helper: Don't remove the offset in vm_area_struct pgoff Neil Roberts
2021-02-23 15:51   ` Neil Roberts
2021-02-24 16:41   ` Steven Price
2021-02-24 16:41     ` Steven Price
2021-03-05 10:22 ` [PATCH 0/2] Fix purging buffers in the shmem helpers Steven Price

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.