Blame SOURCES/CVE-2022-22942.patch

57a3d0
From 05639043d88c1ed4c13670721d222b8621d2fbca Mon Sep 17 00:00:00 2001
57a3d0
From: Joe Lawrence <joe.lawrence@redhat.com>
57a3d0
Date: Wed, 9 Feb 2022 13:27:43 -0500
57a3d0
Subject: [KPATCH CVE-2022-22942] drm/vmwgfx: kpatch fixes for CVE-2022-22942
57a3d0
57a3d0
Kernels:
57a3d0
3.10.0-1160.21.1.el7
57a3d0
3.10.0-1160.24.1.el7
57a3d0
3.10.0-1160.25.1.el7
57a3d0
3.10.0-1160.31.1.el7
57a3d0
3.10.0-1160.36.2.el7
57a3d0
3.10.0-1160.41.1.el7
57a3d0
3.10.0-1160.42.2.el7
57a3d0
3.10.0-1160.45.1.el7
57a3d0
3.10.0-1160.49.1.el7
57a3d0
3.10.0-1160.53.1.el7
57a3d0
57a3d0
Changes since last build:
57a3d0
arches: x86_64
57a3d0
vmwgfx_execbuf.o: changed function: vmw_execbuf_copy_fence_user
57a3d0
vmwgfx_execbuf.o: changed function: vmw_execbuf_process
57a3d0
vmwgfx_fence.o: changed function: vmw_fence_event_ioctl
57a3d0
vmwgfx_kms.o: changed function: vmw_kms_helper_validation_finish
57a3d0
---------------------------
57a3d0
57a3d0
Kpatch-MR: https://gitlab.com/redhat/prdsc/rhel/src/kpatch/rhel-7/-/merge_requests/23
57a3d0
Approved-by: Yannick Cote (@ycote1)
57a3d0
Approved-by: Artem Savkov (@artem.savkov)
57a3d0
Kernels:
57a3d0
3.10.0-1160.21.1.el7
57a3d0
3.10.0-1160.24.1.el7
57a3d0
3.10.0-1160.25.1.el7
57a3d0
3.10.0-1160.31.1.el7
57a3d0
3.10.0-1160.36.2.el7
57a3d0
3.10.0-1160.41.1.el7
57a3d0
3.10.0-1160.42.2.el7
57a3d0
3.10.0-1160.45.1.el7
57a3d0
3.10.0-1160.49.1.el7
57a3d0
3.10.0-1160.53.1.el7
57a3d0
57a3d0
Modifications: none
57a3d0
57a3d0
commit 26695bc7aeaf0bae32d7ab7fcf8950143acb5020
57a3d0
Author: Dave Airlie <airlied@redhat.com>
57a3d0
Date:   Sat Jan 29 02:36:46 2022 -0500
57a3d0
57a3d0
    drm/vmwgfx: Fix stale file descriptors on failed usercopy
57a3d0
57a3d0
    Bugzilla: http://bugzilla.redhat.com/2047597
57a3d0
    CVE: CVE-2022-22942
57a3d0
57a3d0
    commit a0f90c8815706981c483a652a6aefca51a5e191c
57a3d0
    Author: Mathias Krause <minipli@grsecurity.net>
57a3d0
    Date:   Thu Jan 27 18:34:19 2022 +1000
57a3d0
57a3d0
        drm/vmwgfx: Fix stale file descriptors on failed usercopy
57a3d0
57a3d0
        A failing usercopy of the fence_rep object will lead to a stale entry in
57a3d0
        the file descriptor table as put_unused_fd() won't release it. This
57a3d0
        enables userland to refer to a dangling 'file' object through that still
57a3d0
        valid file descriptor, leading to all kinds of use-after-free
57a3d0
        exploitation scenarios.
57a3d0
57a3d0
        Fix this by deferring the call to fd_install() until after the usercopy
57a3d0
        has succeeded.
57a3d0
57a3d0
        Fixes: c906965dee22 ("drm/vmwgfx: Add export fence to file descriptor support")
57a3d0
        Signed-off-by: Mathias Krause <minipli@grsecurity.net>
