Skip to content

Commit

Permalink
drm/vmwgfx: Tighten security around surface sharing v2
Browse files Browse the repository at this point in the history
If using legacy (non-prime) surface sharing, only allow surfaces
to be shared between clients with the same master. This will block
malicious clients from peeking at contents at surfaces from other
(possibly vt-switched) masters.

v2:
s/legacy_client/primary_client/

Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com>
Reviewed-by: Brian Paul <brianp@vmware.com>
  • Loading branch information
Thomas Hellstrom committed Mar 28, 2014
1 parent adebcb2 commit 6d10aab
Showing 1 changed file with 24 additions and 0 deletions.
24 changes: 24 additions & 0 deletions drivers/gpu/drm/vmwgfx/vmwgfx_surface.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,13 @@
* @base: The TTM base object handling user-space visibility.
* @srf: The surface metadata.
* @size: TTM accounting size for the surface.
* @master: master of the creating client. Used for security check.
*/
struct vmw_user_surface {
struct ttm_prime_object prime;
struct vmw_surface srf;
uint32_t size;
struct drm_master *master;
};

/**
Expand Down Expand Up @@ -624,6 +626,8 @@ static void vmw_user_surface_free(struct vmw_resource *res)
struct vmw_private *dev_priv = srf->res.dev_priv;
uint32_t size = user_srf->size;

if (user_srf->master)
drm_master_put(&user_srf->master);
kfree(srf->offsets);
kfree(srf->sizes);
kfree(srf->snooper.image);
Expand Down Expand Up @@ -819,6 +823,8 @@ int vmw_surface_define_ioctl(struct drm_device *dev, void *data,

user_srf->prime.base.shareable = false;
user_srf->prime.base.tfile = NULL;
if (drm_is_primary_client(file_priv))
user_srf->master = drm_master_get(file_priv->master);

/**
* From this point, the generic resource management functions
Expand Down Expand Up @@ -885,6 +891,7 @@ vmw_surface_handle_reference(struct vmw_private *dev_priv,
struct ttm_base_object **base_p)
{
struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile;
struct vmw_user_surface *user_srf;
uint32_t handle;
struct ttm_base_object *base;
int ret;
Expand Down Expand Up @@ -915,6 +922,21 @@ vmw_surface_handle_reference(struct vmw_private *dev_priv,
}

if (handle_type != DRM_VMW_HANDLE_PRIME) {
user_srf = container_of(base, struct vmw_user_surface,
prime.base);

/*
* Make sure the surface creator has the same
* authenticating master.
*/
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;
}

ret = ttm_ref_object_add(tfile, base, TTM_REF_USAGE, NULL);
if (unlikely(ret != 0)) {
DRM_ERROR("Could not add a reference to a surface.\n");
Expand Down Expand Up @@ -1273,6 +1295,8 @@ int vmw_gb_surface_define_ioctl(struct drm_device *dev, void *data,

user_srf->prime.base.shareable = false;
user_srf->prime.base.tfile = NULL;
if (drm_is_primary_client(file_priv))
user_srf->master = drm_master_get(file_priv->master);

/**
* From this point, the generic resource management functions
Expand Down

0 comments on commit 6d10aab

Please sign in to comment.