]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 9 Apr 2017 08:25:33 +0000 (10:25 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 9 Apr 2017 08:25:33 +0000 (10:25 +0200)
added patches:
drm-ttm-drm-vmwgfx-relax-permission-checking-when-opening-surfaces.patch
drm-vmwgfx-avoid-calling-vzalloc-with-a-0-size-in-vmw_get_cap_3d_ioctl.patch
drm-vmwgfx-fix-integer-overflow-in-vmw_surface_define_ioctl.patch
drm-vmwgfx-null-pointer-dereference-in-vmw_surface_define_ioctl.patch
drm-vmwgfx-remove-getparam-error-message.patch
drm-vmwgfx-type-check-lookups-of-fence-objects.patch

queue-4.4/drm-ttm-drm-vmwgfx-relax-permission-checking-when-opening-surfaces.patch [new file with mode: 0644]
queue-4.4/drm-vmwgfx-avoid-calling-vzalloc-with-a-0-size-in-vmw_get_cap_3d_ioctl.patch [new file with mode: 0644]
queue-4.4/drm-vmwgfx-fix-integer-overflow-in-vmw_surface_define_ioctl.patch [new file with mode: 0644]
queue-4.4/drm-vmwgfx-null-pointer-dereference-in-vmw_surface_define_ioctl.patch [new file with mode: 0644]
queue-4.4/drm-vmwgfx-remove-getparam-error-message.patch [new file with mode: 0644]
queue-4.4/drm-vmwgfx-type-check-lookups-of-fence-objects.patch [new file with mode: 0644]

diff --git a/queue-4.4/drm-ttm-drm-vmwgfx-relax-permission-checking-when-opening-surfaces.patch b/queue-4.4/drm-ttm-drm-vmwgfx-relax-permission-checking-when-opening-surfaces.patch
new file mode 100644 (file)
index 0000000..c6247c8
--- /dev/null
@@ -0,0 +1,172 @@
+From fe25deb7737ce6c0879ccf79c99fa1221d428bf2 Mon Sep 17 00:00:00 2001
+From: Thomas Hellstrom <thellstrom@vmware.com>
+Date: Mon, 27 Mar 2017 11:21:25 +0200
+Subject: drm/ttm, drm/vmwgfx: Relax permission checking when opening surfaces
+
+From: Thomas Hellstrom <thellstrom@vmware.com>
+
+commit fe25deb7737ce6c0879ccf79c99fa1221d428bf2 upstream.
+
+Previously, when a surface was opened using a legacy (non prime) handle,
+it was verified to have been created by a client in the same master realm.
+Relax this so that opening is also allowed recursively if the client
+already has the surface open.
+
+This works around a regression in svga mesa where opening of a shared
+surface is used recursively to obtain surface information.
+
+Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com>
+Reviewed-by: Sinclair Yeh <syeh@vmware.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/ttm/ttm_object.c         |   10 +++++++---
+ drivers/gpu/drm/vmwgfx/vmwgfx_fence.c    |    6 ++----
+ drivers/gpu/drm/vmwgfx/vmwgfx_resource.c |    4 ++--
+ drivers/gpu/drm/vmwgfx/vmwgfx_surface.c  |   22 +++++++++-------------
+ include/drm/ttm/ttm_object.h             |    5 ++++-
+ 5 files changed, 24 insertions(+), 23 deletions(-)
+
+--- a/drivers/gpu/drm/ttm/ttm_object.c
++++ b/drivers/gpu/drm/ttm/ttm_object.c
+@@ -179,7 +179,7 @@ int ttm_base_object_init(struct ttm_obje
+       if (unlikely(ret != 0))
+               goto out_err0;
+-      ret = ttm_ref_object_add(tfile, base, TTM_REF_USAGE, NULL);
++      ret = ttm_ref_object_add(tfile, base, TTM_REF_USAGE, NULL, false);
+       if (unlikely(ret != 0))
+               goto out_err1;
+@@ -318,7 +318,8 @@ EXPORT_SYMBOL(ttm_ref_object_exists);
+ int ttm_ref_object_add(struct ttm_object_file *tfile,
+                      struct ttm_base_object *base,
+-                     enum ttm_ref_type ref_type, bool *existed)
++                     enum ttm_ref_type ref_type, bool *existed,
++                     bool require_existed)
+ {
+       struct drm_open_hash *ht = &tfile->ref_hash[ref_type];
+       struct ttm_ref_object *ref;
+@@ -345,6 +346,9 @@ int ttm_ref_object_add(struct ttm_object
+               }
+               rcu_read_unlock();
++              if (require_existed)
++                      return -EPERM;
++
+               ret = ttm_mem_global_alloc(mem_glob, sizeof(*ref),
+                                          false, false);
+               if (unlikely(ret != 0))
+@@ -635,7 +639,7 @@ int ttm_prime_fd_to_handle(struct ttm_ob
+       prime = (struct ttm_prime_object *) dma_buf->priv;
+       base = &prime->base;
+       *handle = base->hash.key;
+-      ret = ttm_ref_object_add(tfile, base, TTM_REF_USAGE, NULL);
++      ret = ttm_ref_object_add(tfile, base, TTM_REF_USAGE, NULL, false);
+       dma_buf_put(dma_buf);
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c
+@@ -1144,10 +1144,8 @@ int vmw_fence_event_ioctl(struct drm_dev
+               (void) vmw_fence_obj_reference(fence);
+               if (user_fence_rep != NULL) {
+-                      bool existed;
+-
+-                      ret = ttm_ref_object_add(tfile, base,
+-                                               TTM_REF_USAGE, &existed);
++                      ret = ttm_ref_object_add(vmw_fp->tfile, base,
++                                               TTM_REF_USAGE, NULL, false);
+                       if (unlikely(ret != 0)) {
+                               DRM_ERROR("Failed to reference a fence "
+                                         "object.\n");
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c
+@@ -591,7 +591,7 @@ static int vmw_user_dmabuf_synccpu_grab(
+               return ret;
+       ret = ttm_ref_object_add(tfile, &user_bo->prime.base,
+-                               TTM_REF_SYNCCPU_WRITE, &existed);
++                               TTM_REF_SYNCCPU_WRITE, &existed, false);
+       if (ret != 0 || existed)
+               ttm_bo_synccpu_write_release(&user_bo->dma.base);
+@@ -775,7 +775,7 @@ int vmw_user_dmabuf_reference(struct ttm
+       *handle = user_bo->prime.base.hash.key;
+       return ttm_ref_object_add(tfile, &user_bo->prime.base,
+-                                TTM_REF_USAGE, NULL);
++                                TTM_REF_USAGE, NULL, false);
+ }
+ /*
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c
+@@ -904,17 +904,16 @@ vmw_surface_handle_reference(struct vmw_
+       uint32_t handle;
+       struct ttm_base_object *base;
+       int ret;
++      bool require_exist = false;
+       if (handle_type == DRM_VMW_HANDLE_PRIME) {
+               ret = ttm_prime_fd_to_handle(tfile, u_handle, &handle);
+               if (unlikely(ret != 0))
+                       return ret;
+       } else {
+-              if (unlikely(drm_is_render_client(file_priv))) {
+-                      DRM_ERROR("Render client refused legacy "
+-                                "surface reference.\n");
+-                      return -EACCES;
+-              }
++              if (unlikely(drm_is_render_client(file_priv)))
++                      require_exist = true;
++
+               if (ACCESS_ONCE(vmw_fpriv(file_priv)->locked_master)) {
+                       DRM_ERROR("Locked master refused legacy "
+                                 "surface reference.\n");
+@@ -942,17 +941,14 @@ vmw_surface_handle_reference(struct vmw_
+               /*
+                * Make sure the surface creator has the same
+-               * authenticating master.
++               * authenticating master, or is already registered with us.
+                */
+               if (drm_is_primary_client(file_priv) &&
+-                  user_srf->master != file_priv->master) {
+-                      DRM_ERROR("Trying to reference surface outside of"
+-                                " master domain.\n");
+-                      ret = -EACCES;
+-                      goto out_bad_resource;
+-              }
++                  user_srf->master != file_priv->master)
++                      require_exist = true;
+-              ret = ttm_ref_object_add(tfile, base, TTM_REF_USAGE, NULL);
++              ret = ttm_ref_object_add(tfile, base, TTM_REF_USAGE, NULL,
++                                       require_exist);
+               if (unlikely(ret != 0)) {
+                       DRM_ERROR("Could not add a reference to a surface.\n");
+                       goto out_bad_resource;
+--- a/include/drm/ttm/ttm_object.h
++++ b/include/drm/ttm/ttm_object.h
+@@ -229,6 +229,8 @@ extern void ttm_base_object_unref(struct
+  * @ref_type: The type of reference.
+  * @existed: Upon completion, indicates that an identical reference object
+  * already existed, and the refcount was upped on that object instead.
++ * @require_existed: Fail with -EPERM if an identical ref object didn't
++ * already exist.
+  *
+  * Checks that the base object is shareable and adds a ref object to it.
+  *
+@@ -243,7 +245,8 @@ extern void ttm_base_object_unref(struct
+  */
+ extern int ttm_ref_object_add(struct ttm_object_file *tfile,
+                             struct ttm_base_object *base,
+-                            enum ttm_ref_type ref_type, bool *existed);
++                            enum ttm_ref_type ref_type, bool *existed,
++                            bool require_existed);
+ extern bool ttm_ref_object_exists(struct ttm_object_file *tfile,
+                                 struct ttm_base_object *base);
diff --git a/queue-4.4/drm-vmwgfx-avoid-calling-vzalloc-with-a-0-size-in-vmw_get_cap_3d_ioctl.patch b/queue-4.4/drm-vmwgfx-avoid-calling-vzalloc-with-a-0-size-in-vmw_get_cap_3d_ioctl.patch
new file mode 100644 (file)
index 0000000..a6b90fd
--- /dev/null
@@ -0,0 +1,34 @@
+From 63774069d9527a1aeaa4aa20e929ef5e8e9ecc38 Mon Sep 17 00:00:00 2001
+From: Murray McAllister <murray.mcallister@insomniasec.com>
+Date: Mon, 27 Mar 2017 11:15:12 +0200
+Subject: drm/vmwgfx: avoid calling vzalloc with a 0 size in vmw_get_cap_3d_ioctl()
+
+From: Murray McAllister <murray.mcallister@insomniasec.com>
+
+commit 63774069d9527a1aeaa4aa20e929ef5e8e9ecc38 upstream.
+
+In vmw_get_cap_3d_ioctl(), a user can supply 0 for a size that is
+used in vzalloc(). This eventually calls dump_stack() (in warn_alloc()),
+which can leak useful addresses to dmesg.
+
+Add check to avoid a size of 0.
+
+Signed-off-by: Murray McAllister <murray.mcallister@insomniasec.com>
+Reviewed-by: Sinclair Yeh <syeh@vmware.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c
+@@ -186,7 +186,7 @@ int vmw_get_cap_3d_ioctl(struct drm_devi
+       bool gb_objects = !!(dev_priv->capabilities & SVGA_CAP_GBOBJECTS);
+       struct vmw_fpriv *vmw_fp = vmw_fpriv(file_priv);
+-      if (unlikely(arg->pad64 != 0)) {
++      if (unlikely(arg->pad64 != 0 || arg->max_size == 0)) {
+               DRM_ERROR("Illegal GET_3D_CAP argument.\n");
+               return -EINVAL;
+       }
diff --git a/queue-4.4/drm-vmwgfx-fix-integer-overflow-in-vmw_surface_define_ioctl.patch b/queue-4.4/drm-vmwgfx-fix-integer-overflow-in-vmw_surface_define_ioctl.patch
new file mode 100644 (file)
index 0000000..07d25ae
--- /dev/null
@@ -0,0 +1,39 @@
+From e7e11f99564222d82f0ce84bd521e57d78a6b678 Mon Sep 17 00:00:00 2001
+From: Li Qiang <liq3ea@gmail.com>
+Date: Mon, 27 Mar 2017 20:10:53 -0700
+Subject: drm/vmwgfx: fix integer overflow in vmw_surface_define_ioctl()
+
+From: Li Qiang <liq3ea@gmail.com>
+
+commit e7e11f99564222d82f0ce84bd521e57d78a6b678 upstream.
+
+In vmw_surface_define_ioctl(), the 'num_sizes' is the sum of the
+'req->mip_levels' array. This array can be assigned any value from
+the user space. As both the 'num_sizes' and the array is uint32_t,
+it is easy to make 'num_sizes' overflow. The later 'mip_levels' is
+used as the loop count. This can lead an oob write. Add the check of
+'req->mip_levels' to avoid this.
+
+Signed-off-by: Li Qiang <liqiang6-s@360.cn>
+Reviewed-by: Thomas Hellstrom <thellstrom@vmware.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/vmwgfx/vmwgfx_surface.c |    5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c
+@@ -715,8 +715,11 @@ int vmw_surface_define_ioctl(struct drm_
+                       128;
+       num_sizes = 0;
+-      for (i = 0; i < DRM_VMW_MAX_SURFACE_FACES; ++i)
++      for (i = 0; i < DRM_VMW_MAX_SURFACE_FACES; ++i) {
++              if (req->mip_levels[i] > DRM_VMW_MAX_MIP_LEVELS)
++                      return -EINVAL;
+               num_sizes += req->mip_levels[i];
++      }
+       if (num_sizes > DRM_VMW_MAX_SURFACE_FACES * DRM_VMW_MAX_MIP_LEVELS ||
+           num_sizes == 0)
diff --git a/queue-4.4/drm-vmwgfx-null-pointer-dereference-in-vmw_surface_define_ioctl.patch b/queue-4.4/drm-vmwgfx-null-pointer-dereference-in-vmw_surface_define_ioctl.patch
new file mode 100644 (file)
index 0000000..60710fe
--- /dev/null
@@ -0,0 +1,36 @@
+From 36274ab8c596f1240c606bb514da329add2a1bcd Mon Sep 17 00:00:00 2001
+From: Murray McAllister <murray.mcallister@insomniasec.com>
+Date: Mon, 27 Mar 2017 11:12:53 +0200
+Subject: drm/vmwgfx: NULL pointer dereference in vmw_surface_define_ioctl()
+
+From: Murray McAllister <murray.mcallister@insomniasec.com>
+
+commit 36274ab8c596f1240c606bb514da329add2a1bcd upstream.
+
+Before memory allocations vmw_surface_define_ioctl() checks the
+upper-bounds of a user-supplied size, but does not check if the
+supplied size is 0.
+
+Add check to avoid NULL pointer dereferences.
+
+Signed-off-by: Murray McAllister <murray.mcallister@insomniasec.com>
+Reviewed-by: Sinclair Yeh <syeh@vmware.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/vmwgfx/vmwgfx_surface.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c
+@@ -718,8 +718,8 @@ int vmw_surface_define_ioctl(struct drm_
+       for (i = 0; i < DRM_VMW_MAX_SURFACE_FACES; ++i)
+               num_sizes += req->mip_levels[i];
+-      if (num_sizes > DRM_VMW_MAX_SURFACE_FACES *
+-          DRM_VMW_MAX_MIP_LEVELS)
++      if (num_sizes > DRM_VMW_MAX_SURFACE_FACES * DRM_VMW_MAX_MIP_LEVELS ||
++          num_sizes == 0)
+               return -EINVAL;
+       size = vmw_user_surface_size + 128 +
diff --git a/queue-4.4/drm-vmwgfx-remove-getparam-error-message.patch b/queue-4.4/drm-vmwgfx-remove-getparam-error-message.patch
new file mode 100644 (file)
index 0000000..afba4ff
--- /dev/null
@@ -0,0 +1,33 @@
+From 53e16798b0864464c5444a204e1bb93ae246c429 Mon Sep 17 00:00:00 2001
+From: Thomas Hellstrom <thellstrom@vmware.com>
+Date: Mon, 27 Mar 2017 13:06:05 +0200
+Subject: drm/vmwgfx: Remove getparam error message
+
+From: Thomas Hellstrom <thellstrom@vmware.com>
+
+commit 53e16798b0864464c5444a204e1bb93ae246c429 upstream.
+
+The mesa winsys sometimes uses unimplemented parameter requests to
+check for features. Remove the error message to avoid bloating the
+kernel log.
+
+Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com>
+Reviewed-by: Brian Paul <brianp@vmware.com>
+Reviewed-by: Sinclair Yeh <syeh@vmware.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c |    2 --
+ 1 file changed, 2 deletions(-)
+
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c
+@@ -114,8 +114,6 @@ int vmw_getparam_ioctl(struct drm_device
+               param->value = dev_priv->has_dx;
+               break;
+       default:
+-              DRM_ERROR("Illegal vmwgfx get param request: %d\n",
+-                        param->param);
+               return -EINVAL;
+       }
diff --git a/queue-4.4/drm-vmwgfx-type-check-lookups-of-fence-objects.patch b/queue-4.4/drm-vmwgfx-type-check-lookups-of-fence-objects.patch
new file mode 100644 (file)
index 0000000..f08cda4
--- /dev/null
@@ -0,0 +1,157 @@
+From f7652afa8eadb416b23eb57dec6f158529942041 Mon Sep 17 00:00:00 2001
+From: Thomas Hellstrom <thellstrom@vmware.com>
+Date: Mon, 27 Mar 2017 11:09:08 +0200
+Subject: drm/vmwgfx: Type-check lookups of fence objects
+
+From: Thomas Hellstrom <thellstrom@vmware.com>
+
+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.
+
+Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com>
+Reviewed-by: Sinclair Yeh <syeh@vmware.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/vmwgfx/vmwgfx_fence.c |   75 ++++++++++++++++++++++------------
+ 1 file changed, 49 insertions(+), 26 deletions(-)
+
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c
+@@ -539,7 +539,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))
+@@ -702,6 +702,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)
+ {
+@@ -727,13 +762,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);
+@@ -772,13 +803,9 @@ int vmw_fence_obj_signaled_ioctl(struct
+       struct 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);
+@@ -1093,6 +1120,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;
+@@ -1106,15 +1134,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);
+@@ -1122,7 +1146,7 @@ int vmw_fence_event_ioctl(struct drm_dev
+               if (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 "
+@@ -1166,8 +1190,7 @@ int vmw_fence_event_ioctl(struct drm_dev
+       return 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;