57a3d0
        Signed-off-by: Zack Rusin <zackr@vmware.com>
57a3d0
        Signed-off-by: Dave Airlie <airlied@redhat.com>
57a3d0
        Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
57a3d0
57a3d0
    Signed-off-by: Dave Airlie <airlied@redhat.com>
57a3d0
57a3d0
Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
57a3d0
---
57a3d0
 drivers/gpu/drm/vmwgfx/vmwgfx_drv.h     |  5 ++--
57a3d0
 drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c | 34 ++++++++++++-------------
57a3d0
 drivers/gpu/drm/vmwgfx/vmwgfx_fence.c   |  2 +-
57a3d0
 drivers/gpu/drm/vmwgfx/vmwgfx_kms.c     |  2 +-
57a3d0
 4 files changed, 21 insertions(+), 22 deletions(-)
57a3d0
57a3d0
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
57a3d0
index cd607ba9c2fe..efd540f02227 100644
57a3d0
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
57a3d0
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
57a3d0
@@ -924,15 +924,14 @@ extern int vmw_execbuf_fence_commands(struct drm_file *file_priv,
57a3d0
 				      struct vmw_private *dev_priv,
57a3d0
 				      struct vmw_fence_obj **p_fence,
57a3d0
 				      uint32_t *p_handle);
57a3d0
-extern void vmw_execbuf_copy_fence_user(struct vmw_private *dev_priv,
57a3d0
+extern int vmw_execbuf_copy_fence_user(struct vmw_private *dev_priv,
57a3d0
 					struct vmw_fpriv *vmw_fp,
57a3d0
 					int ret,
57a3d0
 					struct drm_vmw_fence_rep __user
57a3d0
 					*user_fence_rep,
57a3d0
 					struct vmw_fence_obj *fence,
57a3d0
 					uint32_t fence_handle,
57a3d0
-					int32_t out_fence_fd,
57a3d0
-					struct sync_file *sync_file);
57a3d0
+					int32_t out_fence_fd);
57a3d0
 bool vmw_cmd_describe(const void *buf, u32 *size, char const **cmd);
57a3d0
 
57a3d0
 /**
57a3d0
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
57a3d0
index 88b8178d4687..4f792fb89bb8 100644
57a3d0
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
57a3d0
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
57a3d0
@@ -3595,20 +3595,19 @@ int vmw_execbuf_fence_commands(struct drm_file *file_priv,
57a3d0
  * object so we wait for it immediately, and then unreference the
57a3d0
  * user-space reference.
57a3d0
  */
