From: Greg Kroah-Hartman Date: Fri, 12 Mar 2021 13:38:57 +0000 (+0100) Subject: 5.4-stable patches X-Git-Tag: v4.4.262~89 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=00c19f188bc5013d967a6c326a1de582705c0aeb;p=thirdparty%2Fkernel%2Fstable-queue.git 5.4-stable patches added patches: drm-compat-clear-bounce-structures.patch drm-shmem-helper-check-for-purged-buffers-in-fault-handler.patch drm-shmem-helper-don-t-remove-the-offset-in-vm_area_struct-pgoff.patch --- diff --git a/queue-5.4/drm-compat-clear-bounce-structures.patch b/queue-5.4/drm-compat-clear-bounce-structures.patch new file mode 100644 index 00000000000..d8bac9920d8 --- /dev/null +++ b/queue-5.4/drm-compat-clear-bounce-structures.patch @@ -0,0 +1,79 @@ +From de066e116306baf3a6a62691ac63cfc0b1dabddb Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Mon, 22 Feb 2021 11:06:43 +0100 +Subject: drm/compat: Clear bounce structures + +From: Daniel Vetter + +commit de066e116306baf3a6a62691ac63cfc0b1dabddb upstream. + +Some of them have gaps, or fields we don't clear. Native ioctl code +does full copies plus zero-extends on size mismatch, so nothing can +leak. But compat is more hand-rolled so need to be careful. + +None of these matter for performance, so just memset. + +Also I didn't fix up the CONFIG_DRM_LEGACY or CONFIG_DRM_AGP ioctl, those +are security holes anyway. + +Acked-by: Maxime Ripard +Reported-by: syzbot+620cf21140fc7e772a5d@syzkaller.appspotmail.com # vblank ioctl +Cc: syzbot+620cf21140fc7e772a5d@syzkaller.appspotmail.com +Cc: stable@vger.kernel.org +Signed-off-by: Daniel Vetter +Link: https://patchwork.freedesktop.org/patch/msgid/20210222100643.400935-1-daniel.vetter@ffwll.ch +(cherry picked from commit e926c474ebee404441c838d18224cd6f246a71b7) +Signed-off-by: Maarten Lankhorst +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/drm_ioc32.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +--- a/drivers/gpu/drm/drm_ioc32.c ++++ b/drivers/gpu/drm/drm_ioc32.c +@@ -99,6 +99,8 @@ static int compat_drm_version(struct fil + if (copy_from_user(&v32, (void __user *)arg, sizeof(v32))) + return -EFAULT; + ++ memset(&v, 0, sizeof(v)); ++ + v = (struct drm_version) { + .name_len = v32.name_len, + .name = compat_ptr(v32.name), +@@ -137,6 +139,9 @@ static int compat_drm_getunique(struct f + + if (copy_from_user(&uq32, (void __user *)arg, sizeof(uq32))) + return -EFAULT; ++ ++ memset(&uq, 0, sizeof(uq)); ++ + uq = (struct drm_unique){ + .unique_len = uq32.unique_len, + .unique = compat_ptr(uq32.unique), +@@ -265,6 +270,8 @@ static int compat_drm_getclient(struct f + if (copy_from_user(&c32, argp, sizeof(c32))) + return -EFAULT; + ++ memset(&client, 0, sizeof(client)); ++ + client.idx = c32.idx; + + err = drm_ioctl_kernel(file, drm_getclient, &client, 0); +@@ -850,6 +857,8 @@ static int compat_drm_wait_vblank(struct + if (copy_from_user(&req32, argp, sizeof(req32))) + return -EFAULT; + ++ memset(&req, 0, sizeof(req)); ++ + req.request.type = req32.request.type; + req.request.sequence = req32.request.sequence; + req.request.signal = req32.request.signal; +@@ -887,6 +896,8 @@ static int compat_drm_mode_addfb2(struct + struct drm_mode_fb_cmd2 req64; + int err; + ++ memset(&req64, 0, sizeof(req64)); ++ + if (copy_from_user(&req64, argp, + offsetof(drm_mode_fb_cmd232_t, modifier))) + return -EFAULT; diff --git a/queue-5.4/drm-shmem-helper-check-for-purged-buffers-in-fault-handler.patch b/queue-5.4/drm-shmem-helper-check-for-purged-buffers-in-fault-handler.patch new file mode 100644 index 00000000000..39a74683073 --- /dev/null +++ b/queue-5.4/drm-shmem-helper-check-for-purged-buffers-in-fault-handler.patch @@ -0,0 +1,56 @@ +From d611b4a0907cece060699f2fd347c492451cd2aa Mon Sep 17 00:00:00 2001 +From: Neil Roberts +Date: Tue, 23 Feb 2021 16:51:24 +0100 +Subject: drm/shmem-helper: Check for purged buffers in fault handler + +From: Neil Roberts + +commit d611b4a0907cece060699f2fd347c492451cd2aa upstream. + +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 +Reviewed-by: Steven Price +Signed-off-by: Steven Price +Link: https://patchwork.freedesktop.org/patch/msgid/20210223155125.199577-2-nroberts@igalia.com +Signed-off-by: Maarten Lankhorst +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/drm_gem_shmem_helper.c | 18 ++++++++++++++---- + 1 file changed, 14 insertions(+), 4 deletions(-) + +--- a/drivers/gpu/drm/drm_gem_shmem_helper.c ++++ b/drivers/gpu/drm/drm_gem_shmem_helper.c +@@ -474,14 +474,24 @@ static vm_fault_t drm_gem_shmem_fault(st + 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); + +- page = shmem->pages[vmf->pgoff]; ++ if (vmf->pgoff >= num_pages || ++ WARN_ON_ONCE(!shmem->pages) || ++ shmem->madv < 0) { ++ ret = VM_FAULT_SIGBUS; ++ } else { ++ page = shmem->pages[vmf->pgoff]; + +- return vmf_insert_page(vma, vmf->address, page); ++ ret = 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) diff --git a/queue-5.4/drm-shmem-helper-don-t-remove-the-offset-in-vm_area_struct-pgoff.patch b/queue-5.4/drm-shmem-helper-don-t-remove-the-offset-in-vm_area_struct-pgoff.patch new file mode 100644 index 00000000000..991160a0584 --- /dev/null +++ b/queue-5.4/drm-shmem-helper-don-t-remove-the-offset-in-vm_area_struct-pgoff.patch @@ -0,0 +1,74 @@ +From 11d5a4745e00e73745774671dbf2fb07bd6e2363 Mon Sep 17 00:00:00 2001 +From: Neil Roberts +Date: Tue, 23 Feb 2021 16:51:25 +0100 +Subject: drm/shmem-helper: Don't remove the offset in vm_area_struct pgoff + +From: Neil Roberts + +commit 11d5a4745e00e73745774671dbf2fb07bd6e2363 upstream. + +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 +Reviewed-by: Steven Price +Signed-off-by: Steven Price +Link: https://patchwork.freedesktop.org/patch/msgid/20210223155125.199577-3-nroberts@igalia.com +Signed-off-by: Maarten Lankhorst +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/drm_gem_shmem_helper.c | 11 ++++++----- + 1 file changed, 6 insertions(+), 5 deletions(-) + +--- a/drivers/gpu/drm/drm_gem_shmem_helper.c ++++ b/drivers/gpu/drm/drm_gem_shmem_helper.c +@@ -476,15 +476,19 @@ static vm_fault_t drm_gem_shmem_fault(st + 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); + } +@@ -559,9 +563,6 @@ int drm_gem_shmem_mmap(struct file *filp + vma->vm_flags &= ~VM_PFNMAP; + vma->vm_flags |= VM_MIXEDMAP; + +- /* Remove the fake offset */ +- vma->vm_pgoff -= drm_vma_node_start(&shmem->base.vma_node); +- + return 0; + } + EXPORT_SYMBOL_GPL(drm_gem_shmem_mmap); diff --git a/queue-5.4/series b/queue-5.4/series index 491437c7d1e..7fe1e342ebc 100644 --- a/queue-5.4/series +++ b/queue-5.4/series @@ -46,3 +46,6 @@ net-hns3-fix-query-vlan-mask-value-error-for-flow-director.patch net-hns3-fix-bug-when-calculating-the-tcam-table-info.patch s390-cio-return-efault-if-copy_to_user-fails.patch bnxt_en-reliably-allocate-irq-table-on-reset-to-avoid-crash.patch +drm-compat-clear-bounce-structures.patch +drm-shmem-helper-check-for-purged-buffers-in-fault-handler.patch +drm-shmem-helper-don-t-remove-the-offset-in-vm_area_struct-pgoff.patch