• Daniel Vetter's avatar
    drm/atomic: Fix potential use-after-free in nonblocking commits · 4e076c73
    Daniel Vetter authored
    This requires a bit of background.  Properly done a modeset driver's
    unload/remove sequence should be
    
    	drm_dev_unplug();
    	drm_atomic_helper_shutdown();
    	drm_dev_put();
    
    The trouble is that the drm_dev_unplugged() checks are by design racy,
    they do not synchronize against all outstanding ioctl.  This is because
    those ioctl could block forever (both for modeset and for driver
    specific ioctls), leading to deadlocks in hotunplug.  Instead the code
    sections that touch the hardware need to be annotated with
    drm_dev_enter/exit, to avoid accessing hardware resources after the
    unload/remove has finished.
    
    To avoid use-after-free issues all the involved userspace visible
    objects are supposed to hold a reference on the underlying drm_device,
    like drm_file does.
    
    The issue now is that we missed one, the atomic modeset ioctl can be run
    in a nonblocking fashion, and in that case it cannot rely on the implied
    drm_device reference provided by the ioctl calling context.  This can
    result in a use-after-free if an nonblocking atomic commit is carefully
    raced against a driver unload.
    
    Fix this by unconditionally grabbing a drm_device reference for any
    drm_atomic_state structures.  Strictly speaking this isn't required for
    blocking commits and TEST_ONLY calls, but it's the simpler approach.
    
    Thanks to shanzhulig for the initial idea of grabbing an unconditional
    reference, I just added comments, a condensed commit message and fixed a
    minor potential issue in where exactly we drop the final reference.
    Reported-by: default avatarshanzhulig <shanzhulig@gmail.com>
    Suggested-by: default avatarshanzhulig <shanzhulig@gmail.com>
    Reviewed-by: default avatarMaxime Ripard <mripard@kernel.org>
    Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
    Cc: Thomas Zimmermann <tzimmermann@suse.de>
    Cc: David Airlie <airlied@gmail.com>
    Cc: stable@kernel.org
    Signed-off-by: default avatarDaniel Vetter <daniel.vetter@intel.com>
    Signed-off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
    Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
    4e076c73
drm_atomic.c 56.4 KB