linux/drivers/gpu/drm
Daniel Vetter 4e076c73e4 drm/atomic: Fix potential use-after-free in nonblocking commits
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: shanzhulig <shanzhulig@gmail.com>
Suggested-by: shanzhulig <shanzhulig@gmail.com>
Reviewed-by: Maxime 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: Daniel Vetter <daniel.vetter@intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2023-07-21 09:53:30 -07:00
..
amd drm/amdgpu: use a macro to define no xcp partition case 2023-07-18 14:42:54 -04:00
arm
armada drm/client: Send hotplug event after registering a client 2023-07-11 14:02:01 +02:00
aspeed
ast drm/ast: Fix modeset failed on DisplayPort 2023-06-01 10:40:38 +02:00
atmel-hlcdc
bridge Linux 6.5-rc1 2023-07-11 09:23:20 +02:00
display drm changes for 6.5-rc1: 2023-06-29 11:00:17 -07:00
etnaviv
exynos drm/client: Send hotplug event after registering a client 2023-07-11 14:02:01 +02:00
fsl-dcu
gma500 drm/client: Send hotplug event after registering a client 2023-07-11 14:02:01 +02:00
gud
hisilicon
hyperv
i2c drm changes for 6.5-rc1: 2023-06-29 11:00:17 -07:00
i915 Revert "drm/i915: use localized __diag_ignore_all() instead of per file" 2023-07-17 13:39:04 +01:00
imx
ingenic
kmb
lib
lima drm/lima: fix sched context destroy 2023-06-07 11:53:22 +08:00
logicvc
mcde
mediatek drm/mediatek: Replace all non-returning strlcpy with strscpy 2023-06-01 07:07:37 -07:00
meson drm/meson: venc: include linux/bitfield.h 2023-06-02 15:47:52 +02:00
mgag200 Merge drm/drm-fixes into drm-misc-fixes 2023-05-12 09:47:12 +02:00
msm drm/client: Send hotplug event after registering a client 2023-07-11 14:02:01 +02:00
mxsfb drm: lcdif: Add i.MX93 LCDIF compatible string 2023-05-26 19:07:33 +02:00
nouveau drm/nouveau/kms/nv50-: init hpd_irq_lock for PIOR DP 2023-07-19 11:08:47 +02:00
omapdrm drm/client: Send hotplug event after registering a client 2023-07-11 14:02:01 +02:00
panel Linux 6.5-rc1 2023-07-11 09:23:20 +02:00
panfrost drm next for 6.4-rc1 2023-04-25 16:12:15 -07:00
pl111 drm/pl111: Fix FB depth on IMPD-1 framebuffer 2023-05-16 09:46:21 +02:00
qxl
radeon drm/client: Send hotplug event after registering a client 2023-07-11 14:02:01 +02:00
renesas drm: Place Renesas drivers in a separate dir 2023-05-29 16:41:03 +03:00
rockchip drm changes for 6.5-rc1: 2023-06-29 11:00:17 -07:00
scheduler Linux 6.5-rc1 2023-07-11 09:23:20 +02:00
solomon drm: Switch i2c drivers back to use .probe() 2023-05-30 16:55:16 -07:00
sprd
sti drm/sti/sti_hdmi: convert to using is_hdmi from display info 2023-05-02 18:48:58 +03:00
stm drm/stm: ltdc: fix late dereference check 2023-05-26 13:31:22 +02:00
sun4i drm changes for 6.5-rc1: 2023-06-29 11:00:17 -07:00
tegra drm/client: Send hotplug event after registering a client 2023-07-11 14:02:01 +02:00
tests Merge drm/drm-next into drm-misc-next 2023-05-09 15:03:40 +02:00
tidss
tilcdc
tiny
ttm Linux 6.5-rc1 2023-07-11 09:23:20 +02:00
tve200
udl drm/udl: delete dead code 2023-05-03 16:32:33 +02:00
v3d
vboxvideo
vc4 Merge tag 'amd-drm-next-6.5-2023-06-09' of https://gitlab.freedesktop.org/agd5f/linux into drm-next 2023-06-15 14:11:22 +10:00
vgem
virtio drm/virtio: Wait for each dma-fence of in-fence array individually 2023-06-03 04:50:50 +03:00
vkms drm/vkms: Fix RGB565 pixel conversion 2023-05-15 10:58:11 -03:00
vmwgfx drm/vmwgfx: Add unwind hints around RBP clobber 2023-06-07 10:03:12 -07:00
xen
xlnx
Kconfig Renesas DRM/KMS drivers: 2023-06-09 11:17:00 +10:00
Makefile Merge tag 'amd-drm-next-6.5-2023-06-09' of https://gitlab.freedesktop.org/agd5f/linux into drm-next 2023-06-15 14:11:22 +10:00
drm_agpsupport.c
drm_aperture.c
drm_atomic.c drm/atomic: Fix potential use-after-free in nonblocking commits 2023-07-21 09:53:30 -07:00
drm_atomic_helper.c drm/drm_atomic_helper.c: fix a typo 2023-05-17 09:22:07 +02:00
drm_atomic_state_helper.c
drm_atomic_uapi.c
drm_auth.c
drm_blend.c
drm_bridge.c
drm_bridge_connector.c
drm_buddy.c
drm_bufs.c
drm_cache.c
drm_client.c drm/client: Send hotplug event after registering a client 2023-07-11 14:02:01 +02:00
drm_client_modeset.c drm/client: Fix memory leak in drm_client_modeset_probe 2023-07-13 15:55:58 +02:00
drm_color_mgmt.c
drm_connector.c drm/connector: Allow drivers to pass list of supported colorspaces 2023-06-09 12:46:44 -04:00
drm_context.c
drm_crtc.c
drm_crtc_helper.c
drm_crtc_helper_internal.h
drm_crtc_internal.h
drm_damage_helper.c
drm_debugfs.c
drm_debugfs_crc.c
drm_displayid.c
drm_dma.c
drm_drv.c Documentation: vkms: clarify devres managed reference cleanup 2023-05-08 15:56:25 +00:00
drm_dumb_buffers.c
drm_edid.c drm/edid: make drm_edid_duplicate() safe to call with NULL parameter 2023-06-02 13:23:30 +03:00
drm_edid_load.c
drm_encoder.c
drm_encoder_slave.c
drm_fb_dma_helper.c
drm_fb_helper.c Linux 6.4-rc7 2023-06-19 16:01:25 +10:00
drm_fbdev_dma.c drm/client: Send hotplug event after registering a client 2023-07-11 14:02:01 +02:00
drm_fbdev_generic.c drm/client: Send hotplug event after registering a client 2023-07-11 14:02:01 +02:00
drm_file.c drm: Add fdinfo memory stats 2023-05-24 18:03:30 +02:00
drm_flip_work.c
drm_format_helper.c
drm_fourcc.c
drm_framebuffer.c
drm_gem.c drm: convert drm_gem_put_pages() to use a folio_batch 2023-06-23 16:59:29 -07:00
drm_gem_atomic_helper.c
drm_gem_dma_helper.c
drm_gem_framebuffer_helper.c
drm_gem_shmem_helper.c
drm_gem_ttm_helper.c
drm_gem_vram_helper.c drm/vram-helper: fix function names in vram helper doc 2023-05-08 09:16:18 +02:00
drm_hashtab.c
drm_internal.h
drm_ioc32.c
drm_ioctl.c
drm_irq.c
drm_kms_helper_common.c
drm_lease.c
drm_legacy.h
drm_legacy_misc.c
drm_lock.c
drm_managed.c drivers/gpu: use ARCH_DMA_MINALIGN instead of ARCH_KMALLOC_MINALIGN 2023-06-19 16:19:21 -07:00
drm_memory.c
drm_mipi_dbi.c
drm_mipi_dsi.c drm/display/dp_mst: Replace all non-returning strlcpy with strscpy 2023-06-01 07:07:36 -07:00
drm_mm.c
drm_mode_config.c
drm_mode_object.c
drm_modes.c
drm_modeset_helper.c
drm_modeset_lock.c
drm_of.c
drm_panel.c
drm_panel_orientation_quirks.c drm: panel-orientation-quirks: Change Air's quirk to support Air Plus 2023-05-17 11:46:49 +02:00
drm_pci.c
drm_plane.c
drm_plane_helper.c
drm_prime.c
drm_print.c
drm_privacy_screen.c
drm_privacy_screen_x86.c
drm_probe_helper.c
drm_property.c
drm_rect.c
drm_scatter.c
drm_self_refresh_helper.c
drm_simple_kms_helper.c
drm_suballoc.c
drm_syncobj.c dma-buf: fix an error pointer vs NULL bug 2023-07-06 19:50:23 +05:30
drm_sysfs.c Merge drm/drm-next into drm-misc-next 2023-05-09 15:03:40 +02:00
drm_trace.h
drm_trace_points.c
drm_vblank.c
drm_vblank_work.c
drm_vm.c
drm_vma_manager.c
drm_writeback.c