summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Vetter <daniel.vetter@ffwll.ch>2014-07-24 12:08:52 +0200
committerDaniel Vetter <daniel.vetter@ffwll.ch>2014-08-05 15:54:13 +0200
commit82a1f64963fa58749b28b39b7ad64140dc2df8cb (patch)
treebbcb2fde44a5856c61594436bbe6854559073da3
parentbadfb904f82f8fc82e4f23ca990f09f9a8a8a41c (diff)
drm: Fix race when checking for fb in the generic kms obj lookuptopic/core-stuff-2014-08-05
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> Reviewed-by: Rob Clark <robdclark@gmail.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
-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,
mutex_lock(&dev->mode_config.idr_mutex);
obj = idr_find(&dev->mode_config.crtc_idr, id);
- if (!obj || (type != DRM_MODE_OBJECT_ANY && obj->type != type) ||
- (obj->id != id))
+ if (obj && type != DRM_MODE_OBJECT_ANY && obj->type != type)
+ obj = NULL;
+ if (obj && obj->id != id)
+ obj = NULL;
+ /* don't leak out unref'd fb's */
+ if (obj && (obj->type == DRM_MODE_OBJECT_FB))
obj = NULL;
mutex_unlock(&dev->mode_config.idr_mutex);
@@ -474,9 +478,6 @@ struct drm_mode_object *drm_mode_object_find(struct drm_device *dev,
* function.*/
WARN_ON(type == DRM_MODE_OBJECT_FB);
obj = _object_find(dev, id, type);
- /* don't leak out unref'd fb's */
- if (obj && (obj->type == DRM_MODE_OBJECT_FB))
- obj = NULL;
return obj;
}
EXPORT_SYMBOL(drm_mode_object_find);