linux/drivers/gpu/drm
Lyude Paul 3a8844c298 drm/dp_mst: Fix unbalanced malloc ref in drm_dp_mst_deallocate_vcpi()
In drm_dp_mst_deallocate_vcpi(), we currently unconditionally call
drm_dp_mst_put_port_malloc() on the port that's passed to us, even if we
never successfully allocated VCPI to it. This is contrary to what we do
in drm_dp_mst_allocate_vcpi(), where we only call
drm_dp_mst_get_port_malloc() on the passed port if we successfully
allocated VCPI to it.

As a result, if drm_dp_mst_allocate_vcpi() fails during a modeset and
another successive modeset calls drm_dp_mst_deallocate_vcpi() we will
end up dropping someone else's malloc reference to the port. Example:

[  962.309260] ==================================================================
[  962.309290] BUG: KASAN: use-after-free in drm_dp_mst_put_port_malloc+0x72/0x180 [drm_kms_helper]
[  962.309296] Read of size 4 at addr ffff888416c30004 by task kworker/0:1H/500

[  962.309308] CPU: 0 PID: 500 Comm: kworker/0:1H Tainted: G        W  O      5.0.0-rc2Lyude-Test+ #1
[  962.309313] Hardware name: LENOVO 20L8S2N800/20L8S2N800, BIOS N22ET35W (1.12 ) 04/09/2018
[  962.309428] Workqueue: events_highpri intel_atomic_cleanup_work [i915]
[  962.309434] Call Trace:
[  962.309452]  dump_stack+0xad/0x150
[  962.309462]  ? dump_stack_print_info.cold.0+0x1b/0x1b
[  962.309472]  ? kmsg_dump_rewind_nolock+0xd9/0xd9
[  962.309504]  ? drm_dp_mst_put_port_malloc+0x72/0x180 [drm_kms_helper]
[  962.309515]  print_address_description+0x6c/0x23c
[  962.309542]  ? drm_dp_mst_put_port_malloc+0x72/0x180 [drm_kms_helper]
[  962.309568]  ? drm_dp_mst_put_port_malloc+0x72/0x180 [drm_kms_helper]
[  962.309577]  kasan_report.cold.3+0x1a/0x32
[  962.309605]  ? drm_dp_mst_put_port_malloc+0x72/0x180 [drm_kms_helper]
[  962.309631]  drm_dp_mst_put_port_malloc+0x72/0x180 [drm_kms_helper]
[  962.309658]  ? drm_dp_mst_put_mstb_malloc+0x180/0x180 [drm_kms_helper]
[  962.309687]  drm_dp_mst_destroy_state+0xcd/0x120 [drm_kms_helper]
[  962.309745]  drm_atomic_state_default_clear+0x6ee/0xcc0 [drm]
[  962.309864]  intel_atomic_state_clear+0xe/0x80 [i915]
[  962.309928]  __drm_atomic_state_free+0x35/0xd0 [drm]
[  962.310044]  intel_atomic_cleanup_work+0x56/0x70 [i915]
[  962.310057]  process_one_work+0x884/0x1400
[  962.310067]  ? drain_workqueue+0x5a0/0x5a0
[  962.310075]  ? __schedule+0x87f/0x1e80
[  962.310086]  ? __sched_text_start+0x8/0x8
[  962.310095]  ? run_rebalance_domains+0x400/0x400
[  962.310110]  ? deref_stack_reg+0xb4/0x120
[  962.310117]  ? __read_once_size_nocheck.constprop.7+0x10/0x10
[  962.310124]  ? worker_enter_idle+0x47f/0x6a0
[  962.310134]  ? schedule+0xd7/0x2e0
[  962.310141]  ? __schedule+0x1e80/0x1e80
[  962.310148]  ? _raw_spin_lock_irq+0x9f/0x130
[  962.310155]  ? _raw_write_unlock_irqrestore+0x110/0x110
[  962.310164]  worker_thread+0x196/0x11e0
[  962.310175]  ? set_load_weight+0x2e0/0x2e0
[  962.310181]  ? __switch_to_asm+0x34/0x70
[  962.310187]  ? __switch_to_asm+0x40/0x70
[  962.310194]  ? process_one_work+0x1400/0x1400
[  962.310199]  ? __switch_to_asm+0x40/0x70
[  962.310205]  ? __switch_to_asm+0x34/0x70
[  962.310211]  ? __switch_to_asm+0x34/0x70
[  962.310216]  ? __switch_to_asm+0x40/0x70
[  962.310221]  ? __switch_to_asm+0x34/0x70
[  962.310226]  ? __switch_to_asm+0x40/0x70
[  962.310231]  ? __switch_to_asm+0x34/0x70
[  962.310236]  ? __switch_to_asm+0x40/0x70
[  962.310242]  ? syscall_return_via_sysret+0xf/0x7f
[  962.310248]  ? __switch_to_asm+0x34/0x70
[  962.310253]  ? __switch_to_asm+0x40/0x70
[  962.310258]  ? __switch_to_asm+0x34/0x70
[  962.310263]  ? __switch_to_asm+0x40/0x70
[  962.310268]  ? __switch_to_asm+0x34/0x70
[  962.310273]  ? __switch_to_asm+0x40/0x70
[  962.310281]  ? __schedule+0x87f/0x1e80
[  962.310292]  ? __sched_text_start+0x8/0x8
[  962.310300]  ? save_stack+0x8c/0xb0
[  962.310308]  ? __kasan_kmalloc.constprop.6+0xc6/0xd0
[  962.310313]  ? kthread+0x98/0x3a0
[  962.310318]  ? ret_from_fork+0x35/0x40
[  962.310334]  ? __wake_up_common+0x178/0x6f0
[  962.310343]  ? _raw_spin_lock_irqsave+0xa4/0x140
[  962.310349]  ? __lock_text_start+0x8/0x8
[  962.310355]  ? _raw_write_lock_irqsave+0x70/0x130
[  962.310360]  ? __lock_text_start+0x8/0x8
[  962.310371]  ? process_one_work+0x1400/0x1400
[  962.310376]  kthread+0x2e2/0x3a0
[  962.310383]  ? kthread_create_on_node+0xc0/0xc0
[  962.310389]  ret_from_fork+0x35/0x40

