Skip to content

Commit ad4ae2f

Browse files
thomashvmwgregkh
authored andcommitted
drm/ttm, drm/vmwgfx: Relax permission checking when opening surfaces
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>
1 parent 0e075f2 commit ad4ae2f

5 files changed

Lines changed: 24 additions & 23 deletions

File tree

drivers/gpu/drm/ttm/ttm_object.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ int ttm_base_object_init(struct ttm_object_file *tfile,
179179
if (unlikely(ret != 0))
180180
goto out_err0;
181181

182-
ret = ttm_ref_object_add(tfile, base, TTM_REF_USAGE, NULL);
182+
ret = ttm_ref_object_add(tfile, base, TTM_REF_USAGE, NULL, false);
183183
if (unlikely(ret != 0))
184184
goto out_err1;
185185

@@ -318,7 +318,8 @@ EXPORT_SYMBOL(ttm_ref_object_exists);
318318

319319
int ttm_ref_object_add(struct ttm_object_file *tfile,
320320
struct ttm_base_object *base,
321-
enum ttm_ref_type ref_type, bool *existed)
321+
enum ttm_ref_type ref_type, bool *existed,
322+
bool require_existed)
322323
{
323324
struct drm_open_hash *ht = &tfile->ref_hash[ref_type];
324325
struct ttm_ref_object *ref;
@@ -345,6 +346,9 @@ int ttm_ref_object_add(struct ttm_object_file *tfile,
345346
}
346347

347348
rcu_read_unlock();
349+
if (require_existed)
350+
return -EPERM;
351+
348352
ret = ttm_mem_global_alloc(mem_glob, sizeof(*ref),
349353
false, false);
350354
if (unlikely(ret != 0))
@@ -635,7 +639,7 @@ int ttm_prime_fd_to_handle(struct ttm_object_file *tfile,
635639
prime = (struct ttm_prime_object *) dma_buf->priv;
636640
base = &prime->base;
637641
*handle = base->hash.key;
638-
ret = ttm_ref_object_add(tfile, base, TTM_REF_USAGE, NULL);
642+
ret = ttm_ref_object_add(tfile, base, TTM_REF_USAGE, NULL, false);
639643

640644
dma_buf_put(dma_buf);
641645

drivers/gpu/drm/vmwgfx/vmwgfx_fence.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1144,10 +1144,8 @@ int vmw_fence_event_ioctl(struct drm_device *dev, void *data,
11441144
(void) vmw_fence_obj_reference(fence);
11451145

11461146
if (user_fence_rep != NULL) {
1147-
bool existed;
1148-
1149-
ret = ttm_ref_object_add(tfile, base,
1150-
TTM_REF_USAGE, &existed);
1147+
ret = ttm_ref_object_add(vmw_fp->tfile, base,
1148+
TTM_REF_USAGE, NULL, false);
11511149
if (unlikely(ret != 0)) {
11521150
DRM_ERROR("Failed to reference a fence "
11531151
"object.\n");

drivers/gpu/drm/vmwgfx/vmwgfx_resource.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -591,7 +591,7 @@ static int vmw_user_dmabuf_synccpu_grab(struct vmw_user_dma_buffer *user_bo,
591591
return ret;
592592

593593
ret = ttm_ref_object_add(tfile, &user_bo->prime.base,
594-
TTM_REF_SYNCCPU_WRITE, &existed);
594+
TTM_REF_SYNCCPU_WRITE, &existed, false);
595595
if (ret != 0 || existed)
596596
ttm_bo_synccpu_write_release(&user_bo->dma.base);
597597

@@ -775,7 +775,7 @@ int vmw_user_dmabuf_reference(struct ttm_object_file *tfile,
775775

776776
*handle = user_bo->prime.base.hash.key;
777777
return ttm_ref_object_add(tfile, &user_bo->prime.base,
778-
TTM_REF_USAGE, NULL);
778+
TTM_REF_USAGE, NULL, false);
779779
}
780780

781781
/*

drivers/gpu/drm/vmwgfx/vmwgfx_surface.c

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -904,17 +904,16 @@ vmw_surface_handle_reference(struct vmw_private *dev_priv,
904904
uint32_t handle;
905905
struct ttm_base_object *base;
906906
int ret;
907+
bool require_exist = false;
907908

908909
if (handle_type == DRM_VMW_HANDLE_PRIME) {
909910
ret = ttm_prime_fd_to_handle(tfile, u_handle, &handle);
910911
if (unlikely(ret != 0))
911912
return ret;
912913
} else {
913-
if (unlikely(drm_is_render_client(file_priv))) {
914-
DRM_ERROR("Render client refused legacy "
915-
"surface reference.\n");
916-
return -EACCES;
917-
}
914+
if (unlikely(drm_is_render_client(file_priv)))
915+
require_exist = true;
916+
918917
if (ACCESS_ONCE(vmw_fpriv(file_priv)->locked_master)) {
919918
DRM_ERROR("Locked master refused legacy "
920919
"surface reference.\n");
@@ -942,17 +941,14 @@ vmw_surface_handle_reference(struct vmw_private *dev_priv,
942941

943942
/*
944943
* Make sure the surface creator has the same
945-
* authenticating master.
944+
* authenticating master, or is already registered with us.
946945
*/
947946
if (drm_is_primary_client(file_priv) &&
948-
user_srf->master != file_priv->master) {
949-
DRM_ERROR("Trying to reference surface outside of"
950-
" master domain.\n");
951-
ret = -EACCES;
952-
goto out_bad_resource;
953-
}
947+
user_srf->master != file_priv->master)
948+
require_exist = true;
954949

955-
ret = ttm_ref_object_add(tfile, base, TTM_REF_USAGE, NULL);
950+
ret = ttm_ref_object_add(tfile, base, TTM_REF_USAGE, NULL,
951+
require_exist);
956952
if (unlikely(ret != 0)) {
957953
DRM_ERROR("Could not add a reference to a surface.\n");
958954
goto out_bad_resource;

include/drm/ttm/ttm_object.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,8 @@ extern void ttm_base_object_unref(struct ttm_base_object **p_base);
229229
* @ref_type: The type of reference.
230230
* @existed: Upon completion, indicates that an identical reference object
231231
* already existed, and the refcount was upped on that object instead.
232+
* @require_existed: Fail with -EPERM if an identical ref object didn't
233+
* already exist.
232234
*
233235
* Checks that the base object is shareable and adds a ref object to it.
234236
*
@@ -243,7 +245,8 @@ extern void ttm_base_object_unref(struct ttm_base_object **p_base);
243245
*/
244246
extern int ttm_ref_object_add(struct ttm_object_file *tfile,
245247
struct ttm_base_object *base,
246-
enum ttm_ref_type ref_type, bool *existed);
248+
enum ttm_ref_type ref_type, bool *existed,
249+
bool require_existed);
247250

248251
extern bool ttm_ref_object_exists(struct ttm_object_file *tfile,
249252
struct ttm_base_object *base);

0 commit comments

Comments
 (0)