Patch "drm/vmwgfx: Type-check lookups of fence objects" has been added to the 4.10-stable tree
Subsystems (4)
This is a note to let you know that I've just added the patch titled
drm/vmwgfx: Type-check lookups of fence objects
to the 4.10-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
drm-vmwgfx-type-check-lookups-of-fence-objects.patch
and it can be found in the queue-4.10 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
f7652afa8eadb416b23eb57dec6f158529942041Mon Sep 17 00:00:00 2001
From: Thomas Hellstrom <[email protected]>
Date: Mon, 27 Mar 2017 11:09:08 +0200
Subject: drm/vmwgfx: Type-check lookups of fence objects
From: Thomas Hellstrom <[email protected]>
commit f7652afa8eadb416b23eb57dec6f158529942041 upstream.
A malicious caller could otherwise hand over handles to other objects causing all sorts of interesting problems.
Testing done: Ran a Fedora 25 desktop using both Xorg and gnome-shell/Wayland.
--- drivers/gpu/drm/vmwgfx/vmwgfx_fence.c | 75 ++++++++++++++++++++++------------ 1 file changed, 49 insertions(+), 26 deletions(-)
drivers/gpu/drm/vmwgfx/vmwgfx_fence.c +49 -26
@@ -538,7 +538,7 @@ int vmw_fence_create(struct vmw_fence_ma struct vmw_fence_obj **p_fence) {struct vmw_fence_obj *fence; -int ret; +int ret; fence =kzalloc (sizeof (*fence),GFP_KERNEL );if (unlikely (fence ==NULL ))
@@ -701,6 +701,41 @@ void vmw_fence_fifo_up(struct vmw_fence_ } +/** +* vmw_fence_obj_lookup - Look up a user-space fence object +* +* @tfile: A struct ttm_object_file identifying the caller. +* @handle: A handle identifying the fence object. +* @return: A struct vmw_user_fence base ttm object on success or +* an error pointer on failure. +* +* The fence object is looked up and type-checked. The caller needs +* to have opened the fence object first, but since that happens on +* creation and fence objects aren't shareable, that's not an +* issue currently. +*/ +static struct ttm_base_object * +vmw_fence_obj_lookup (struct ttm_object_file *tfile,u32 handle) +{ +struct ttm_base_object *base =ttm_base_object_lookup (tfile, handle); + +if (!base) { +pr_err ("Invalid fence object handle 0x%08lx.\n" , + (unsigned long )handle); +return ERR_PTR (-EINVAL ); + } + +if (base->refcount_release != vmw_user_fence_base_release) { +pr_err ("Invalid fence object handle 0x%08lx.\n" , + (unsigned long )handle); +ttm_base_object_unref (&base); +return ERR_PTR (-EINVAL ); + } + +return base; +} + +int vmw_fence_obj_wait_ioctl (struct drm_device *dev,void *data,struct drm_file *file_priv) {
@@ -726,13 +761,9 @@ int vmw_fence_obj_wait_ioctl(struct drm_ arg->kernel_cookie = jiffies + wait_timeout; } - base =ttm_base_object_lookup (tfile, arg->handle); -if (unlikely (base ==NULL )) { -printk (KERN_ERR "Wait invalid fence object handle " -"0x%08lx.\n" , - (unsigned long )arg->handle); -return -EINVAL ; - } + base =vmw_fence_obj_lookup (tfile, arg->handle); +if (IS_ERR (base)) +return PTR_ERR (base); fence = &(container_of(base, struct vmw_user_fence, base)->fence);
@@ -771,13 +802,9 @@ int vmw_fence_obj_signaled_ioctl(structstruct ttm_object_file *tfile =vmw_fpriv (file_priv)->tfile;struct vmw_private *dev_priv =vmw_priv (dev); - base =ttm_base_object_lookup (tfile, arg->handle); -if (unlikely (base ==NULL )) { -printk (KERN_ERR "Fence signaled invalid fence object handle " -"0x%08lx.\n" , - (unsigned long )arg->handle); -return -EINVAL ; - } + base =vmw_fence_obj_lookup (tfile, arg->handle); +if (IS_ERR (base)) +return PTR_ERR (base); fence = &(container_of(base, struct vmw_user_fence, base)->fence); fman =fman_from_fence (fence);
@@ -1024,6 +1051,7 @@ int vmw_fence_event_ioctl(struct drm_dev (struct drm_vmw_fence_event_arg *) data;struct vmw_fence_obj *fence =NULL ;struct vmw_fpriv *vmw_fp =vmw_fpriv (file_priv); +struct ttm_object_file *tfile = vmw_fp->tfile;struct drm_vmw_fence_rep __user *user_fence_rep = (struct drm_vmw_fence_rep __user *)(unsigned long ) arg->fence_rep;
@@ -1037,15 +1065,11 @@ int vmw_fence_event_ioctl(struct drm_dev*/ if (arg->handle) {struct ttm_base_object *base = -ttm_base_object_lookup_for_ref (dev_priv->tdev, - arg->handle); +vmw_fence_obj_lookup (tfile, arg->handle); + +if (IS_ERR (base)) +return PTR_ERR (base); -if (unlikely (base ==NULL )) { -DRM_ERROR ("Fence event invalid fence object handle " -"0x%08lx.\n" , - (unsigned long )arg->handle); -return -EINVAL ; - } fence = &(container_of(base, struct vmw_user_fence, base)->fence); (void )vmw_fence_obj_reference (fence);
@@ -1053,7 +1077,7 @@ int vmw_fence_event_ioctl(struct drm_devif (user_fence_rep !=NULL ) {bool existed; - ret =ttm_ref_object_add (vmw_fp->tfile, base, + ret =ttm_ref_object_add (tfile, base,TTM_REF_USAGE , &existed);if (unlikely (ret !=0 )) { DRM_ERROR("Failed to reference a fence "
@@ -1097,8 +1121,7 @@ int vmw_fence_event_ioctl(struct drm_devreturn 0 ; out_no_create:if (user_fence_rep !=NULL ) -ttm_ref_object_base_unref (vmw_fpriv (file_priv)->tfile, - handle,TTM_REF_USAGE ); +ttm_ref_object_base_unref (tfile, handle,TTM_REF_USAGE ); out_no_ref_obj:vmw_fence_obj_unreference (&fence);return ret;
Patches currently in stable-queue which might be from [email protected] are
queue-4.10/drm-vmwgfx-remove-getparam-error-message.patch queue-4.10/drm-vmwgfx-type-check-lookups-of-fence-objects.patch queue-4.10/drm-vmwgfx-fix-integer-overflow-in-vmw_surface_define_ioctl.patch queue-4.10/drm-ttm-drm-vmwgfx-relax-permission-checking-when-opening-surfaces.patch