From mboxrd@z Thu Jan 1 00:00:00 1970 From: Mario Kleiner Subject: [PATCH 3/3] drm: Use vblank_disable_and_save in drm_vblank_cleanup() Date: Wed, 6 Aug 2014 03:22:46 +0200 Message-ID: <1407288166-19881-4-git-send-email-mario.kleiner.de@gmail.com> References: <1407288166-19881-1-git-send-email-mario.kleiner.de@gmail.com> Return-path: In-Reply-To: <1407288166-19881-1-git-send-email-mario.kleiner.de@gmail.com> Sender: stable-owner@vger.kernel.org To: dri-devel@lists.freedesktop.org Cc: airlied@redhat.com, mario.kleiner.de@gmail.com, stable@vger.kernel.org List-Id: dri-devel@lists.freedesktop.org Calling vblank_disable_fn() will cause that function to no-op if !dev->vblank_disable_allowed for some kms drivers, e.g., on nouveau-kms. This can cause the gpu vblank irq's to not get disabled before freeing the dev->vblank array, so if a vblank irq fires and calls into drm_handle_vblank() after drm_vblank_cleanup() completes, it will cause use-after-free access to dev->vblank array. Call vblank_disable_and_save unconditionally, so vblank irqs are guaranteed to be off, before we delete the data structures on which they operate. Signed-off-by: Mario Kleiner Cc: stable@vger.kernel.org --- drivers/gpu/drm/drm_irq.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index 89e91e3..22e2bba9 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c @@ -164,6 +164,7 @@ static void vblank_disable_fn(unsigned long arg) void drm_vblank_cleanup(struct drm_device *dev) { int crtc; + unsigned long irqflags; /* Bail if the driver didn't call drm_vblank_init() */ if (dev->num_crtcs == 0) @@ -171,7 +172,9 @@ void drm_vblank_cleanup(struct drm_device *dev) for (crtc = 0; crtc < dev->num_crtcs; crtc++) { del_timer_sync(&dev->vblank[crtc].disable_timer); - vblank_disable_fn((unsigned long)&dev->vblank[crtc]); + spin_lock_irqsave(&dev->vbl_lock, irqflags); + vblank_disable_and_save(dev, crtc); + spin_unlock_irqrestore(&dev->vbl_lock, irqflags); } kfree(dev->vblank); -- 1.9.1