Skip to content

Commit

Permalink
drm: mark context support as a legacy subsystem
Browse files Browse the repository at this point in the history
So after a lot of digging around in git histories it looks like this
has only ever be used by dri1 render clients. Hence we can fully
disable the entire thing for modesetting drivers and so greatly reduce
the attack surface for potential exploits (or at least tools like
trinity ...).

Also add the drm_legacy prefix for functions which are called from
common code. To further reduce the impact on common code also extract
all the ctx release handling into a function (instead of only
releasing individual handles) and make ctxbitmap_cleanup return void -
it can never fail.

Reviewed-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Dave Airlie <airlied@redhat.com>
  • Loading branch information
danvet authored and airlied committed Aug 19, 2013
1 parent 8d38c4b commit 7c51013
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 39 deletions.
73 changes: 65 additions & 8 deletions drivers/gpu/drm/drm_context.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,6 @@

#include <drm/drmP.h>

/******************************************************************/
/** \name Context bitmap support */
/*@{*/

/**
* Free a handle from the context bitmap.
*
Expand All @@ -56,13 +52,48 @@
* in drm_device::ctx_idr, while holding the drm_device::struct_mutex
* lock.
*/
void drm_ctxbitmap_free(struct drm_device * dev, int ctx_handle)
static void drm_ctxbitmap_free(struct drm_device * dev, int ctx_handle)
{
if (drm_core_check_feature(dev, DRIVER_MODESET))
return;

mutex_lock(&dev->struct_mutex);
idr_remove(&dev->ctx_idr, ctx_handle);
mutex_unlock(&dev->struct_mutex);
}

/******************************************************************/
/** \name Context bitmap support */
/*@{*/

void drm_legacy_ctxbitmap_release(struct drm_device *dev,
struct drm_file *file_priv)
{
if (drm_core_check_feature(dev, DRIVER_MODESET))
return;

mutex_lock(&dev->ctxlist_mutex);
if (!list_empty(&dev->ctxlist)) {
struct drm_ctx_list *pos, *n;

list_for_each_entry_safe(pos, n, &dev->ctxlist, head) {
if (pos->tag == file_priv &&
pos->handle != DRM_KERNEL_CONTEXT) {
if (dev->driver->context_dtor)
dev->driver->context_dtor(dev,
pos->handle);

drm_ctxbitmap_free(dev, pos->handle);

list_del(&pos->head);
kfree(pos);
--dev->ctx_count;
}
}
}
mutex_unlock(&dev->ctxlist_mutex);
}

/**
* Context bitmap allocation.
*
Expand Down Expand Up @@ -90,10 +121,12 @@ static int drm_ctxbitmap_next(struct drm_device * dev)
*
* Initialise the drm_device::ctx_idr
*/
int drm_ctxbitmap_init(struct drm_device * dev)
void drm_legacy_ctxbitmap_init(struct drm_device * dev)
{
if (drm_core_check_feature(dev, DRIVER_MODESET))
return;

idr_init(&dev->ctx_idr);
return 0;
}

