drm: fix send_vblank_event use-after-free error

The drm_pending_event can be freed by drm_send_event_locked, as a
result we should call trace_drm_vblank_event_delivered before this
to avoid hitting a user-after-free error when accessing the pid member:

[  378.438497] BUG: KASAN: use-after-free in send_vblank_event+0xf0/0x310 [drm] at addr ffff8801ac7e50a0
[  378.438500] Read of size 4 by task Xorg/1562
[  378.438501] =============================================================================
[  378.438504] BUG kmalloc-128 (Tainted: G    B          ): kasan: bad access detected
[  378.438506] -----------------------------------------------------------------------------

[  378.438509] INFO: Freed in 0x10001309c age=18446737369265680575 cpu=0 pid=0
[  378.438541]  drm_send_event_locked+0x207/0x2f0 [drm]
[  378.438544]  __slab_free+0x24c/0x650
[  378.438546]  kfree+0x3a2/0x760
[  378.438578]  drm_send_event_locked+0x207/0x2f0 [drm]
[  378.438610]  send_vblank_event+0xb7/0x310 [drm]
[  378.438643]  drm_crtc_send_vblank_event+0x130/0x1f0 [drm]
[  378.438722]  intel_atomic_commit_tail+0x23b5/0x53f0 [i915]
[  378.438802]  intel_atomic_commit+0xbae/0x12f0 [i915]
[  378.438839]  drm_atomic_commit+0xb0/0x120 [drm]
[  378.438855]  drm_atomic_helper_connector_dpms+0x339/0x5d0 [drm_kms_helper]
[  378.438891]  drm_mode_obj_set_property_ioctl+0x8f1/0xcc0 [drm]
[  378.438927]  drm_mode_connector_property_set_ioctl+0xf3/0x170 [drm]
[  378.438959]  drm_ioctl+0x2d7/0xae0 [drm]
[  378.438962]  do_vfs_ioctl+0x1c9/0x1280
[  378.438964]  SyS_ioctl+0x79/0x90
[  378.438967]  entry_SYSCALL_64_fastpath+0x1a/0xa4

Cc: dri-devel@lists.freedesktop.org
Cc: Daniel Vetter <daniel.vetter@intel.com>
Signed-off-by: Matthew Auld <matthew.auld@intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Link: http://patchwork.freedesktop.org/patch/msgid/1466440966-5410-1-git-send-email-matthew.auld@intel.com
This commit is contained in:
Matthew Auld 2016-06-20 17:42:46 +01:00 committed by Daniel Vetter
parent bd3e22088f
commit c001da4f7c

View File

@ -994,10 +994,10 @@ static void send_vblank_event(struct drm_device *dev,
e->event.tv_sec = now->tv_sec;
e->event.tv_usec = now->tv_usec;
drm_send_event_locked(dev, &e->base);
trace_drm_vblank_event_delivered(e->base.pid, e->pipe,
e->event.sequence);
drm_send_event_locked(dev, &e->base);
}
/**