[  962.310401] Allocated by task 1462:
[  962.310410]  __kasan_kmalloc.constprop.6+0xc6/0xd0
[  962.310437]  drm_dp_add_port+0xd60/0x1960 [drm_kms_helper]
[  962.310464]  drm_dp_send_link_address+0x4b0/0x770 [drm_kms_helper]
[  962.310491]  drm_dp_check_and_send_link_address+0x197/0x1f0 [drm_kms_helper]
[  962.310515]  drm_dp_mst_link_probe_work+0x2b6/0x330 [drm_kms_helper]
[  962.310522]  process_one_work+0x884/0x1400
[  962.310529]  worker_thread+0x196/0x11e0
[  962.310533]  kthread+0x2e2/0x3a0
[  962.310538]  ret_from_fork+0x35/0x40

[  962.310543] Freed by task 500:
[  962.310550]  __kasan_slab_free+0x133/0x180
[  962.310555]  kfree+0x92/0x1a0
[  962.310581]  drm_dp_mst_put_port_malloc+0x14d/0x180 [drm_kms_helper]
[  962.310693]  intel_connector_destroy+0xb2/0xe0 [i915]
[  962.310747]  drm_mode_object_put.part.0+0x12b/0x1a0 [drm]
[  962.310802]  drm_atomic_state_default_clear+0x1f2/0xcc0 [drm]
[  962.310916]  intel_atomic_state_clear+0xe/0x80 [i915]
[  962.310972]  __drm_atomic_state_free+0x35/0xd0 [drm]
[  962.311083]  intel_atomic_cleanup_work+0x56/0x70 [i915]
[  962.311092]  process_one_work+0x884/0x1400
[  962.311098]  worker_thread+0x196/0x11e0
[  962.311103]  kthread+0x2e2/0x3a0
[  962.311108]  ret_from_fork+0x35/0x40