/**
Expand All @@ -104,7 +137,7 @@ int drm_ctxbitmap_init(struct drm_device * dev)
* Free all idr members using drm_ctx_sarea_free helper function
* while holding the drm_device::struct_mutex lock.
*/
void drm_ctxbitmap_cleanup(struct drm_device * dev)
void drm_legacy_ctxbitmap_cleanup(struct drm_device * dev)
{
mutex_lock(&dev->struct_mutex);
idr_destroy(&dev->ctx_idr);
Expand Down Expand Up @@ -136,6 +169,9 @@ int drm_getsareactx(struct drm_device *dev, void *data,
struct drm_local_map *map;
struct drm_map_list *_entry;

if (drm_core_check_feature(dev, DRIVER_MODESET))
return -EINVAL;

mutex_lock(&dev->struct_mutex);

map = idr_find(&dev->ctx_idr, request->ctx_id);
Expand Down Expand Up @@ -180,6 +216,9 @@ int drm_setsareactx(struct drm_device *dev, void *data,
struct drm_local_map *map = NULL;
struct drm_map_list *r_list = NULL;

if (drm_core_check_feature(dev, DRIVER_MODESET))
return -EINVAL;

mutex_lock(&dev->struct_mutex);
list_for_each_entry(r_list, &dev->maplist, head) {
if (r_list->map
Expand Down Expand Up @@ -280,6 +319,9 @@ int drm_resctx(struct drm_device *dev, void *data,
struct drm_ctx ctx;
int i;

if (drm_core_check_feature(dev, DRIVER_MODESET))
return -EINVAL;

if (res->count >= DRM_RESERVED_CONTEXTS) {
memset(&ctx, 0, sizeof(ctx));
for (i = 0; i < DRM_RESERVED_CONTEXTS; i++) {
Expand Down Expand Up @@ -310,6 +352,9 @@ int drm_addctx(struct drm_device *dev, void *data,
struct drm_ctx_list *ctx_entry;
struct drm_ctx *ctx = data;

if (drm_core_check_feature(dev, DRIVER_MODESET))
return -EINVAL;

ctx->handle = drm_ctxbitmap_next(dev);
if (ctx->handle == DRM_KERNEL_CONTEXT) {
/* Skip kernel's context and get a new one. */
Expand Down Expand Up @@ -353,6 +398,9 @@ int drm_getctx(struct drm_device *dev, void *data, struct drm_file *file_priv)
{
struct drm_ctx *ctx = data;

if (drm_core_check_feature(dev, DRIVER_MODESET))
return -EINVAL;

/* This is 0, because we don't handle any context flags */
ctx->flags = 0;

Expand All @@ -375,6 +423,9 @@ int drm_switchctx(struct drm_device *dev, void *data,
{
struct drm_ctx *ctx = data;

if (drm_core_check_feature(dev, DRIVER_MODESET))
return -EINVAL;

DRM_DEBUG("%d\n", ctx->handle);
return drm_context_switch(dev, dev->last_context, ctx->handle);
}
Expand All @@ -395,6 +446,9 @@ int drm_newctx(struct drm_device *dev, void *data,
{
struct drm_ctx *ctx = data;

if (drm_core_check_feature(dev, DRIVER_MODESET))
return -EINVAL;

DRM_DEBUG("%d\n", ctx->handle);
drm_context_switch_complete(dev, file_priv, ctx->handle);

Expand All @@ -417,6 +471,9 @@ int drm_rmctx(struct drm_device *dev, void *data,
{
struct drm_ctx *ctx = data;

if (drm_core_check_feature(dev, DRIVER_MODESET))
return -EINVAL;

DRM_DEBUG("%d\n", ctx->handle);
if (ctx->handle != DRM_KERNEL_CONTEXT) {
if (dev->driver->context_dtor)
Expand Down
21 changes: 1 addition & 20 deletions drivers/gpu/drm/drm_fops.c
Original file line number Diff line number Diff line change
Expand Up @@ -474,26 +474,7 @@ int drm_release(struct inode *inode, struct file *filp)
if (dev->driver->driver_features & DRIVER_GEM)
drm_gem_release(dev, file_priv);

mutex_lock(&dev->ctxlist_mutex);
if (!list_empty(&dev->ctxlist)) {
struct drm_ctx_list *pos, *n;

list_for_each_entry_safe(pos, n, &dev->ctxlist, head) {
if (pos->tag == file_priv &&
pos->handle != DRM_KERNEL_CONTEXT) {
if (dev->driver->context_dtor)
dev->driver->context_dtor(dev,
pos->handle);

drm_ctxbitmap_free(dev, pos->handle);

list_del(&pos->head);
kfree(pos);
--dev->ctx_count;
}
}
}
mutex_unlock(&dev->ctxlist_mutex);
drm_legacy_ctxbitmap_release(dev, file_priv);

mutex_lock(&dev->struct_mutex);

Expand Down
10 changes: 2 additions & 8 deletions drivers/gpu/drm/drm_stub.c
Original file line number Diff line number Diff line change
Expand Up @@ -288,13 +288,7 @@ int drm_fill_in_dev(struct drm_device *dev,
goto error_out_unreg;
}



retcode = drm_ctxbitmap_init(dev);
if (retcode) {
DRM_ERROR("Cannot allocate memory for context bitmap.\n");
goto error_out_unreg;
}
drm_legacy_ctxbitmap_init(dev);

if (driver->driver_features & DRIVER_GEM) {
retcode = drm_gem_init(dev);
Expand Down Expand Up @@ -463,7 +457,7 @@ void drm_put_dev(struct drm_device *dev)
drm_rmmap(dev, r_list->map);
drm_ht_remove(&dev->map_hash);

drm_ctxbitmap_cleanup(dev);
drm_legacy_ctxbitmap_cleanup(dev);

if (drm_core_check_feature(dev, DRIVER_MODESET))
drm_put_minor(&dev->control);
Expand Down
7 changes: 4 additions & 3 deletions include/drm/drmP.h
Original file line number Diff line number Diff line change
Expand Up @@ -1313,9 +1313,10 @@ extern int drm_newctx(struct drm_device *dev, void *data,
extern int drm_rmctx(struct drm_device *dev, void *data,
struct drm_file *file_priv);

extern int drm_ctxbitmap_init(struct drm_device *dev);
extern void drm_ctxbitmap_cleanup(struct drm_device *dev);
extern void drm_ctxbitmap_free(struct drm_device *dev, int ctx_handle);
extern void drm_legacy_ctxbitmap_init(struct drm_device *dev);
extern void drm_legacy_ctxbitmap_cleanup(struct drm_device *dev);
extern void drm_legacy_ctxbitmap_release(struct drm_device *dev,
struct drm_file *file_priv);

extern int drm_setsareactx(struct drm_device *dev, void *data,
struct drm_file *file_priv);
Expand Down

0 comments on commit 7c51013

Please sign in to comment.