mirror of
https://github.com/torvalds/linux.git
synced 2024-11-22 12:11:40 +00:00
drm/ttm, drm/vmwgfx: Relax permission checking when opening surfaces
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. Cc: <stable@vger.kernel.org> Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com> Reviewed-by: Sinclair Yeh <syeh@vmware.com>
This commit is contained in:
parent
63774069d9
commit
fe25deb773
@ -179,7 +179,7 @@ int ttm_base_object_init(struct ttm_object_file *tfile,
|
||||
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_file *tfile,
|
||||
}
|
||||
|
||||
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_object_file *tfile,
|
||||
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);
|
||||
|
||||
|
@ -1075,10 +1075,8 @@ int vmw_fence_event_ioctl(struct drm_device *dev, void *data,
|
||||
(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");
|
||||
|
@ -589,7 +589,7 @@ static int vmw_user_dmabuf_synccpu_grab(struct vmw_user_dma_buffer *user_bo,
|
||||
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);
|
||||
|
||||
@ -773,7 +773,7 @@ int vmw_user_dmabuf_reference(struct ttm_object_file *tfile,
|
||||
|
||||
*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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -891,17 +891,16 @@ vmw_surface_handle_reference(struct vmw_private *dev_priv,
|
||||
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");
|
||||
@ -929,17 +928,14 @@ vmw_surface_handle_reference(struct vmw_private *dev_priv,
|
||||
|
||||
/*
|
||||
* 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;
|
||||
|
@ -229,6 +229,8 @@ extern void ttm_base_object_unref(struct ttm_base_object **p_base);
|
||||
* @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 ttm_base_object **p_base);
|
||||
*/
|
||||
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);
|
||||
|
Loading…
Reference in New Issue
Block a user