[  962.311116] The buggy address belongs to the object at ffff888416c30000
                which belongs to the cache kmalloc-2k of size 2048
[  962.311122] The buggy address is located 4 bytes inside of
                2048-byte region [ffff888416c30000, ffff888416c30800)
[  962.311124] The buggy address belongs to the page:
[  962.311132] page:ffffea00105b0c00 count:1 mapcount:0 mapping:ffff88841d003040 index:0x0 compound_mapcount: 0
[  962.311142] flags: 0x8000000000010200(slab|head)
[  962.311152] raw: 8000000000010200 dead000000000100 dead000000000200 ffff88841d003040
[  962.311159] raw: 0000000000000000 00000000000f000f 00000001ffffffff 0000000000000000
[  962.311162] page dumped because: kasan: bad access detected

So, bail early if drm_dp_mst_deallocate_vcpi() is called on a port with
no VCPI allocation. Additionally, clean up the surrounding kerneldoc
while we're at it since the port is assumed to be kept around because
the DRM driver is expected to hold a malloc reference to it, not just
us.

Changes since v1:
* Doc changes - danvet

Signed-off-by: Lyude Paul <lyude@redhat.com>
Fixes: eceae14724 ("drm/dp_mst: Start tracking per-port VCPI allocations")
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Link: https://patchwork.freedesktop.org/patch/msgid/20190202002023.29665-2-lyude@redhat.com
2019-02-05 18:05:53 -05:00
..
amd drm/irq: Ditch DRIVER_IRQ_SHARED 2019-01-29 15:45:21 +01:00
arc drm: Split out drm_probe_helper.h 2019-01-24 13:20:42 +01:00
arm drm/irq: Don't check for DRIVER_HAVE_IRQ in drm_irq_(un)install 2019-01-29 15:45:06 +01:00
armada drm: Split out drm_probe_helper.h 2019-01-24 13:20:42 +01:00
ast drm: Split out drm_probe_helper.h 2019-01-24 13:20:42 +01:00
atmel-hlcdc drm/irq: Don't check for DRIVER_HAVE_IRQ in drm_irq_(un)install 2019-01-29 15:45:06 +01:00
bochs drm/bochs: fix bochs_gem_prime_mmap 2019-02-05 10:28:15 +01:00
bridge drm/bridge: dw-hdmi: add support for YUV420 output 2019-02-01 13:15:10 +01:00
cirrus drm/cirrus: add plane setup 2019-02-05 10:28:13 +01:00
etnaviv drm: Split out drm_probe_helper.h 2019-01-24 13:20:42 +01:00
exynos drm/<drivers>: Don't set FBINFO_(FLAG_)DEFAULT 2019-01-29 10:56:42 +01:00
fsl-dcu drm/irq: Don't check for DRIVER_HAVE_IRQ in drm_irq_(un)install 2019-01-29 15:45:06 +01:00
gma500 drm/irq: Ditch DRIVER_IRQ_SHARED 2019-01-29 15:45:21 +01:00
hisilicon drm/irq: Don't check for DRIVER_HAVE_IRQ in drm_irq_(un)install 2019-01-29 15:45:06 +01:00
i2c drm: Split out drm_probe_helper.h 2019-01-24 13:20:42 +01:00
i810
i915 drm/irq: Ditch DRIVER_IRQ_SHARED 2019-01-29 15:45:21 +01:00
imx drm: Split out drm_probe_helper.h 2019-01-24 13:20:42 +01:00
lib
mediatek drm: Split out drm_probe_helper.h 2019-01-24 13:20:42 +01:00
meson drm/meson: add support for HDMI2.0 2160p modes 2019-02-01 13:15:09 +01:00
mga drm/irq: Ditch DRIVER_IRQ_SHARED 2019-01-29 15:45:21 +01:00
mgag200 drm: Split out drm_probe_helper.h 2019-01-24 13:20:42 +01:00
msm drm/irq: Don't check for DRIVER_HAVE_IRQ in drm_irq_(un)install 2019-01-29 15:45:06 +01:00
mxsfb drm/irq: Don't check for DRIVER_HAVE_IRQ in drm_irq_(un)install 2019-01-29 15:45:06 +01:00
nouveau drm/<drivers>: Don't set FBINFO_(FLAG_)DEFAULT 2019-01-29 10:56:42 +01:00
omapdrm drm: Split out drm_probe_helper.h 2019-01-24 13:20:42 +01:00
panel drm/panel: simple: Add support for PDA 91-00156-A0 panel 2019-01-28 17:45:28 +01:00
pl111 drm: Split out drm_probe_helper.h 2019-01-24 13:20:42 +01:00
qxl drm/qxl: use ttm_tt 2019-01-30 10:51:35 +01:00
r128 drm/irq: Ditch DRIVER_IRQ_SHARED 2019-01-29 15:45:21 +01:00
radeon drm/irq: Ditch DRIVER_IRQ_SHARED 2019-01-29 15:45:21 +01:00
rcar-du drm: Split out drm_probe_helper.h 2019-01-24 13:20:42 +01:00
rockchip drm/<drivers>: Don't set FBINFO_(FLAG_)DEFAULT 2019-01-29 10:56:42 +01:00
savage drm/savage: mark expected switch fall-throughs 2019-01-30 17:35:29 +01:00
scheduler drm/scheduler: Add drm_sched_suspend/resume_timeout() 2018-12-05 17:56:16 -05:00
selftests drm/selftest: fix spelling mistake "dimention" -> "dimension" 2018-12-11 15:19:42 +01:00
shmobile drm/irq: Don't check for DRIVER_HAVE_IRQ in drm_irq_(un)install 2019-01-29 15:45:06 +01:00
sis
sti drm: Split out drm_probe_helper.h 2019-01-24 13:20:42 +01:00
stm drm: Split out drm_probe_helper.h 2019-01-24 13:20:42 +01:00
sun4i drm/sun4i: Add support for A23 display pipeline 2019-01-25 10:42:07 +01:00
tdfx
tegra drm/<drivers>: Don't set FBINFO_(FLAG_)DEFAULT 2019-01-29 10:56:42 +01:00
tilcdc drm/irq: Don't check for DRIVER_HAVE_IRQ in drm_irq_(un)install 2019-01-29 15:45:06 +01:00
tinydrm drm: Split out drm_probe_helper.h 2019-01-24 13:20:42 +01:00
ttm drm/ttm: Use drm_debug_printer for all ttm_bo_mem_space_debug output 2018-12-21 15:27:58 -05:00
tve200 drm: Split out drm_probe_helper.h 2019-01-24 13:20:42 +01:00
udl drm: Split out drm_probe_helper.h 2019-01-24 13:20:42 +01:00
v3d drm/v3d: Invalidate the caches from the outside in. 2018-12-07 10:56:51 -08:00
vc4 drm/irq: Don't check for DRIVER_HAVE_IRQ in drm_irq_(un)install 2019-01-29 15:45:06 +01:00
vgem dma-buf: make fence sequence numbers 64 bit v2 2018-12-07 12:44:16 +01:00
via drm/via: mark expected switch fall-throughs 2019-01-30 17:35:29 +01:00
virtio drm: Split out drm_probe_helper.h 2019-01-24 13:20:42 +01:00
vkms drm/vkms: Bugfix racing hrtimer vblank handle 2019-02-03 19:28:21 -02:00
vmwgfx drm/irq: Ditch DRIVER_IRQ_SHARED 2019-01-29 15:45:21 +01:00
xen drm/xen-front: Fix mmap attributes for display buffers 2019-02-04 08:39:31 +02:00
zte drm: Split out drm_probe_helper.h 2019-01-24 13:20:42 +01:00
Kconfig drm/cma-helper: Remove unused fbdev code 2019-01-17 10:56:38 +01:00
Makefile Merge tag 'vmwgfx-next-2018-12-05' of git://people.freedesktop.org/~thomash/linux into drm-next 2018-12-06 13:43:56 +10:00
ati_pcigart.c drm/ati_pcigart: Fix error code in drm_ati_pcigart_init() 2018-12-17 10:47:17 +01:00
drm_agpsupport.c drm: Trivial comment grammar cleanups 2019-02-04 10:21:17 +01:00
drm_atomic.c drm-misc-next for 5.1: 2019-01-10 05:58:52 +10:00
drm_atomic_helper.c drm: Trivial comment grammar cleanups 2019-02-04 10:21:17 +01:00
drm_atomic_state_helper.c drm: Put damage blob when destroy plane state 2018-12-24 11:53:50 +01:00
drm_atomic_uapi.c drm: Trivial comment grammar cleanups 2019-02-04 10:21:17 +01:00
drm_auth.c drm: set is_master to 0 upon drm_new_set_master() failure 2018-11-26 16:14:27 -05:00
drm_blend.c
drm_bridge.c drm: bridge: Constify mode arguments to bridge .mode_set() operation 2019-01-14 03:51:14 +02:00
drm_bufs.c drm: Trivial comment grammar cleanups 2019-02-04 10:21:17 +01:00
drm_cache.c
drm_client.c drm/gem: Add drm_gem_object_funcs 2018-11-20 14:56:18 +01:00
drm_color_mgmt.c drm: Add DRM_MODESET_LOCK_BEGIN/END helpers 2018-11-29 10:48:31 -05:00
drm_connector.c drm: Trivial comment grammar cleanups 2019-02-04 10:21:17 +01:00
drm_context.c drm: Fix error handling in drm_legacy_addctx 2019-01-07 11:26:31 +01:00
drm_crtc.c drm: Move the legacy kms disable_all helper to crtc helpers 2019-01-11 22:54:29 +01:00
drm_crtc_helper.c drm: Remove use of drm_mode_object 2019-01-15 13:20:56 +01:00
drm_crtc_helper_internal.h
drm_crtc_internal.h drm: Unexport drm_crtc_force_disable 2019-01-11 15:56:40 +01:00
drm_damage_helper.c drm/damage-helper: Add drm_atomic_helper_damage_merged() 2019-01-17 10:56:54 +01:00
drm_debugfs.c drm: Merge drm_info.c into drm_debugfs.c 2018-11-22 09:52:27 +01:00
drm_debugfs_crc.c
drm_dma.c
drm_dp_aux_dev.c
drm_dp_cec.c
drm_dp_dual_mode_helper.c
drm_dp_helper.c Merge drm/drm-next into drm-misc-next 2019-01-24 11:03:16 +01:00
drm_dp_mst_topology.c drm/dp_mst: Fix unbalanced malloc ref in drm_dp_mst_deallocate_vcpi() 2019-02-05 18:05:53 -05:00
drm_drv.c drm/docs: improve docs for drm_drv.c 2019-01-12 13:07:30 +01:00
drm_dsc.c drm/dsc: Add helpers for DSC picture parameter set infoframes 2018-11-27 18:35:17 -08:00
drm_dumb_buffers.c
drm_edid.c drm/edid: Add display_info.rgb_quant_range_selectable 2019-01-10 19:01:06 +02:00
drm_edid_load.c
drm_encoder.c
drm_encoder_slave.c
drm_fb_cma_helper.c drm/cma-helper: Remove unused fbdev code 2019-01-17 10:56:38 +01:00
drm_fb_helper.c drm: Trivial comment grammar cleanups 2019-02-04 10:21:17 +01:00
drm_file.c drm: Trivial comment grammar cleanups 2019-02-04 10:21:17 +01:00
drm_flip_work.c drm: move drm_can_sleep() to drm_util.h 2019-01-14 10:58:37 +01:00
drm_fourcc.c drm: Introduce new DRM_FORMAT_XYUV 2018-11-20 16:20:13 +02:00
drm_framebuffer.c drm: Trivial comment grammar cleanups 2019-02-04 10:21:17 +01:00
drm_gem.c drm: Trivial comment grammar cleanups 2019-02-04 10:21:17 +01:00
drm_gem_cma_helper.c drm/cma-helper: Add DRM_GEM_CMA_VMAP_DRIVER_OPS 2018-11-20 14:57:25 +01:00
drm_gem_framebuffer_helper.c drm/gem-fb-helper: Add drm_gem_fb_create_with_dirty() 2019-01-17 10:56:45 +01:00
drm_hashtab.c
drm_internal.h drm-misc-next for 5.1: 2019-01-10 05:58:52 +10:00
drm_ioc32.c
drm_ioctl.c drm/ioctl: Fix Spectre v1 vulnerabilities 2018-12-20 08:13:29 +01:00
drm_irq.c drm/irq: Ditch DRIVER_IRQ_SHARED 2019-01-29 15:45:21 +01:00
drm_kms_helper_common.c
drm_lease.c drm-misc-next for 5.1: 2019-01-10 05:58:52 +10:00
drm_legacy.h
drm_lock.c
drm_memory.c
drm_mipi_dsi.c
drm_mm.c drm: Trivial comment grammar cleanups 2019-02-04 10:21:17 +01:00
drm_mode_config.c drm-misc-next for 5.1: 2019-01-10 05:58:52 +10:00
drm_mode_object.c drm: Reorder set_property_atomic to avoid returning with an active ww_ctx 2019-01-03 09:54:26 +00:00
drm_modes.c drm: Trivial comment grammar cleanups 2019-02-04 10:21:17 +01:00
drm_modeset_helper.c drm: Split out drm_probe_helper.h 2019-01-24 13:20:42 +01:00
drm_modeset_lock.c drm/atomic: integrate modeset lock with private objects 2018-12-11 15:24:30 +01:00
drm_of.c drm/of: Fix kerneldoc 2019-01-12 13:07:58 +01:00
drm_panel.c drm/panel: Small documentation polish 2019-01-12 13:08:12 +01:00
drm_panel_orientation_quirks.c drm: panel-orientation-quirks: Do rotation quirk for new GPD Win2 FW 2018-11-15 10:55:30 +01:00
drm_pci.c
drm_plane.c drm: Auto-set allow_fb_modifiers when given modifiers at plane init 2019-01-11 16:53:55 +01:00
drm_plane_helper.c
drm_prime.c drm/prime: Fix drm_gem_prime_mmap() stack use 2018-11-22 15:44:05 +01:00
drm_print.c
drm_probe_helper.c drm: Split out drm_probe_helper.h 2019-01-24 13:20:42 +01:00
drm_property.c drm: Trivial comment grammar cleanups 2019-02-04 10:21:17 +01:00
drm_rect.c
drm_scatter.c
drm_scdc_helper.c
drm_simple_kms_helper.c drm: Split out drm_probe_helper.h 2019-01-24 13:20:42 +01:00
drm_syncobj.c drm/syncobj: remove drm_syncobj_cb and cleanup 2018-12-11 17:38:38 +01:00
drm_sysfs.c drm/lease: Send a distinct uevent 2018-11-30 10:57:18 +01:00
drm_trace.h
drm_trace_points.c
drm_vblank.c drm: Trivial comment grammar cleanups 2019-02-04 10:21:17 +01:00
drm_vm.c
drm_vma_manager.c
drm_writeback.c