APPLIED: [SRU Focal, HWE-5.11, Impish] UBUNTU: SAUCE: drm/vmwgfx: Fix stale file descriptors on failed usercopy
Stefan Bader
stefan.bader at canonical.com
Fri Jan 28 09:04:18 UTC 2022
- Previous message (by thread): [SRU Focal, OEM-5.10, HWE-5.11, Impish, OEM-5.14, Jammy] UBUNTU: SAUCE: drm/vmwgfx: Fix stale file descriptors on failed usercopy
- Next message (by thread): ACK: [SRU Bionic, Focal, OEM-5.10, HWE-5.11, Impish, OEM-5.14, Jammy 0/1] CVE-2022-22942
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
On 27.01.22 21:58, Thadeu Lima de Souza Cascardo wrote:
> From: Mathias Krause <minipli at grsecurity.net>
>
> A failing usercopy of the fence_rep object will lead to a stale entry in
> the file descriptor table as put_unused_fd() won't release it. This
> enables userland to refer to a dangling 'file' object through that still
> valid file descriptor, leading to all kinds of use-after-free
> exploitation scenarios.
>
> Fix this by deferring the call to fd_install() until after the usercopy
> has succeeded.
>
> Cc: Zack Rusin <zackr at vmware.com>
> Fixes: c906965dee22 ("drm/vmwgfx: Add export fence to file descriptor support")
> [mks: backport to v5.16 and older]
> Signed-off-by: Mathias Krause <minipli at grsecurity.net>
> CVE-2022-22942
> Signed-off-by: Thadeu Lima de Souza Cascardo <cascardo at canonical.com>
> ---
Applied to impish,focal:linux/master-next and
focal:linux-hwe-5.11/hwe-5.11-next. Thanks.
-Stefan
> drivers/gpu/drm/vmwgfx/vmwgfx_drv.h | 5 ++--
> drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c | 33 +++++++++++++------------
> drivers/gpu/drm/vmwgfx/vmwgfx_fence.c | 2 +-
> drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 2 +-
> 4 files changed, 21 insertions(+), 21 deletions(-)
>
> diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
> index 1523b51a7284..ad208a5f4ebe 100644
> --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
> +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
> @@ -1088,15 +1088,14 @@ extern int vmw_execbuf_fence_commands(struct drm_file *file_priv,
> struct vmw_private *dev_priv,
> struct vmw_fence_obj **p_fence,
> uint32_t *p_handle);
> -extern void vmw_execbuf_copy_fence_user(struct vmw_private *dev_priv,
> +extern int vmw_execbuf_copy_fence_user(struct vmw_private *dev_priv,
> struct vmw_fpriv *vmw_fp,
> int ret,
> struct drm_vmw_fence_rep __user
> *user_fence_rep,
> struct vmw_fence_obj *fence,
> uint32_t fence_handle,
> - int32_t out_fence_fd,
> - struct sync_file *sync_file);
> + int32_t out_fence_fd);
> bool vmw_cmd_describe(const void *buf, u32 *size, char const **cmd);
>
> /**
> diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
> index 83e1b54eb864..739cbc77d886 100644
> --- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
> +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
> @@ -3816,17 +3816,17 @@ int vmw_execbuf_fence_commands(struct drm_file *file_priv,
> * Also if copying fails, user-space will be unable to signal the fence object
> * so we wait for it immediately, and then unreference the user-space reference.
> */
> -void
> +int
> vmw_execbuf_copy_fence_user(struct vmw_private *dev_priv,
> struct vmw_fpriv *vmw_fp, int ret,
> struct drm_vmw_fence_rep __user *user_fence_rep,
> struct vmw_fence_obj *fence, uint32_t fence_handle,
> - int32_t out_fence_fd, struct sync_file *sync_file)
> + int32_t out_fence_fd)
> {
> struct drm_vmw_fence_rep fence_rep;
>
> if (user_fence_rep == NULL)
> - return;
> + return 0;
>
> memset(&fence_rep, 0, sizeof(fence_rep));
>
> @@ -3854,20 +3854,14 @@ vmw_execbuf_copy_fence_user(struct vmw_private *dev_priv,
> * handle.
> */
> if (unlikely(ret != 0) && (fence_rep.error == 0)) {
> - if (sync_file)
> - fput(sync_file->file);
> -
> - if (fence_rep.fd != -1) {
> - put_unused_fd(fence_rep.fd);
> - fence_rep.fd = -1;
> - }
> -
> ttm_ref_object_base_unref(vmw_fp->tfile, fence_handle,
> TTM_REF_USAGE);
> VMW_DEBUG_USER("Fence copy error. Syncing.\n");
> (void) vmw_fence_obj_wait(fence, false, false,
> VMW_FENCE_WAIT_TIMEOUT);
> }
> +
> + return ret ? -EFAULT : 0;
> }
>
> /**
> @@ -4209,16 +4203,23 @@ int vmw_execbuf_process(struct drm_file *file_priv,
>
> (void) vmw_fence_obj_wait(fence, false, false,
> VMW_FENCE_WAIT_TIMEOUT);
> + }
> + }
> +
> + ret = vmw_execbuf_copy_fence_user(dev_priv, vmw_fpriv(file_priv), ret,
> + user_fence_rep, fence, handle, out_fence_fd);
> +
> + if (sync_file) {
> + if (ret) {
> + /* usercopy of fence failed, put the file object */
> + fput(sync_file->file);
> + put_unused_fd(out_fence_fd);
> } else {
> /* Link the fence with the FD created earlier */
> fd_install(out_fence_fd, sync_file->file);
> }
> }
>
> - vmw_execbuf_copy_fence_user(dev_priv, vmw_fpriv(file_priv), ret,
> - user_fence_rep, fence, handle, out_fence_fd,
> - sync_file);
> -
> /* Don't unreference when handing fence out */
> if (unlikely(out_fence != NULL)) {
> *out_fence = fence;
> @@ -4236,7 +4237,7 @@ int vmw_execbuf_process(struct drm_file *file_priv,
> */
> vmw_validation_unref_lists(&val_ctx);
>
> - return 0;
> + return ret;
>
> out_unlock_binding:
> mutex_unlock(&dev_priv->binding_mutex);
> diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c
> index 0f8d29397157..8bc41ec97d71 100644
> --- a/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c
> +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c
> @@ -1171,7 +1171,7 @@ int vmw_fence_event_ioctl(struct drm_device *dev, void *data,
> }
>
> vmw_execbuf_copy_fence_user(dev_priv, vmw_fp, 0, user_fence_rep, fence,
> - handle, -1, NULL);
> + handle, -1);
> vmw_fence_obj_unreference(&fence);
> return 0;
> out_no_create:
> diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
> index 312ed0881a99..e58112997c88 100644
> --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
> +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
> @@ -2479,7 +2479,7 @@ void vmw_kms_helper_validation_finish(struct vmw_private *dev_priv,
> if (file_priv)
> vmw_execbuf_copy_fence_user(dev_priv, vmw_fpriv(file_priv),
> ret, user_fence_rep, fence,
> - handle, -1, NULL);
> + handle, -1);
> if (out_fence)
> *out_fence = fence;
> else
-------------- next part --------------
A non-text attachment was scrubbed...
Name: OpenPGP_signature
Type: application/pgp-signature
Size: 833 bytes
Desc: OpenPGP digital signature
URL: <https://lists.ubuntu.com/archives/kernel-team/attachments/20220128/e74b1772/attachment.sig>
- Previous message (by thread): [SRU Focal, OEM-5.10, HWE-5.11, Impish, OEM-5.14, Jammy] UBUNTU: SAUCE: drm/vmwgfx: Fix stale file descriptors on failed usercopy
- Next message (by thread): ACK: [SRU Bionic, Focal, OEM-5.10, HWE-5.11, Impish, OEM-5.14, Jammy 0/1] CVE-2022-22942
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
More information about the kernel-team
mailing list