aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Vetter <daniel.vetter@ffwll.ch>2013-08-08 09:41:21 -0400
committerDave Airlie <airlied@redhat.com>2013-08-18 20:04:48 -0400
commit7c510133d93dd6f15ca040733ba7b2891ed61fd1 (patch)
tree82c22a7ef8058c7a1c212e89fb6156eaad3fa19e
parent8d38c4b4371b8f9d1d72737c880cdae14b024142 (diff)
drm: mark context support as a legacy subsystem
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>
-rw-r--r--drivers/gpu/drm/drm_context.c73
-rw-r--r--drivers/gpu/drm/drm_fops.c21
-rw-r--r--drivers/gpu/drm/drm_stub.c10
-rw-r--r--include/drm/drmP.h7
4 files changed, 72 insertions, 39 deletions
diff --git a/drivers/gpu/drm/drm_context.c b/drivers/gpu/drm/drm_context.c
index 224ff965bcf7..b4fb86d89850 100644
--- a/drivers/gpu/drm/drm_context.c
+++ b/drivers/gpu/drm/drm_context.c
@@ -42,10 +42,6 @@
42 42
43#include <drm/drmP.h> 43#include <drm/drmP.h>
44 44
45/******************************************************************/
46/** \name Context bitmap support */
47/*@{*/
48
49/** 45/**
50 * Free a handle from the context bitmap. 46 * Free a handle from the context bitmap.
51 * 47 *
@@ -56,13 +52,48 @@
56 * in drm_device::ctx_idr, while holding the drm_device::struct_mutex 52 * in drm_device::ctx_idr, while holding the drm_device::struct_mutex
57 * lock. 53 * lock.
58 */ 54 */
59void drm_ctxbitmap_free(struct drm_device * dev, int ctx_handle) 55static void drm_ctxbitmap_free(struct drm_device * dev, int ctx_handle)
60{ 56{
57 if (drm_core_check_feature(dev, DRIVER_MODESET))
58 return;
59
61 mutex_lock(&dev->struct_mutex); 60 mutex_lock(&dev->struct_mutex);
62 idr_remove(&dev->ctx_idr, ctx_handle); 61 idr_remove(&dev->ctx_idr, ctx_handle);
63 mutex_unlock(&dev->struct_mutex); 62 mutex_unlock(&dev->struct_mutex);
64} 63}
65 64
65/******************************************************************/
66/** \name Context bitmap support */
67/*@{*/
68
69void drm_legacy_ctxbitmap_release(struct drm_device *dev,
70 struct drm_file *file_priv)
71{
72 if (drm_core_check_feature(dev, DRIVER_MODESET))
73 return;
74
75 mutex_lock(&dev->ctxlist_mutex);
76 if (!list_empty(&dev->ctxlist)) {
77 struct drm_ctx_list *pos, *n;
78
79 list_for_each_entry_safe(pos, n, &dev->ctxlist, head) {
80 if (pos->tag == file_priv &&
81 pos->handle != DRM_KERNEL_CONTEXT) {
82 if (dev->driver->context_dtor)
83 dev->driver->context_dtor(dev,
84 pos->handle);
85
86 drm_ctxbitmap_free(dev, pos->handle);
87
88 list_del(&pos->head);
89 kfree(pos);
90 --dev->ctx_count;
91 }
92 }
93 }
94 mutex_unlock(&dev->ctxlist_mutex);
95}
96
66/** 97/**
67 * Context bitmap allocation. 98 * Context bitmap allocation.
68 * 99 *
@@ -90,10 +121,12 @@ static int drm_ctxbitmap_next(struct drm_device * dev)
90 * 121 *
91 * Initialise the drm_device::ctx_idr 122 * Initialise the drm_device::ctx_idr
92 */ 123 */
93int drm_ctxbitmap_init(struct drm_device * dev) 124void drm_legacy_ctxbitmap_init(struct drm_device * dev)
94{ 125{
126 if (drm_core_check_feature(dev, DRIVER_MODESET))
127 return;
128
95 idr_init(&dev->ctx_idr); 129 idr_init(&dev->ctx_idr);
96 return 0;
97} 130}
98 131
99/** 132/**
@@ -104,7 +137,7 @@ int drm_ctxbitmap_init(struct drm_device * dev)
104 * Free all idr members using drm_ctx_sarea_free helper function 137 * Free all idr members using drm_ctx_sarea_free helper function
105 * while holding the drm_device::struct_mutex lock. 138 * while holding the drm_device::struct_mutex lock.
106 */ 139 */
107void drm_ctxbitmap_cleanup(struct drm_device * dev) 140void drm_legacy_ctxbitmap_cleanup(struct drm_device * dev)
108{ 141{
109 mutex_lock(&dev->struct_mutex); 142 mutex_lock(&dev->struct_mutex);
110 idr_destroy(&dev->ctx_idr); 143 idr_destroy(&dev->ctx_idr);
@@ -136,6 +169,9 @@ int drm_getsareactx(struct drm_device *dev, void *data,
136 struct drm_local_map *map; 169 struct drm_local_map *map;
137 struct drm_map_list *_entry; 170 struct drm_map_list *_entry;
138 171
172 if (drm_core_check_feature(dev, DRIVER_MODESET))
173 return -EINVAL;
174
139 mutex_lock(&dev->struct_mutex); 175 mutex_lock(&dev->struct_mutex);
140 176
141 map = idr_find(&dev->ctx_idr, request->ctx_id); 177 map = idr_find(&dev->ctx_idr, request->ctx_id);
@@ -180,6 +216,9 @@ int drm_setsareactx(struct drm_device *dev, void *data,
180 struct drm_local_map *map = NULL; 216 struct drm_local_map *map = NULL;
181 struct drm_map_list *r_list = NULL; 217 struct drm_map_list *r_list = NULL;
182 218
219 if (drm_core_check_feature(dev, DRIVER_MODESET))
220 return -EINVAL;
221
183 mutex_lock(&dev->struct_mutex); 222 mutex_lock(&dev->struct_mutex);
184 list_for_each_entry(r_list, &dev->maplist, head) { 223 list_for_each_entry(r_list, &dev->maplist, head) {
185 if (r_list->map 224 if (r_list->map
@@ -280,6 +319,9 @@ int drm_resctx(struct drm_device *dev, void *data,
280 struct drm_ctx ctx; 319 struct drm_ctx ctx;
281 int i; 320 int i;
282 321
322 if (drm_core_check_feature(dev, DRIVER_MODESET))
323 return -EINVAL;
324
283 if (res->count >= DRM_RESERVED_CONTEXTS) { 325 if (res->count >= DRM_RESERVED_CONTEXTS) {
284 memset(&ctx, 0, sizeof(ctx)); 326 memset(&ctx, 0, sizeof(ctx));
285 for (i = 0; i < DRM_RESERVED_CONTEXTS; i++) { 327 for (i = 0; i < DRM_RESERVED_CONTEXTS; i++) {
@@ -310,6 +352,9 @@ int drm_addctx(struct drm_device *dev, void *data,
310 struct drm_ctx_list *ctx_entry; 352 struct drm_ctx_list *ctx_entry;
311 struct drm_ctx *ctx = data; 353 struct drm_ctx *ctx = data;
312 354
355 if (drm_core_check_feature(dev, DRIVER_MODESET))
356 return -EINVAL;
357
313 ctx->handle = drm_ctxbitmap_next(dev); 358 ctx->handle = drm_ctxbitmap_next(dev);
314 if (ctx->handle == DRM_KERNEL_CONTEXT) { 359 if (ctx->handle == DRM_KERNEL_CONTEXT) {
315 /* Skip kernel's context and get a new one. */ 360 /* Skip kernel's context and get a new one. */
@@ -353,6 +398,9 @@ int drm_getctx(struct drm_device *dev, void *data, struct drm_file *file_priv)
353{ 398{
354 struct drm_ctx *ctx = data; 399 struct drm_ctx *ctx = data;
355 400
401 if (drm_core_check_feature(dev, DRIVER_MODESET))
402 return -EINVAL;
403
356 /* This is 0, because we don't handle any context flags */ 404 /* This is 0, because we don't handle any context flags */
357 ctx->flags = 0; 405 ctx->flags = 0;
358 406
@@ -375,6 +423,9 @@ int drm_switchctx(struct drm_device *dev, void *data,
375{ 423{
376 struct drm_ctx *ctx = data; 424 struct drm_ctx *ctx = data;
377 425
426 if (drm_core_check_feature(dev, DRIVER_MODESET))
427 return -EINVAL;
428
378 DRM_DEBUG("%d\n", ctx->handle); 429 DRM_DEBUG("%d\n", ctx->handle);
379 return drm_context_switch(dev, dev->last_context, ctx->handle); 430 return drm_context_switch(dev, dev->last_context, ctx->handle);
380} 431}
@@ -395,6 +446,9 @@ int drm_newctx(struct drm_device *dev, void *data,
395{ 446{
396 struct drm_ctx *ctx = data; 447 struct drm_ctx *ctx = data;
397 448
449 if (drm_core_check_feature(dev, DRIVER_MODESET))
450 return -EINVAL;
451
398 DRM_DEBUG("%d\n", ctx->handle); 452 DRM_DEBUG("%d\n", ctx->handle);
399 drm_context_switch_complete(dev, file_priv, ctx->handle); 453 drm_context_switch_complete(dev, file_priv, ctx->handle);
400 454
@@ -417,6 +471,9 @@ int drm_rmctx(struct drm_device *dev, void *data,
417{ 471{
418 struct drm_ctx *ctx = data; 472 struct drm_ctx *ctx = data;
419 473
474 if (drm_core_check_feature(dev, DRIVER_MODESET))
475 return -EINVAL;
476
420 DRM_DEBUG("%d\n", ctx->handle); 477 DRM_DEBUG("%d\n", ctx->handle);
421 if (ctx->handle != DRM_KERNEL_CONTEXT) { 478 if (ctx->handle != DRM_KERNEL_CONTEXT) {
422 if (dev->driver->context_dtor) 479 if (dev->driver->context_dtor)
diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c
index f343234bd831..10334999f229 100644
--- a/drivers/gpu/drm/drm_fops.c
+++ b/drivers/gpu/drm/drm_fops.c
@@ -474,26 +474,7 @@ int drm_release(struct inode *inode, struct file *filp)
474 if (dev->driver->driver_features & DRIVER_GEM) 474 if (dev->driver->driver_features & DRIVER_GEM)
475 drm_gem_release(dev, file_priv); 475 drm_gem_release(dev, file_priv);
476 476
477 mutex_lock(&dev->ctxlist_mutex); 477 drm_legacy_ctxbitmap_release(dev, file_priv);
478 if (!list_empty(&dev->ctxlist)) {
479 struct drm_ctx_list *pos, *n;
480
481 list_for_each_entry_safe(pos, n, &dev->ctxlist, head) {
482 if (pos->tag == file_priv &&
483 pos->handle != DRM_KERNEL_CONTEXT) {
484 if (dev->driver->context_dtor)
485 dev->driver->context_dtor(dev,
486 pos->handle);
487
488 drm_ctxbitmap_free(dev, pos->handle);
489
490 list_del(&pos->head);
491 kfree(pos);
492 --dev->ctx_count;
493 }
494 }
495 }
496 mutex_unlock(&dev->ctxlist_mutex);
497 478
498 mutex_lock(&dev->struct_mutex); 479 mutex_lock(&dev->struct_mutex);
499 480
diff --git a/drivers/gpu/drm/drm_stub.c b/drivers/gpu/drm/drm_stub.c
index d663f7d66dab..aa0664d91060 100644
--- a/drivers/gpu/drm/drm_stub.c
+++ b/drivers/gpu/drm/drm_stub.c
@@ -288,13 +288,7 @@ int drm_fill_in_dev(struct drm_device *dev,
288 goto error_out_unreg; 288 goto error_out_unreg;
289 } 289 }
290 290
291 291 drm_legacy_ctxbitmap_init(dev);
292
293 retcode = drm_ctxbitmap_init(dev);
294 if (retcode) {
295 DRM_ERROR("Cannot allocate memory for context bitmap.\n");
296 goto error_out_unreg;
297 }
298 292
299 if (driver->driver_features & DRIVER_GEM) { 293 if (driver->driver_features & DRIVER_GEM) {
300 retcode = drm_gem_init(dev); 294 retcode = drm_gem_init(dev);
@@ -463,7 +457,7 @@ void drm_put_dev(struct drm_device *dev)
463 drm_rmmap(dev, r_list->map); 457 drm_rmmap(dev, r_list->map);
464 drm_ht_remove(&dev->map_hash); 458 drm_ht_remove(&dev->map_hash);
465 459
466 drm_ctxbitmap_cleanup(dev); 460 drm_legacy_ctxbitmap_cleanup(dev);
467 461
468 if (drm_core_check_feature(dev, DRIVER_MODESET)) 462 if (drm_core_check_feature(dev, DRIVER_MODESET))
469 drm_put_minor(&dev->control); 463 drm_put_minor(&dev->control);
diff --git a/include/drm/drmP.h b/include/drm/drmP.h
index 1da25304c289..277f307e053d 100644
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -1313,9 +1313,10 @@ extern int drm_newctx(struct drm_device *dev, void *data,
1313extern int drm_rmctx(struct drm_device *dev, void *data, 1313extern int drm_rmctx(struct drm_device *dev, void *data,
1314 struct drm_file *file_priv); 1314 struct drm_file *file_priv);
1315 1315
1316extern int drm_ctxbitmap_init(struct drm_device *dev); 1316extern void drm_legacy_ctxbitmap_init(struct drm_device *dev);
1317extern void drm_ctxbitmap_cleanup(struct drm_device *dev); 1317extern void drm_legacy_ctxbitmap_cleanup(struct drm_device *dev);
1318extern void drm_ctxbitmap_free(struct drm_device *dev, int ctx_handle); 1318extern void drm_legacy_ctxbitmap_release(struct drm_device *dev,
1319 struct drm_file *file_priv);
1319 1320
1320extern int drm_setsareactx(struct drm_device *dev, void *data, 1321extern int drm_setsareactx(struct drm_device *dev, void *data,
1321 struct drm_file *file_priv); 1322 struct drm_file *file_priv);