aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Vetter <daniel.vetter@ffwll.ch>2014-07-24 06:12:45 -0400
committerDave Airlie <airlied@redhat.com>2014-08-04 21:06:52 -0400
commit168c02ec06f891990617cee2abbba70858c071e7 (patch)
treebbcb2fde44a5856c61594436bbe6854559073da3
parentdff01de1c3cafb128344fe809cbca84606b1b65c (diff)
drm: Fix race when checking for fb in the generic kms obj lookup
In my review of commit 98f75de40e9d83c3a90d294b8fd25fa2874212a9 Author: Rob Clark <robdclark@gmail.com> Date: Fri May 30 11:37:03 2014 -0400 drm: add object property typ I asked for a check to make sure that we never leak an fb from the generic mode object lookup since those have completely different lifetime rules. Rob added it, but outside of the idr mutex, which means that our dereference of obj->type can already chase free'd memory. Somehow I didn't spot this, so fix this asap. v2: Simplify the conditionals as suggested by Chris. Cc: Rob Clark <robdclark@gmail.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch> Reviewed-by: Rob Clark <robdclark@gmail.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
-rw-r--r--drivers/gpu/drm/drm_crtc.c11
1 files changed, 6 insertions, 5 deletions
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 3c4a62169f28..fa2be249999c 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -446,8 +446,12 @@ static struct drm_mode_object *_object_find(struct drm_device *dev,
446 446
447 mutex_lock(&dev->mode_config.idr_mutex); 447 mutex_lock(&dev->mode_config.idr_mutex);
448 obj = idr_find(&dev->mode_config.crtc_idr, id); 448 obj = idr_find(&dev->mode_config.crtc_idr, id);
449 if (!obj || (type != DRM_MODE_OBJECT_ANY && obj->type != type) || 449 if (obj && type != DRM_MODE_OBJECT_ANY && obj->type != type)
450 (obj->id != id)) 450 obj = NULL;
451 if (obj && obj->id != id)
452 obj = NULL;
453 /* don't leak out unref'd fb's */
454 if (obj && (obj->type == DRM_MODE_OBJECT_FB))
451 obj = NULL; 455 obj = NULL;
452 mutex_unlock(&dev->mode_config.idr_mutex); 456 mutex_unlock(&dev->mode_config.idr_mutex);
453 457
@@ -474,9 +478,6 @@ struct drm_mode_object *drm_mode_object_find(struct drm_device *dev,
474 * function.*/ 478 * function.*/
475 WARN_ON(type == DRM_MODE_OBJECT_FB); 479 WARN_ON(type == DRM_MODE_OBJECT_FB);
476 obj = _object_find(dev, id, type); 480 obj = _object_find(dev, id, type);
477 /* don't leak out unref'd fb's */
478 if (obj && (obj->type == DRM_MODE_OBJECT_FB))
479 obj = NULL;
480 return obj; 481 return obj;
481} 482}
482EXPORT_SYMBOL(drm_mode_object_find); 483EXPORT_SYMBOL(drm_mode_object_find);