Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Daniel Vetter and committed by
Dave Airlie
168c02ec dff01de1

+6 -5
+6 -5
drivers/gpu/drm/drm_crtc.c
··· 446 446 447 447 mutex_lock(&dev->mode_config.idr_mutex); 448 448 obj = idr_find(&dev->mode_config.crtc_idr, id); 449 - if (!obj || (type != DRM_MODE_OBJECT_ANY && obj->type != type) || 450 - (obj->id != id)) 449 + if (obj && type != DRM_MODE_OBJECT_ANY && obj->type != type) 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 455 obj = NULL; 452 456 mutex_unlock(&dev->mode_config.idr_mutex); 453 457 ··· 478 474 * function.*/ 479 475 WARN_ON(type == DRM_MODE_OBJECT_FB); 480 476 obj = _object_find(dev, id, type); 481 - /* don't leak out unref'd fb's */ 482 - if (obj && (obj->type == DRM_MODE_OBJECT_FB)) 483 - obj = NULL; 484 477 return obj; 485 478 } 486 479 EXPORT_SYMBOL(drm_mode_object_find);