diff options
author | Neil Roberts | 2021-02-23 16:51:24 +0100 |
---|---|---|
committer | Maarten Lankhorst | 2021-03-11 11:11:33 +0100 |
commit | d611b4a0907cece060699f2fd347c492451cd2aa (patch) | |
tree | 62bb4333a8f34a9cb3e93c492561f5f4327d2f6c /drivers | |
parent | 738acd49eb018feb873e0fac8f9517493f6ce2c7 (diff) |
drm/shmem-helper: Check for purged buffers in fault handler
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>
Signed-off-by: Steven Price <steven.price@arm.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20210223155125.199577-2-nroberts@igalia.com
Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gpu/drm/drm_gem_shmem_helper.c | 18 |
1 files 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) |