57a3d0
-void
57a3d0
+int
57a3d0
 vmw_execbuf_copy_fence_user(struct vmw_private *dev_priv,
57a3d0
 			    struct vmw_fpriv *vmw_fp,
57a3d0
 			    int ret,
57a3d0
 			    struct drm_vmw_fence_rep __user *user_fence_rep,
57a3d0
 			    struct vmw_fence_obj *fence,
57a3d0
 			    uint32_t fence_handle,
57a3d0
-			    int32_t out_fence_fd,
57a3d0
-			    struct sync_file *sync_file)
57a3d0
+			    int32_t out_fence_fd)
57a3d0
 {
57a3d0
 	struct drm_vmw_fence_rep fence_rep;
57a3d0
 
57a3d0
 	if (user_fence_rep == NULL)
57a3d0
-		return;
57a3d0
+		return 0;
57a3d0
 
57a3d0
 	memset(&fence_rep, 0, sizeof(fence_rep));
57a3d0
 
57a3d0
@@ -3636,20 +3635,14 @@ vmw_execbuf_copy_fence_user(struct vmw_private *dev_priv,
57a3d0
 	 * and unreference the handle.
57a3d0
 	 */
57a3d0
 	if (unlikely(ret != 0) && (fence_rep.error == 0)) {
57a3d0
-		if (sync_file)
57a3d0
-			fput(sync_file->file);
57a3d0
-
57a3d0
-		if (fence_rep.fd != -1) {
57a3d0
-			put_unused_fd(fence_rep.fd);
57a3d0
-			fence_rep.fd = -1;
57a3d0
-		}
57a3d0
-
57a3d0
 		ttm_ref_object_base_unref(vmw_fp->tfile,
57a3d0
 					  fence_handle, TTM_REF_USAGE);
57a3d0
 		DRM_ERROR("Fence copy error. Syncing.\n");
57a3d0
 		(void) vmw_fence_obj_wait(fence, false, false,
57a3d0
 					  VMW_FENCE_WAIT_TIMEOUT);
57a3d0
 	}
57a3d0
+
57a3d0
+	return ret ? -EFAULT : 0;
57a3d0
 }
57a3d0
 
57a3d0
 /**
57a3d0
@@ -3997,16 +3990,23 @@ int vmw_execbuf_process(struct drm_file *file_priv,
57a3d0
 
57a3d0
 			(void) vmw_fence_obj_wait(fence, false, false,
57a3d0
 						  VMW_FENCE_WAIT_TIMEOUT);
57a3d0
+		}
57a3d0
+	}
57a3d0
+
57a3d0
+	ret = vmw_execbuf_copy_fence_user(dev_priv, vmw_fpriv(file_priv), ret,
57a3d0
+				    user_fence_rep, fence, handle, out_fence_fd);
57a3d0
+
57a3d0
+	if (sync_file) {
57a3d0
+		if (ret) {
57a3d0
+			/* usercopy of fence failed, put the file object */
57a3d0
+			fput(sync_file->file);
57a3d0
+			put_unused_fd(out_fence_fd);
57a3d0
 		} else {
57a3d0
 			/* Link the fence with the FD created earlier */
57a3d0
 			fd_install(out_fence_fd, sync_file->file);
57a3d0
 		}
57a3d0
 	}
57a3d0
 
57a3d0
-	vmw_execbuf_copy_fence_user(dev_priv, vmw_fpriv(file_priv), ret,
57a3d0
-				    user_fence_rep, fence, handle,
57a3d0
-				    out_fence_fd, sync_file);
57a3d0
-
57a3d0
 	/* Don't unreference when handing fence out */
57a3d0
 	if (unlikely(out_fence != NULL)) {
57a3d0
 		*out_fence = fence;
57a3d0
@@ -4024,7 +4024,7 @@ int vmw_execbuf_process(struct drm_file *file_priv,
57a3d0
 	 */
57a3d0
 	vmw_validation_unref_lists(&val_ctx);
57a3d0
 
57a3d0
-	return 0;
57a3d0
+	return ret;
57a3d0
 
57a3d0
 out_unlock_binding:
57a3d0
 	mutex_unlock(&dev_priv->binding_mutex);
57a3d0
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c
57a3d0
index 301260e23e52..624754cc4fc1 100644
57a3d0
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c
57a3d0
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c
57a3d0
@@ -1167,7 +1167,7 @@ int vmw_fence_event_ioctl(struct drm_device *dev, void *data,
57a3d0
 	}
57a3d0
 
57a3d0
 	vmw_execbuf_copy_fence_user(dev_priv, vmw_fp, 0, user_fence_rep, fence,
57a3d0
-				    handle, -1, NULL);
57a3d0
+				    handle, -1);
57a3d0
 	vmw_fence_obj_unreference(&fence);
57a3d0
 	return 0;
57a3d0
 out_no_create:
57a3d0
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
57a3d0
index ed2f67822f45..fdf58090aa4a 100644
57a3d0
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
57a3d0
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
57a3d0
@@ -2565,7 +2565,7 @@ void vmw_kms_helper_validation_finish(struct vmw_private *dev_priv,
57a3d0
 	if (file_priv)
57a3d0
 		vmw_execbuf_copy_fence_user(dev_priv, vmw_fpriv(file_priv),
57a3d0
 					    ret, user_fence_rep, fence,
57a3d0
-					    handle, -1, NULL);
57a3d0
+					    handle, -1);
57a3d0
 	if (out_fence)
57a3d0
 		*out_fence = fence;
57a3d0
 	else
57a3d0
-- 
57a3d0
2.26.3
57a3d0
57a3d0