* [PATCH 0/1] Fix use-after-free on framebuffers and property blobs when calling drm_dev_unplug
@ 2026-02-25 10:15 Maarten Lankhorst
2026-02-25 10:15 ` [PATCH 1/1] drm: " Maarten Lankhorst
0 siblings, 1 reply; 3+ messages in thread
From: Maarten Lankhorst @ 2026-02-25 10:15 UTC (permalink / raw)
To: dri-devel; +Cc: intel-xe, Maarten Lankhorst
I tried to see what happened with xe_module_unload --r reload on a fully
running system, and came across these bugs in the kernel. Even after
these fixes I still see a hang when reloading, related to cgroups, so
likely some more fixes are needed to address those.
Should this patch have a fixes tag or cc stable patch?
Test-with: https://patchwork.freedesktop.org/series/162133/
Maarten Lankhorst (1):
drm: Fix use-after-free on framebuffers and property blobs when
calling drm_dev_unplug
drivers/gpu/drm/drm_crtc_internal.h | 4 +++-
drivers/gpu/drm/drm_drv.c | 3 +++
drivers/gpu/drm/drm_file.c | 5 ++++-
drivers/gpu/drm/drm_framebuffer.c | 25 +++++++++++++++++++++++++
drivers/gpu/drm/drm_mode_config.c | 8 ++++++++
drivers/gpu/drm/drm_property.c | 20 ++++++++++++++++++++
6 files changed, 63 insertions(+), 2 deletions(-)
--
2.51.0
^ permalink raw reply [flat|nested] 3+ messages in thread* [PATCH 1/1] drm: Fix use-after-free on framebuffers and property blobs when calling drm_dev_unplug 2026-02-25 10:15 [PATCH 0/1] Fix use-after-free on framebuffers and property blobs when calling drm_dev_unplug Maarten Lankhorst @ 2026-02-25 10:15 ` Maarten Lankhorst 2026-03-10 14:07 ` Thomas Hellström 0 siblings, 1 reply; 3+ messages in thread From: Maarten Lankhorst @ 2026-02-25 10:15 UTC (permalink / raw) To: dri-devel; +Cc: intel-xe, Maarten Lankhorst When trying to do a rather aggressive test of igt's "xe_module_load --r reload" with a full desktop environment and game running I noticed a few OOPSes when dereferencing freed pointers, related to framebuffers and property blobs after the compositor exits. Solve this by guarding the freeing in drm_file with drm_dev_enter/exit, and immediately put the references from struct drm_file objects during drm_dev_unplug(). Related warnings for framebuffers on the subtest: [ 739.713076] ------------[ cut here ]------------ WARN_ON(!list_empty(&dev->mode_config.fb_list)) [ 739.713079] WARNING: drivers/gpu/drm/drm_mode_config.c:584 at drm_mode_config_cleanup+0x30b/0x320 [drm], CPU#12: xe_module_load/13145 [ 739.713172] Modules linked in: rfcomm snd_hrtimer xt_CHECKSUM xt_MASQUERADE xt_conntrack ipt_REJECT nf_reject_ipv4 xt_tcpudp xt_addrtype nft_compat x_tables nft_chain_nat nf_nat nf_conntrack nf_defrag_ipv6 nf_defrag_ipv4 nf_tables overlay cfg80211 bnep mtd_intel_dg snd_hda_codec_intelhdmi mtd snd_hda_codec_hdmi nls_utf8 mxm_wmi intel_wmi_thunderbolt gigabyte_wmi wmi_bmof xe drm_gpuvm drm_gpusvm_helper i2c_algo_bit drm_buddy drm_ttm_helper ttm video drm_suballoc_helper gpu_sched drm_client_lib drm_exec drm_display_helper cec drm_kunit_helpers drm_kms_helper kunit x86_pkg_temp_thermal intel_powerclamp coretemp snd_hda_codec_alc882 snd_hda_codec_realtek_lib snd_hda_codec_generic snd_hda_intel snd_soc_avs snd_soc_hda_codec snd_hda_ext_core snd_hda_codec snd_hwdep snd_hda_core snd_intel_dspcfg snd_soc_core snd_compress ac97_bus snd_pcm snd_seq snd_seq_device snd_timer i2c_i801 i2c_mux snd i2c_smbus btusb btrtl btbcm btmtk btintel bluetooth ecdh_generic rfkill ecc mei_me mei ioatdma dca wmi nfsd drm i2c_dev fuse nfnetlink [ 739.713234] CPU: 12 UID: 0 PID: 13145 Comm: xe_module_load Not tainted 7.0.0-rc1-valkyria+ #110 PREEMPT_{RT,(lazy)} [ 739.713239] Hardware name: Gigabyte Technology Co., Ltd. X299 AORUS Gaming 3/X299 AORUS Gaming 3-CF, BIOS F8n 12/06/2021 [ 739.713241] RIP: 0010:drm_mode_config_cleanup+0x30b/0x320 [drm] [ 739.713306] Code: 70 60 48 c7 c7 7a 8d 28 a0 e8 f1 a6 00 00 48 8d 7d 88 e8 88 75 fe ff 48 85 c0 75 e2 48 8d 7d 88 e8 1a 75 fe ff e9 a7 fd ff ff <0f> 0b e9 d6 fe ff ff 0f 0b eb 9c e8 55 0b d2 e1 0f 1f 44 00 00 0f [ 739.713309] RSP: 0018:ffffc90025003be8 EFLAGS: 00010283 [ 739.713312] RAX: ffff88814675ba08 RBX: ffff88810d778b40 RCX: ffffffff8217ed03 [ 739.713314] RDX: 0000000000000000 RSI: 0000000000000000 RDI: ffff88810d778b40 [ 739.713316] RBP: ffffc90025003c60 R08: 0000000000000001 R09: 0000000000000000 [ 739.713318] R10: 0000000000000000 R11: ffff888141aeaf78 R12: ffff88810d778000 [ 739.713319] R13: ffff88810d778b68 R14: ffff88810d7787d8 R15: 000000000000006c [ 739.713321] FS: 00007f99dd0e5980(0000) GS:ffff888cec878000(0000) knlGS:0000000000000000 [ 739.713324] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 739.713326] CR2: 00007f9fa46bcac0 CR3: 00000004fe2b2002 CR4: 00000000003706f0 [ 739.713328] Call Trace: [ 739.713330] <TASK> [ 739.713335] ? intel_pmdemand_destroy_state+0x11/0x20 [xe] [ 739.713574] ? intel_atomic_global_obj_cleanup+0xe4/0x1a0 [xe] [ 739.713794] intel_display_driver_remove_noirq+0x51/0xb0 [xe] [ 739.714041] xe_display_fini_early+0x33/0x50 [xe] [ 739.714284] devm_action_release+0xf/0x20 [ 739.714294] devres_release_all+0xad/0xf0 [ 739.714301] device_unbind_cleanup+0x12/0xa0 [ 739.714305] device_release_driver_internal+0x1b7/0x210 [ 739.714311] device_driver_detach+0x14/0x20 [ 739.714315] unbind_store+0xa6/0xb0 [ 739.714319] drv_attr_store+0x21/0x30 [ 739.714322] sysfs_kf_write+0x48/0x60 [ 739.714328] kernfs_fop_write_iter+0x16b/0x240 [ 739.714333] vfs_write+0x266/0x520 [ 739.714341] ksys_write+0x72/0xe0 [ 739.714345] __x64_sys_write+0x19/0x20 [ 739.714347] x64_sys_call+0xa15/0xa30 [ 739.714355] do_syscall_64+0xd8/0xab0 [ 739.714361] entry_SYSCALL_64_after_hwframe+0x4b/0x53 [ 739.714365] RIP: 0033:0x7f99df4aa146 [ 739.714368] Code: 47 ba 04 00 00 00 48 8b 05 c7 0c 17 00 64 89 10 48 c7 c2 ff ff ff ff c9 48 89 d0 c3 0f 1f 84 00 00 00 00 00 48 8b 45 10 0f 05 <48> 89 c2 48 3d 00 f0 ff ff 77 0f c9 48 89 d0 c3 66 2e 0f 1f 84 00 [ 739.714371] RSP: 002b:00007fffe4b8fc00 EFLAGS: 00000202 ORIG_RAX: 0000000000000001 [ 739.714374] RAX: ffffffffffffffda RBX: 000000000000000c RCX: 00007f99df4aa146 [ 739.714376] RDX: 000000000000000c RSI: 00005561e56d9073 RDI: 0000000000000004 [ 739.714377] RBP: 00007fffe4b8fc10 R08: 0000000000000000 R09: 0000000000000000 [ 739.714379] R10: 0000000000000000 R11: 0000000000000202 R12: 0000000000000004 [ 739.714380] R13: 0000000000000000 R14: 00005561e56d9073 R15: 00005561bb5aacf8 [ 739.714387] </TASK> [ 739.714389] irq event stamp: 0 [ 739.714390] hardirqs last enabled at (0): [<0000000000000000>] 0x0 [ 739.714392] hardirqs last disabled at (0): [<ffffffff81317d2b>] copy_process+0xacb/0x2220 [ 739.714398] softirqs last enabled at (0): [<ffffffff81317d2b>] copy_process+0xacb/0x2220 [ 739.714401] softirqs last disabled at (0): [<0000000000000000>] 0x0 [ 739.714403] ---[ end trace 0000000000000000 ]--- .... [ 739.714459] ------------[ cut here ]------------ [ 739.714461] xe 0000:67:00.0: [drm] drm_WARN_ON(!list_empty(&fb->filp_head)) [ 739.714464] WARNING: drivers/gpu/drm/drm_framebuffer.c:833 at drm_framebuffer_free+0x6c/0x90 [drm], CPU#12: xe_module_load/13145 [ 739.714596] Modules linked in: rfcomm snd_hrtimer xt_CHECKSUM xt_MASQUERADE xt_conntrack ipt_REJECT nf_reject_ipv4 xt_tcpudp xt_addrtype nft_compat x_tables nft_chain_nat nf_nat nf_conntrack nf_defrag_ipv6 nf_defrag_ipv4 nf_tables overlay cfg80211 bnep mtd_intel_dg snd_hda_codec_intelhdmi mtd snd_hda_codec_hdmi nls_utf8 mxm_wmi intel_wmi_thunderbolt gigabyte_wmi wmi_bmof xe drm_gpuvm drm_gpusvm_helper i2c_algo_bit drm_buddy drm_ttm_helper ttm video drm_suballoc_helper gpu_sched drm_client_lib drm_exec drm_display_helper cec drm_kunit_helpers drm_kms_helper kunit x86_pkg_temp_thermal intel_powerclamp coretemp snd_hda_codec_alc882 snd_hda_codec_realtek_lib snd_hda_codec_generic snd_hda_intel snd_soc_avs snd_soc_hda_codec snd_hda_ext_core snd_hda_codec snd_hwdep snd_hda_core snd_intel_dspcfg snd_soc_core snd_compress ac97_bus snd_pcm snd_seq snd_seq_device snd_timer i2c_i801 i2c_mux snd i2c_smbus btusb btrtl btbcm btmtk btintel bluetooth ecdh_generic rfkill ecc mei_me mei ioatdma dca wmi nfsd drm i2c_dev fuse nfnetlink [ 739.714704] CPU: 12 UID: 0 PID: 13145 Comm: xe_module_load Tainted: G W 7.0.0-rc1-valkyria+ #110 PREEMPT_{RT,(lazy)} [ 739.714711] Tainted: [W]=WARN [ 739.714713] Hardware name: Gigabyte Technology Co., Ltd. X299 AORUS Gaming 3/X299 AORUS Gaming 3-CF, BIOS F8n 12/06/2021 [ 739.714715] RIP: 0010:drm_framebuffer_free+0x7a/0x90 [drm] [ 739.714830] Code: 48 85 d2 75 03 48 8b 17 48 89 55 e0 4c 89 45 e8 e8 ab 40 74 e1 48 8d 3d b4 5e df ff 48 8b 55 e0 48 c7 c1 30 38 28 a0 48 89 c6 <67> 48 0f b9 3a 4c 8b 45 e8 eb 9f 31 ff eb c3 0f 1f 80 00 00 00 00 [ 739.714842] RSP: 0018:ffffc90025003bb8 EFLAGS: 00010282 [ 739.714846] RAX: ffffffffa0b60f69 RBX: ffff88814675ba28 RCX: ffffffffa0283830 [ 739.714849] RDX: ffff8881033cc9f0 RSI: ffffffffa0b60f69 RDI: ffffffffa0235740 [ 739.714852] RBP: ffffc90025003bd8 R08: ffff88810d778000 R09: ffffffffa028815b [ 739.714854] R10: 0000000000000000 R11: ffff888141aeaf78 R12: ffff88810d778000 [ 739.714857] R13: ffff888237f18600 R14: ffff88810d7787d8 R15: ffffffffa04484f7 [ 739.714859] FS: 00007f99dd0e5980(0000) GS:ffff888cec878000(0000) knlGS:0000000000000000 [ 739.714863] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 739.714866] CR2: 00007f9fa46bcac0 CR3: 00000004fe2b2002 CR4: 00000000003706f0 [ 739.714869] Call Trace: [ 739.714871] <TASK> [ 739.714876] drm_mode_config_cleanup+0x26a/0x320 [drm] [ 739.714998] ? __drm_printfn_seq_file+0x20/0x20 [drm] [ 739.715115] ? drm_mode_config_cleanup+0x207/0x320 [drm] [ 739.715235] intel_display_driver_remove_noirq+0x51/0xb0 [xe] [ 739.715576] xe_display_fini_early+0x33/0x50 [xe] [ 739.715821] devm_action_release+0xf/0x20 [ 739.715828] devres_release_all+0xad/0xf0 [ 739.715843] device_unbind_cleanup+0x12/0xa0 [ 739.715850] device_release_driver_internal+0x1b7/0x210 [ 739.715856] device_driver_detach+0x14/0x20 [ 739.715860] unbind_store+0xa6/0xb0 [ 739.715865] drv_attr_store+0x21/0x30 [ 739.715868] sysfs_kf_write+0x48/0x60 [ 739.715873] kernfs_fop_write_iter+0x16b/0x240 [ 739.715878] vfs_write+0x266/0x520 [ 739.715886] ksys_write+0x72/0xe0 [ 739.715890] __x64_sys_write+0x19/0x20 [ 739.715893] x64_sys_call+0xa15/0xa30 [ 739.715900] do_syscall_64+0xd8/0xab0 [ 739.715905] entry_SYSCALL_64_after_hwframe+0x4b/0x53 [ 739.715908] RIP: 0033:0x7f99df4aa146 [ 739.715911] Code: 47 ba 04 00 00 00 48 8b 05 c7 0c 17 00 64 89 10 48 c7 c2 ff ff ff ff c9 48 89 d0 c3 0f 1f 84 00 00 00 00 00 48 8b 45 10 0f 05 <48> 89 c2 48 3d 00 f0 ff ff 77 0f c9 48 89 d0 c3 66 2e 0f 1f 84 00 [ 739.715913] RSP: 002b:00007fffe4b8fc00 EFLAGS: 00000202 ORIG_RAX: 0000000000000001 [ 739.715916] RAX: ffffffffffffffda RBX: 000000000000000c RCX: 00007f99df4aa146 [ 739.715918] RDX: 000000000000000c RSI: 00005561e56d9073 RDI: 0000000000000004 [ 739.715919] RBP: 00007fffe4b8fc10 R08: 0000000000000000 R09: 0000000000000000 [ 739.715921] R10: 0000000000000000 R11: 0000000000000202 R12: 0000000000000004 [ 739.715922] R13: 0000000000000000 R14: 00005561e56d9073 R15: 00005561bb5aacf8 [ 739.715929] </TASK> [ 739.715930] irq event stamp: 0 [ 739.715931] hardirqs last enabled at (0): [<0000000000000000>] 0x0 [ 739.715933] hardirqs last disabled at (0): [<ffffffff81317d2b>] copy_process+0xacb/0x2220 [ 739.715938] softirqs last enabled at (0): [<ffffffff81317d2b>] copy_process+0xacb/0x2220 [ 739.715941] softirqs last disabled at (0): [<0000000000000000>] 0x0 [ 739.715943] ---[ end trace 0000000000000000 ]--- ... [ 743.186530] Oops: general protection fault, probably for non-canonical address 0xdead000000000122: 0000 [#1] SMP [ 743.186535] CPU: 3 UID: 1000 PID: 3453 Comm: kwin_wayland Tainted: G W 7.0.0-rc1-valkyria+ #110 PREEMPT_{RT,(lazy)} [ 743.186537] Tainted: [W]=WARN [ 743.186538] Hardware name: Gigabyte Technology Co., Ltd. X299 AORUS Gaming 3/X299 AORUS Gaming 3-CF, BIOS F8n 12/06/2021 [ 743.186539] RIP: 0010:drm_framebuffer_cleanup+0x55/0xc0 [drm] [ 743.186588] Code: d8 72 73 0f b6 42 05 ff c3 39 c3 72 e8 49 8d bd 50 07 00 00 31 f6 e8 3a 80 d3 e1 49 8b 44 24 10 49 8d 7c 24 08 49 8b 54 24 08 <48> 3b 38 0f 85 95 7f 02 00 48 3b 7a 08 0f 85 8b 7f 02 00 48 89 42 [ 743.186589] RSP: 0018:ffffc900085e3cf8 EFLAGS: 00010202 [ 743.186591] RAX: dead000000000122 RBX: 0000000000000001 RCX: ffffffff8217ed03 [ 743.186592] RDX: dead000000000100 RSI: 0000000000000000 RDI: ffff88814675ba08 [ 743.186593] RBP: ffffc900085e3d10 R08: 0000000000000000 R09: 0000000000000000 [ 743.186593] R10: 0000000000000000 R11: 0000000000000000 R12: ffff88814675ba00 [ 743.186594] R13: ffff88810d778000 R14: ffff888119f6dca0 R15: ffff88810c660bb0 [ 743.186595] FS: 00007ff377d21280(0000) GS:ffff888cec3f8000(0000) knlGS:0000000000000000 [ 743.186596] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 743.186596] CR2: 000055690b55e000 CR3: 0000000113586003 CR4: 00000000003706f0 [ 743.186597] Call Trace: [ 743.186598] <TASK> [ 743.186603] intel_user_framebuffer_destroy+0x12/0x90 [xe] [ 743.186722] drm_framebuffer_free+0x3a/0x90 [drm] [ 743.186750] ? trace_hardirqs_on+0x5f/0x120 [ 743.186754] drm_mode_object_put+0x51/0x70 [drm] [ 743.186786] drm_fb_release+0x105/0x190 [drm] [ 743.186812] ? rt_mutex_slowunlock+0x3aa/0x410 [ 743.186817] ? rt_spin_lock+0xea/0x1b0 [ 743.186819] drm_file_free+0x1e0/0x2c0 [drm] [ 743.186843] drm_release_noglobal+0x91/0xf0 [drm] [ 743.186865] __fput+0x100/0x2e0 [ 743.186869] fput_close_sync+0x40/0xa0 [ 743.186870] __x64_sys_close+0x3e/0x80 [ 743.186873] x64_sys_call+0xa07/0xa30 [ 743.186879] do_syscall_64+0xd8/0xab0 [ 743.186881] entry_SYSCALL_64_after_hwframe+0x4b/0x53 [ 743.186882] RIP: 0033:0x7ff37e567732 [ 743.186884] Code: 08 0f 85 a1 38 ff ff 49 89 fb 48 89 f0 48 89 d7 48 89 ce 4c 89 c2 4d 89 ca 4c 8b 44 24 08 4c 8b 4c 24 10 4c 89 5c 24 08 0f 05 <c3> 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 00 f3 0f 1e fa 55 bf 01 00 [ 743.186885] RSP: 002b:00007ffc818169a8 EFLAGS: 00000246 ORIG_RAX: 0000000000000003 [ 743.186886] RAX: ffffffffffffffda RBX: 00007ffc81816a30 RCX: 00007ff37e567732 [ 743.186887] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000012 [ 743.186888] RBP: 00007ffc818169d0 R08: 0000000000000000 R09: 0000000000000000 [ 743.186889] R10: 0000000000000000 R11: 0000000000000246 R12: 000055d60a7996e0 [ 743.186889] R13: 00007ffc81816a90 R14: 00007ffc81816a90 R15: 000055d60a782a30 [ 743.186892] </TASK> [ 743.186893] Modules linked in: rfcomm snd_hrtimer xt_CHECKSUM xt_MASQUERADE xt_conntrack ipt_REJECT nf_reject_ipv4 xt_tcpudp xt_addrtype nft_compat x_tables nft_chain_nat nf_nat nf_conntrack nf_defrag_ipv6 nf_defrag_ipv4 nf_tables overlay cfg80211 bnep mtd_intel_dg snd_hda_codec_intelhdmi mtd snd_hda_codec_hdmi nls_utf8 mxm_wmi intel_wmi_thunderbolt gigabyte_wmi wmi_bmof xe drm_gpuvm drm_gpusvm_helper i2c_algo_bit drm_buddy drm_ttm_helper ttm video drm_suballoc_helper gpu_sched drm_client_lib drm_exec drm_display_helper cec drm_kunit_helpers drm_kms_helper kunit x86_pkg_temp_thermal intel_powerclamp coretemp snd_hda_codec_alc882 snd_hda_codec_realtek_lib snd_hda_codec_generic snd_hda_intel snd_soc_avs snd_soc_hda_codec snd_hda_ext_core snd_hda_codec snd_hwdep snd_hda_core snd_intel_dspcfg snd_soc_core snd_compress ac97_bus snd_pcm snd_seq snd_seq_device snd_timer i2c_i801 i2c_mux snd i2c_smbus btusb btrtl btbcm btmtk btintel bluetooth ecdh_generic rfkill ecc mei_me mei ioatdma dca wmi nfsd drm i2c_dev fuse nfnetlink [ 743.186938] ---[ end trace 0000000000000000 ]--- And for property blobs: void drm_mode_config_cleanup(struct drm_device *dev) { ... list_for_each_entry_safe(blob, bt, &dev->mode_config.property_blob_list, head_global) { drm_property_blob_put(blob); } Resulting in: [ 371.072940] BUG: unable to handle page fault for address: 000001ffffffffff [ 371.072944] #PF: supervisor read access in kernel mode [ 371.072945] #PF: error_code(0x0000) - not-present page [ 371.072947] PGD 0 P4D 0 [ 371.072950] Oops: Oops: 0000 [#1] SMP [ 371.072953] CPU: 0 UID: 1000 PID: 3693 Comm: kwin_wayland Not tainted 7.0.0-rc1-valkyria+ #111 PREEMPT_{RT,(lazy)} [ 371.072956] Hardware name: Gigabyte Technology Co., Ltd. X299 AORUS Gaming 3/X299 AORUS Gaming 3-CF, BIOS F8n 12/06/2021 [ 371.072957] RIP: 0010:drm_property_destroy_user_blobs+0x3b/0x90 [drm] [ 371.073019] Code: 00 00 48 83 ec 10 48 8b 86 30 01 00 00 48 39 c3 74 59 48 89 c2 48 8d 48 c8 48 8b 00 4c 8d 60 c8 eb 04 4c 8d 60 c8 48 8b 71 40 <48> 39 16 0f 85 39 32 01 00 48 3b 50 08 0f 85 2f 32 01 00 48 89 70 [ 371.073021] RSP: 0018:ffffc90006a73de8 EFLAGS: 00010293 [ 371.073022] RAX: 000001ffffffffff RBX: ffff888118a1a930 RCX: ffff8881b92355c0 [ 371.073024] RDX: ffff8881b92355f8 RSI: 000001ffffffffff RDI: ffff888118be4000 [ 371.073025] RBP: ffffc90006a73e08 R08: ffff8881009b7300 R09: ffff888cecc5b000 [ 371.073026] R10: ffffc90006a73e90 R11: 0000000000000002 R12: 000001ffffffffc7 [ 371.073027] R13: ffff888118a1a980 R14: ffff88810b366d20 R15: ffff888118a1a970 [ 371.073028] FS: 00007f1faccbb280(0000) GS:ffff888cec2db000(0000) knlGS:0000000000000000 [ 371.073029] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 371.073030] CR2: 000001ffffffffff CR3: 000000010655c001 CR4: 00000000003706f0 [ 371.073031] Call Trace: [ 371.073033] <TASK> [ 371.073036] drm_file_free+0x1df/0x2a0 [drm] [ 371.073077] drm_release_noglobal+0x7a/0xe0 [drm] [ 371.073113] __fput+0xe2/0x2b0 [ 371.073118] fput_close_sync+0x40/0xa0 [ 371.073119] __x64_sys_close+0x3e/0x80 [ 371.073122] x64_sys_call+0xa07/0xa30 [ 371.073126] do_syscall_64+0xc0/0x840 [ 371.073130] entry_SYSCALL_64_after_hwframe+0x4b/0x53 [ 371.073132] RIP: 0033:0x7f1fb3501732 [ 371.073133] Code: 08 0f 85 a1 38 ff ff 49 89 fb 48 89 f0 48 89 d7 48 89 ce 4c 89 c2 4d 89 ca 4c 8b 44 24 08 4c 8b 4c 24 10 4c 89 5c 24 08 0f 05 <c3> 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 00 f3 0f 1e fa 55 bf 01 00 [ 371.073135] RSP: 002b:00007ffe8e6f0278 EFLAGS: 00000246 ORIG_RAX: 0000000000000003 [ 371.073136] RAX: ffffffffffffffda RBX: 00007ffe8e6f0300 RCX: 00007f1fb3501732 [ 371.073137] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000012 [ 371.073138] RBP: 00007ffe8e6f02a0 R08: 0000000000000000 R09: 0000000000000000 [ 371.073139] R10: 0000000000000000 R11: 0000000000000246 R12: 00005585ba46eea0 [ 371.073140] R13: 00007ffe8e6f0360 R14: 00007ffe8e6f0360 R15: 00005585ba458a30 [ 371.073143] </TASK> [ 371.073144] Modules linked in: rfcomm snd_hrtimer xt_addrtype xt_CHECKSUM xt_MASQUERADE xt_conntrack ipt_REJECT nf_reject_ipv4 xt_tcpudp nft_compat x_tables nft_chain_nat nf_nat nf_conntrack nf_defrag_ipv6 nf_defrag_ipv4 nf_tables overlay cfg80211 bnep snd_hda_codec_intelhdmi snd_hda_codec_hdmi mtd_intel_dg mtd nls_utf8 wmi_bmof mxm_wmi gigabyte_wmi intel_wmi_thunderbolt xe drm_gpuvm drm_gpusvm_helper i2c_algo_bit drm_buddy drm_ttm_helper ttm video drm_suballoc_helper gpu_sched drm_client_lib drm_exec drm_display_helper cec drm_kunit_helpers drm_kms_helper kunit x86_pkg_temp_thermal intel_powerclamp coretemp snd_hda_codec_alc882 snd_hda_codec_realtek_lib snd_hda_codec_generic snd_hda_intel snd_soc_avs snd_soc_hda_codec snd_hda_ext_core snd_hda_codec snd_hwdep snd_hda_core snd_intel_dspcfg snd_soc_core snd_compress ac97_bus snd_pcm snd_seq snd_seq_device snd_timer i2c_i801 btusb i2c_mux i2c_smbus btrtl snd btbcm btmtk btintel bluetooth ecdh_generic rfkill ecc mei_me mei ioatdma dca wmi nfsd drm i2c_dev fuse nfnetlink [ 371.073198] CR2: 000001ffffffffff [ 371.073199] ---[ end trace 0000000000000000 ]--- Signed-off-by: Maarten Lankhorst <dev@lankhorst.se> --- drivers/gpu/drm/drm_crtc_internal.h | 4 +++- drivers/gpu/drm/drm_drv.c | 3 +++ drivers/gpu/drm/drm_file.c | 5 ++++- drivers/gpu/drm/drm_framebuffer.c | 25 +++++++++++++++++++++++++ drivers/gpu/drm/drm_mode_config.c | 8 ++++++++ drivers/gpu/drm/drm_property.c | 20 ++++++++++++++++++++ 6 files changed, 63 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/drm_crtc_internal.h b/drivers/gpu/drm/drm_crtc_internal.h index c094092296448..56834596a496f 100644 --- a/drivers/gpu/drm/drm_crtc_internal.h +++ b/drivers/gpu/drm/drm_crtc_internal.h @@ -94,6 +94,7 @@ int drm_mode_setcrtc(struct drm_device *dev, /* drm_mode_config.c */ int drm_modeset_register_all(struct drm_device *dev); +void drm_modeset_unplug_all(struct drm_device *dev); void drm_modeset_unregister_all(struct drm_device *dev); void drm_mode_config_validate(struct drm_device *dev); @@ -133,6 +134,7 @@ int drm_mode_gamma_set_ioctl(struct drm_device *dev, /* drm_property.c */ void drm_property_destroy_user_blobs(struct drm_device *dev, struct drm_file *file_priv); +void drm_property_blob_unplug(struct drm_device *dev); bool drm_property_change_valid_get(struct drm_property *property, uint64_t value, struct drm_mode_object **ref); @@ -221,7 +223,7 @@ int drm_mode_addfb2(struct drm_device *dev, void *data, struct drm_file *file_priv); int drm_mode_rmfb(struct drm_device *dev, u32 fb_id, struct drm_file *file_priv); - +void drm_framebuffer_unplug(struct drm_device *dev); /* IOCTL */ int drm_mode_addfb_ioctl(struct drm_device *dev, diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index 2915118436ce8..36276ed0b74f4 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c @@ -493,6 +493,9 @@ void drm_dev_unplug(struct drm_device *dev) dev->unplugged = true; synchronize_srcu(&drm_unplug_srcu); + if (drm_core_check_feature(dev, DRIVER_MODESET)) + drm_modeset_unplug_all(dev); + drm_dev_unregister(dev); /* Clear all CPU mappings pointing to this device */ diff --git a/drivers/gpu/drm/drm_file.c b/drivers/gpu/drm/drm_file.c index ec820686b3021..f52141f842a1f 100644 --- a/drivers/gpu/drm/drm_file.c +++ b/drivers/gpu/drm/drm_file.c @@ -233,6 +233,7 @@ static void drm_events_release(struct drm_file *file_priv) void drm_file_free(struct drm_file *file) { struct drm_device *dev; + int idx; if (!file) return; @@ -249,9 +250,11 @@ void drm_file_free(struct drm_file *file) drm_events_release(file); - if (drm_core_check_feature(dev, DRIVER_MODESET)) { + if (drm_core_check_feature(dev, DRIVER_MODESET) && + drm_dev_enter(dev, &idx)) { drm_fb_release(file); drm_property_destroy_user_blobs(dev, file); + drm_dev_exit(idx); } if (drm_core_check_feature(dev, DRIVER_SYNCOBJ)) diff --git a/drivers/gpu/drm/drm_framebuffer.c b/drivers/gpu/drm/drm_framebuffer.c index 147ac19f851b2..8325bf59a5eb0 100644 --- a/drivers/gpu/drm/drm_framebuffer.c +++ b/drivers/gpu/drm/drm_framebuffer.c @@ -1236,3 +1236,28 @@ void drm_framebuffer_debugfs_init(struct drm_device *dev) ARRAY_SIZE(drm_framebuffer_debugfs_list)); } #endif + +/** + * drm_framebuffer_unplug - unplug fb from file list + * @dev: drm device + * + * This function is called from drm_dev_unplug() and removes all + * the references to framebuffers from any &struct drm_file that + * had opened one. + * + * This prevents a use-after-free when closing &struct drm_file. + * + * There is no need to call drm_framebuffer_remove, as the driver + * is now gone and will perform it's own cleanup of framebuffers. + */ +void drm_framebuffer_unplug(struct drm_device *dev) +{ + struct drm_framebuffer *fb, *next; + + list_for_each_entry_safe(fb, next, &dev->mode_config.fb_list, head) { + if (!list_empty(&fb->filp_head)) { + list_del_init(&fb->filp_head); + drm_framebuffer_put(fb); + } + } +} diff --git a/drivers/gpu/drm/drm_mode_config.c b/drivers/gpu/drm/drm_mode_config.c index 84ae8a23a3678..afe5a55276ee6 100644 --- a/drivers/gpu/drm/drm_mode_config.c +++ b/drivers/gpu/drm/drm_mode_config.c @@ -68,6 +68,14 @@ int drm_modeset_register_all(struct drm_device *dev) return ret; } +void drm_modeset_unplug_all(struct drm_device *dev) +{ + /* With drm_dev_enter() now failing, it's safe to unplug all file_priv->fb's and user mode blobs */ + drm_framebuffer_unplug(dev); + drm_property_blob_unplug(dev); + +} + void drm_modeset_unregister_all(struct drm_device *dev) { drm_connector_unregister_all(dev); diff --git a/drivers/gpu/drm/drm_property.c b/drivers/gpu/drm/drm_property.c index f38f2c5437e68..76ff53ed28917 100644 --- a/drivers/gpu/drm/drm_property.c +++ b/drivers/gpu/drm/drm_property.c @@ -1008,3 +1008,23 @@ void drm_property_change_valid_put(struct drm_property *property, } else if (drm_property_type_is(property, DRM_MODE_PROP_BLOB)) drm_property_blob_put(obj_to_blob(ref)); } + +/** + * drm_property_blob_unplug - remove all &struct drm_file references to blobs + * @dev: drm device + * + * This function is called during drm_dev_unplug(), and is intended to remove all + * references to property blobs held by all files, so they are not freed at + * file exit, but sooner. + */ +void drm_property_blob_unplug(struct drm_device *dev) +{ + struct drm_property_blob *blob, *next; + + list_for_each_entry_safe(blob, next, &dev->mode_config.property_blob_list, head_global) { + if (!list_empty(&blob->head_file)) { + list_del_init(&blob->head_file); + drm_property_blob_put(blob); + } + } +} -- 2.51.0 ^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH 1/1] drm: Fix use-after-free on framebuffers and property blobs when calling drm_dev_unplug 2026-02-25 10:15 ` [PATCH 1/1] drm: " Maarten Lankhorst @ 2026-03-10 14:07 ` Thomas Hellström 0 siblings, 0 replies; 3+ messages in thread From: Thomas Hellström @ 2026-03-10 14:07 UTC (permalink / raw) To: Maarten Lankhorst, dri-devel; +Cc: intel-xe On Wed, 2026-02-25 at 11:15 +0100, Maarten Lankhorst wrote: > When trying to do a rather aggressive test of igt's "xe_module_load > --r reload" with a full desktop environment and game running I > noticed > a few OOPSes when dereferencing freed pointers, related to > framebuffers and property blobs after the compositor exits. > > Solve this by guarding the freeing in drm_file with > drm_dev_enter/exit, > and immediately put the references from struct drm_file objects > during > drm_dev_unplug(). > > Related warnings for framebuffers on the subtest: > [ 739.713076] ------------[ cut here ]------------ > WARN_ON(!list_empty(&dev->mode_config.fb_list)) > [ 739.713079] WARNING: drivers/gpu/drm/drm_mode_config.c:584 at > drm_mode_config_cleanup+0x30b/0x320 [drm], CPU#12: > xe_module_load/13145 > [ 739.713172] Modules linked in: rfcomm snd_hrtimer xt_CHECKSUM > xt_MASQUERADE xt_conntrack ipt_REJECT nf_reject_ipv4 xt_tcpudp > xt_addrtype nft_compat x_tables nft_chain_nat nf_nat nf_conntrack > nf_defrag_ipv6 nf_defrag_ipv4 nf_tables overlay cfg80211 bnep > mtd_intel_dg snd_hda_codec_intelhdmi mtd snd_hda_codec_hdmi nls_utf8 > mxm_wmi intel_wmi_thunderbolt gigabyte_wmi wmi_bmof xe drm_gpuvm > drm_gpusvm_helper i2c_algo_bit drm_buddy drm_ttm_helper ttm video > drm_suballoc_helper gpu_sched drm_client_lib drm_exec > drm_display_helper cec drm_kunit_helpers drm_kms_helper kunit > x86_pkg_temp_thermal intel_powerclamp coretemp snd_hda_codec_alc882 > snd_hda_codec_realtek_lib snd_hda_codec_generic snd_hda_intel > snd_soc_avs snd_soc_hda_codec snd_hda_ext_core snd_hda_codec > snd_hwdep snd_hda_core snd_intel_dspcfg snd_soc_core snd_compress > ac97_bus snd_pcm snd_seq snd_seq_device snd_timer i2c_i801 i2c_mux > snd i2c_smbus btusb btrtl btbcm btmtk btintel bluetooth ecdh_generic > rfkill ecc mei_me mei ioatdma dca wmi nfsd drm i2c_dev fuse nfnetlink > [ 739.713234] CPU: 12 UID: 0 PID: 13145 Comm: xe_module_load Not > tainted 7.0.0-rc1-valkyria+ #110 PREEMPT_{RT,(lazy)} > [ 739.713239] Hardware name: Gigabyte Technology Co., Ltd. X299 > AORUS Gaming 3/X299 AORUS Gaming 3-CF, BIOS F8n 12/06/2021 > [ 739.713241] RIP: 0010:drm_mode_config_cleanup+0x30b/0x320 [drm] > [ 739.713306] Code: 70 60 48 c7 c7 7a 8d 28 a0 e8 f1 a6 00 00 48 8d > 7d 88 e8 88 75 fe ff 48 85 c0 75 e2 48 8d 7d 88 e8 1a 75 fe ff e9 a7 > fd ff ff <0f> 0b e9 d6 fe ff ff 0f 0b eb 9c e8 55 0b d2 e1 0f 1f 44 > 00 00 0f > [ 739.713309] RSP: 0018:ffffc90025003be8 EFLAGS: 00010283 > [ 739.713312] RAX: ffff88814675ba08 RBX: ffff88810d778b40 RCX: > ffffffff8217ed03 > [ 739.713314] RDX: 0000000000000000 RSI: 0000000000000000 RDI: > ffff88810d778b40 > [ 739.713316] RBP: ffffc90025003c60 R08: 0000000000000001 R09: > 0000000000000000 > [ 739.713318] R10: 0000000000000000 R11: ffff888141aeaf78 R12: > ffff88810d778000 > [ 739.713319] R13: ffff88810d778b68 R14: ffff88810d7787d8 R15: > 000000000000006c > [ 739.713321] FS: 00007f99dd0e5980(0000) GS:ffff888cec878000(0000) > knlGS:0000000000000000 > [ 739.713324] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 > [ 739.713326] CR2: 00007f9fa46bcac0 CR3: 00000004fe2b2002 CR4: > 00000000003706f0 > [ 739.713328] Call Trace: > [ 739.713330] <TASK> > [ 739.713335] ? intel_pmdemand_destroy_state+0x11/0x20 [xe] > [ 739.713574] ? intel_atomic_global_obj_cleanup+0xe4/0x1a0 [xe] > [ 739.713794] intel_display_driver_remove_noirq+0x51/0xb0 [xe] > [ 739.714041] xe_display_fini_early+0x33/0x50 [xe] > [ 739.714284] devm_action_release+0xf/0x20 > [ 739.714294] devres_release_all+0xad/0xf0 > [ 739.714301] device_unbind_cleanup+0x12/0xa0 > [ 739.714305] device_release_driver_internal+0x1b7/0x210 > [ 739.714311] device_driver_detach+0x14/0x20 > [ 739.714315] unbind_store+0xa6/0xb0 > [ 739.714319] drv_attr_store+0x21/0x30 > [ 739.714322] sysfs_kf_write+0x48/0x60 > [ 739.714328] kernfs_fop_write_iter+0x16b/0x240 > [ 739.714333] vfs_write+0x266/0x520 > [ 739.714341] ksys_write+0x72/0xe0 > [ 739.714345] __x64_sys_write+0x19/0x20 > [ 739.714347] x64_sys_call+0xa15/0xa30 > [ 739.714355] do_syscall_64+0xd8/0xab0 > [ 739.714361] entry_SYSCALL_64_after_hwframe+0x4b/0x53 > [ 739.714365] RIP: 0033:0x7f99df4aa146 > [ 739.714368] Code: 47 ba 04 00 00 00 48 8b 05 c7 0c 17 00 64 89 10 > 48 c7 c2 ff ff ff ff c9 48 89 d0 c3 0f 1f 84 00 00 00 00 00 48 8b 45 > 10 0f 05 <48> 89 c2 48 3d 00 f0 ff ff 77 0f c9 48 89 d0 c3 66 2e 0f > 1f 84 00 > [ 739.714371] RSP: 002b:00007fffe4b8fc00 EFLAGS: 00000202 ORIG_RAX: > 0000000000000001 > [ 739.714374] RAX: ffffffffffffffda RBX: 000000000000000c RCX: > 00007f99df4aa146 > [ 739.714376] RDX: 000000000000000c RSI: 00005561e56d9073 RDI: > 0000000000000004 > [ 739.714377] RBP: 00007fffe4b8fc10 R08: 0000000000000000 R09: > 0000000000000000 > [ 739.714379] R10: 0000000000000000 R11: 0000000000000202 R12: > 0000000000000004 > [ 739.714380] R13: 0000000000000000 R14: 00005561e56d9073 R15: > 00005561bb5aacf8 > [ 739.714387] </TASK> > [ 739.714389] irq event stamp: 0 > [ 739.714390] hardirqs last enabled at (0): [<0000000000000000>] > 0x0 > [ 739.714392] hardirqs last disabled at (0): [<ffffffff81317d2b>] > copy_process+0xacb/0x2220 > [ 739.714398] softirqs last enabled at (0): [<ffffffff81317d2b>] > copy_process+0xacb/0x2220 > [ 739.714401] softirqs last disabled at (0): [<0000000000000000>] > 0x0 > [ 739.714403] ---[ end trace 0000000000000000 ]--- > > .... > [ 739.714459] ------------[ cut here ]------------ > [ 739.714461] xe 0000:67:00.0: [drm] drm_WARN_ON(!list_empty(&fb- > >filp_head)) > [ 739.714464] WARNING: drivers/gpu/drm/drm_framebuffer.c:833 at > drm_framebuffer_free+0x6c/0x90 [drm], CPU#12: xe_module_load/13145 > [ 739.714596] Modules linked in: rfcomm snd_hrtimer xt_CHECKSUM > xt_MASQUERADE xt_conntrack ipt_REJECT nf_reject_ipv4 xt_tcpudp > xt_addrtype nft_compat x_tables nft_chain_nat nf_nat nf_conntrack > nf_defrag_ipv6 nf_defrag_ipv4 nf_tables overlay cfg80211 bnep > mtd_intel_dg snd_hda_codec_intelhdmi mtd snd_hda_codec_hdmi nls_utf8 > mxm_wmi intel_wmi_thunderbolt gigabyte_wmi wmi_bmof xe drm_gpuvm > drm_gpusvm_helper i2c_algo_bit drm_buddy drm_ttm_helper ttm video > drm_suballoc_helper gpu_sched drm_client_lib drm_exec > drm_display_helper cec drm_kunit_helpers drm_kms_helper kunit > x86_pkg_temp_thermal intel_powerclamp coretemp snd_hda_codec_alc882 > snd_hda_codec_realtek_lib snd_hda_codec_generic snd_hda_intel > snd_soc_avs snd_soc_hda_codec snd_hda_ext_core snd_hda_codec > snd_hwdep snd_hda_core snd_intel_dspcfg snd_soc_core snd_compress > ac97_bus snd_pcm snd_seq snd_seq_device snd_timer i2c_i801 i2c_mux > snd i2c_smbus btusb btrtl btbcm btmtk btintel bluetooth ecdh_generic > rfkill ecc mei_me mei ioatdma dca wmi nfsd drm i2c_dev fuse nfnetlink > [ 739.714704] CPU: 12 UID: 0 PID: 13145 Comm: xe_module_load > Tainted: G W 7.0.0-rc1-valkyria+ #110 > PREEMPT_{RT,(lazy)} > [ 739.714711] Tainted: [W]=WARN > [ 739.714713] Hardware name: Gigabyte Technology Co., Ltd. X299 > AORUS Gaming 3/X299 AORUS Gaming 3-CF, BIOS F8n 12/06/2021 > [ 739.714715] RIP: 0010:drm_framebuffer_free+0x7a/0x90 [drm] > [ 739.714830] Code: 48 85 d2 75 03 48 8b 17 48 89 55 e0 4c 89 45 e8 > e8 ab 40 74 e1 48 8d 3d b4 5e df ff 48 8b 55 e0 48 c7 c1 30 38 28 a0 > 48 89 c6 <67> 48 0f b9 3a 4c 8b 45 e8 eb 9f 31 ff eb c3 0f 1f 80 00 > 00 00 00 > [ 739.714842] RSP: 0018:ffffc90025003bb8 EFLAGS: 00010282 > [ 739.714846] RAX: ffffffffa0b60f69 RBX: ffff88814675ba28 RCX: > ffffffffa0283830 > [ 739.714849] RDX: ffff8881033cc9f0 RSI: ffffffffa0b60f69 RDI: > ffffffffa0235740 > [ 739.714852] RBP: ffffc90025003bd8 R08: ffff88810d778000 R09: > ffffffffa028815b > [ 739.714854] R10: 0000000000000000 R11: ffff888141aeaf78 R12: > ffff88810d778000 > [ 739.714857] R13: ffff888237f18600 R14: ffff88810d7787d8 R15: > ffffffffa04484f7 > [ 739.714859] FS: 00007f99dd0e5980(0000) GS:ffff888cec878000(0000) > knlGS:0000000000000000 > [ 739.714863] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 > [ 739.714866] CR2: 00007f9fa46bcac0 CR3: 00000004fe2b2002 CR4: > 00000000003706f0 > [ 739.714869] Call Trace: > [ 739.714871] <TASK> > [ 739.714876] drm_mode_config_cleanup+0x26a/0x320 [drm] > [ 739.714998] ? __drm_printfn_seq_file+0x20/0x20 [drm] > [ 739.715115] ? drm_mode_config_cleanup+0x207/0x320 [drm] > [ 739.715235] intel_display_driver_remove_noirq+0x51/0xb0 [xe] > [ 739.715576] xe_display_fini_early+0x33/0x50 [xe] > [ 739.715821] devm_action_release+0xf/0x20 > [ 739.715828] devres_release_all+0xad/0xf0 > [ 739.715843] device_unbind_cleanup+0x12/0xa0 > [ 739.715850] device_release_driver_internal+0x1b7/0x210 > [ 739.715856] device_driver_detach+0x14/0x20 > [ 739.715860] unbind_store+0xa6/0xb0 > [ 739.715865] drv_attr_store+0x21/0x30 > [ 739.715868] sysfs_kf_write+0x48/0x60 > [ 739.715873] kernfs_fop_write_iter+0x16b/0x240 > [ 739.715878] vfs_write+0x266/0x520 > [ 739.715886] ksys_write+0x72/0xe0 > [ 739.715890] __x64_sys_write+0x19/0x20 > [ 739.715893] x64_sys_call+0xa15/0xa30 > [ 739.715900] do_syscall_64+0xd8/0xab0 > [ 739.715905] entry_SYSCALL_64_after_hwframe+0x4b/0x53 > [ 739.715908] RIP: 0033:0x7f99df4aa146 > [ 739.715911] Code: 47 ba 04 00 00 00 48 8b 05 c7 0c 17 00 64 89 10 > 48 c7 c2 ff ff ff ff c9 48 89 d0 c3 0f 1f 84 00 00 00 00 00 48 8b 45 > 10 0f 05 <48> 89 c2 48 3d 00 f0 ff ff 77 0f c9 48 89 d0 c3 66 2e 0f > 1f 84 00 > [ 739.715913] RSP: 002b:00007fffe4b8fc00 EFLAGS: 00000202 ORIG_RAX: > 0000000000000001 > [ 739.715916] RAX: ffffffffffffffda RBX: 000000000000000c RCX: > 00007f99df4aa146 > [ 739.715918] RDX: 000000000000000c RSI: 00005561e56d9073 RDI: > 0000000000000004 > [ 739.715919] RBP: 00007fffe4b8fc10 R08: 0000000000000000 R09: > 0000000000000000 > [ 739.715921] R10: 0000000000000000 R11: 0000000000000202 R12: > 0000000000000004 > [ 739.715922] R13: 0000000000000000 R14: 00005561e56d9073 R15: > 00005561bb5aacf8 > [ 739.715929] </TASK> > [ 739.715930] irq event stamp: 0 > [ 739.715931] hardirqs last enabled at (0): [<0000000000000000>] > 0x0 > [ 739.715933] hardirqs last disabled at (0): [<ffffffff81317d2b>] > copy_process+0xacb/0x2220 > [ 739.715938] softirqs last enabled at (0): [<ffffffff81317d2b>] > copy_process+0xacb/0x2220 > [ 739.715941] softirqs last disabled at (0): [<0000000000000000>] > 0x0 > [ 739.715943] ---[ end trace 0000000000000000 ]--- > > ... > > [ 743.186530] Oops: general protection fault, probably for non- > canonical address 0xdead000000000122: 0000 [#1] SMP > [ 743.186535] CPU: 3 UID: 1000 PID: 3453 Comm: kwin_wayland Tainted: > G W 7.0.0-rc1-valkyria+ #110 PREEMPT_{RT,(lazy)} > [ 743.186537] Tainted: [W]=WARN > [ 743.186538] Hardware name: Gigabyte Technology Co., Ltd. X299 > AORUS Gaming 3/X299 AORUS Gaming 3-CF, BIOS F8n 12/06/2021 > [ 743.186539] RIP: 0010:drm_framebuffer_cleanup+0x55/0xc0 [drm] > [ 743.186588] Code: d8 72 73 0f b6 42 05 ff c3 39 c3 72 e8 49 8d bd > 50 07 00 00 31 f6 e8 3a 80 d3 e1 49 8b 44 24 10 49 8d 7c 24 08 49 8b > 54 24 08 <48> 3b 38 0f 85 95 7f 02 00 48 3b 7a 08 0f 85 8b 7f 02 00 > 48 89 42 > [ 743.186589] RSP: 0018:ffffc900085e3cf8 EFLAGS: 00010202 > [ 743.186591] RAX: dead000000000122 RBX: 0000000000000001 RCX: > ffffffff8217ed03 > [ 743.186592] RDX: dead000000000100 RSI: 0000000000000000 RDI: > ffff88814675ba08 > [ 743.186593] RBP: ffffc900085e3d10 R08: 0000000000000000 R09: > 0000000000000000 > [ 743.186593] R10: 0000000000000000 R11: 0000000000000000 R12: > ffff88814675ba00 > [ 743.186594] R13: ffff88810d778000 R14: ffff888119f6dca0 R15: > ffff88810c660bb0 > [ 743.186595] FS: 00007ff377d21280(0000) GS:ffff888cec3f8000(0000) > knlGS:0000000000000000 > [ 743.186596] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 > [ 743.186596] CR2: 000055690b55e000 CR3: 0000000113586003 CR4: > 00000000003706f0 > [ 743.186597] Call Trace: > [ 743.186598] <TASK> > [ 743.186603] intel_user_framebuffer_destroy+0x12/0x90 [xe] > [ 743.186722] drm_framebuffer_free+0x3a/0x90 [drm] > [ 743.186750] ? trace_hardirqs_on+0x5f/0x120 > [ 743.186754] drm_mode_object_put+0x51/0x70 [drm] > [ 743.186786] drm_fb_release+0x105/0x190 [drm] > [ 743.186812] ? rt_mutex_slowunlock+0x3aa/0x410 > [ 743.186817] ? rt_spin_lock+0xea/0x1b0 > [ 743.186819] drm_file_free+0x1e0/0x2c0 [drm] > [ 743.186843] drm_release_noglobal+0x91/0xf0 [drm] > [ 743.186865] __fput+0x100/0x2e0 > [ 743.186869] fput_close_sync+0x40/0xa0 > [ 743.186870] __x64_sys_close+0x3e/0x80 > [ 743.186873] x64_sys_call+0xa07/0xa30 > [ 743.186879] do_syscall_64+0xd8/0xab0 > [ 743.186881] entry_SYSCALL_64_after_hwframe+0x4b/0x53 > [ 743.186882] RIP: 0033:0x7ff37e567732 > [ 743.186884] Code: 08 0f 85 a1 38 ff ff 49 89 fb 48 89 f0 48 89 d7 > 48 89 ce 4c 89 c2 4d 89 ca 4c 8b 44 24 08 4c 8b 4c 24 10 4c 89 5c 24 > 08 0f 05 <c3> 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 00 f3 0f 1e fa 55 > bf 01 00 > [ 743.186885] RSP: 002b:00007ffc818169a8 EFLAGS: 00000246 ORIG_RAX: > 0000000000000003 > [ 743.186886] RAX: ffffffffffffffda RBX: 00007ffc81816a30 RCX: > 00007ff37e567732 > [ 743.186887] RDX: 0000000000000000 RSI: 0000000000000000 RDI: > 0000000000000012 > [ 743.186888] RBP: 00007ffc818169d0 R08: 0000000000000000 R09: > 0000000000000000 > [ 743.186889] R10: 0000000000000000 R11: 0000000000000246 R12: > 000055d60a7996e0 > [ 743.186889] R13: 00007ffc81816a90 R14: 00007ffc81816a90 R15: > 000055d60a782a30 > [ 743.186892] </TASK> > [ 743.186893] Modules linked in: rfcomm snd_hrtimer xt_CHECKSUM > xt_MASQUERADE xt_conntrack ipt_REJECT nf_reject_ipv4 xt_tcpudp > xt_addrtype nft_compat x_tables nft_chain_nat nf_nat nf_conntrack > nf_defrag_ipv6 nf_defrag_ipv4 nf_tables overlay cfg80211 bnep > mtd_intel_dg snd_hda_codec_intelhdmi mtd snd_hda_codec_hdmi nls_utf8 > mxm_wmi intel_wmi_thunderbolt gigabyte_wmi wmi_bmof xe drm_gpuvm > drm_gpusvm_helper i2c_algo_bit drm_buddy drm_ttm_helper ttm video > drm_suballoc_helper gpu_sched drm_client_lib drm_exec > drm_display_helper cec drm_kunit_helpers drm_kms_helper kunit > x86_pkg_temp_thermal intel_powerclamp coretemp snd_hda_codec_alc882 > snd_hda_codec_realtek_lib snd_hda_codec_generic snd_hda_intel > snd_soc_avs snd_soc_hda_codec snd_hda_ext_core snd_hda_codec > snd_hwdep snd_hda_core snd_intel_dspcfg snd_soc_core snd_compress > ac97_bus snd_pcm snd_seq snd_seq_device snd_timer i2c_i801 i2c_mux > snd i2c_smbus btusb btrtl btbcm btmtk btintel bluetooth ecdh_generic > rfkill ecc mei_me mei ioatdma dca wmi nfsd drm i2c_dev fuse nfnetlink > [ 743.186938] ---[ end trace 0000000000000000 ]--- > > And for property blobs: > > void drm_mode_config_cleanup(struct drm_device *dev) > { > ... > list_for_each_entry_safe(blob, bt, &dev- > >mode_config.property_blob_list, > head_global) { > drm_property_blob_put(blob); > } > > Resulting in: > > [ 371.072940] BUG: unable to handle page fault for address: > 000001ffffffffff > [ 371.072944] #PF: supervisor read access in kernel mode > [ 371.072945] #PF: error_code(0x0000) - not-present page > [ 371.072947] PGD 0 P4D 0 > [ 371.072950] Oops: Oops: 0000 [#1] SMP > [ 371.072953] CPU: 0 UID: 1000 PID: 3693 Comm: kwin_wayland Not > tainted 7.0.0-rc1-valkyria+ #111 PREEMPT_{RT,(lazy)} > [ 371.072956] Hardware name: Gigabyte Technology Co., Ltd. X299 > AORUS Gaming 3/X299 AORUS Gaming 3-CF, BIOS F8n 12/06/2021 > [ 371.072957] RIP: 0010:drm_property_destroy_user_blobs+0x3b/0x90 > [drm] > [ 371.073019] Code: 00 00 48 83 ec 10 48 8b 86 30 01 00 00 48 39 c3 > 74 59 48 89 c2 48 8d 48 c8 48 8b 00 4c 8d 60 c8 eb 04 4c 8d 60 c8 48 > 8b 71 40 <48> 39 16 0f 85 39 32 01 00 48 3b 50 08 0f 85 2f 32 01 00 > 48 89 70 > [ 371.073021] RSP: 0018:ffffc90006a73de8 EFLAGS: 00010293 > [ 371.073022] RAX: 000001ffffffffff RBX: ffff888118a1a930 RCX: > ffff8881b92355c0 > [ 371.073024] RDX: ffff8881b92355f8 RSI: 000001ffffffffff RDI: > ffff888118be4000 > [ 371.073025] RBP: ffffc90006a73e08 R08: ffff8881009b7300 R09: > ffff888cecc5b000 > [ 371.073026] R10: ffffc90006a73e90 R11: 0000000000000002 R12: > 000001ffffffffc7 > [ 371.073027] R13: ffff888118a1a980 R14: ffff88810b366d20 R15: > ffff888118a1a970 > [ 371.073028] FS: 00007f1faccbb280(0000) GS:ffff888cec2db000(0000) > knlGS:0000000000000000 > [ 371.073029] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 > [ 371.073030] CR2: 000001ffffffffff CR3: 000000010655c001 CR4: > 00000000003706f0 > [ 371.073031] Call Trace: > [ 371.073033] <TASK> > [ 371.073036] drm_file_free+0x1df/0x2a0 [drm] > [ 371.073077] drm_release_noglobal+0x7a/0xe0 [drm] > [ 371.073113] __fput+0xe2/0x2b0 > [ 371.073118] fput_close_sync+0x40/0xa0 > [ 371.073119] __x64_sys_close+0x3e/0x80 > [ 371.073122] x64_sys_call+0xa07/0xa30 > [ 371.073126] do_syscall_64+0xc0/0x840 > [ 371.073130] entry_SYSCALL_64_after_hwframe+0x4b/0x53 > [ 371.073132] RIP: 0033:0x7f1fb3501732 > [ 371.073133] Code: 08 0f 85 a1 38 ff ff 49 89 fb 48 89 f0 48 89 d7 > 48 89 ce 4c 89 c2 4d 89 ca 4c 8b 44 24 08 4c 8b 4c 24 10 4c 89 5c 24 > 08 0f 05 <c3> 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 00 f3 0f 1e fa 55 > bf 01 00 > [ 371.073135] RSP: 002b:00007ffe8e6f0278 EFLAGS: 00000246 ORIG_RAX: > 0000000000000003 > [ 371.073136] RAX: ffffffffffffffda RBX: 00007ffe8e6f0300 RCX: > 00007f1fb3501732 > [ 371.073137] RDX: 0000000000000000 RSI: 0000000000000000 RDI: > 0000000000000012 > [ 371.073138] RBP: 00007ffe8e6f02a0 R08: 0000000000000000 R09: > 0000000000000000 > [ 371.073139] R10: 0000000000000000 R11: 0000000000000246 R12: > 00005585ba46eea0 > [ 371.073140] R13: 00007ffe8e6f0360 R14: 00007ffe8e6f0360 R15: > 00005585ba458a30 > [ 371.073143] </TASK> > [ 371.073144] Modules linked in: rfcomm snd_hrtimer xt_addrtype > xt_CHECKSUM xt_MASQUERADE xt_conntrack ipt_REJECT nf_reject_ipv4 > xt_tcpudp nft_compat x_tables nft_chain_nat nf_nat nf_conntrack > nf_defrag_ipv6 nf_defrag_ipv4 nf_tables overlay cfg80211 bnep > snd_hda_codec_intelhdmi snd_hda_codec_hdmi mtd_intel_dg mtd nls_utf8 > wmi_bmof mxm_wmi gigabyte_wmi intel_wmi_thunderbolt xe drm_gpuvm > drm_gpusvm_helper i2c_algo_bit drm_buddy drm_ttm_helper ttm video > drm_suballoc_helper gpu_sched drm_client_lib drm_exec > drm_display_helper cec drm_kunit_helpers drm_kms_helper kunit > x86_pkg_temp_thermal intel_powerclamp coretemp snd_hda_codec_alc882 > snd_hda_codec_realtek_lib snd_hda_codec_generic snd_hda_intel > snd_soc_avs snd_soc_hda_codec snd_hda_ext_core snd_hda_codec > snd_hwdep snd_hda_core snd_intel_dspcfg snd_soc_core snd_compress > ac97_bus snd_pcm snd_seq snd_seq_device snd_timer i2c_i801 btusb > i2c_mux i2c_smbus btrtl snd btbcm btmtk btintel bluetooth > ecdh_generic rfkill ecc mei_me mei ioatdma dca wmi nfsd drm i2c_dev > fuse nfnetlink > [ 371.073198] CR2: 000001ffffffffff > [ 371.073199] ---[ end trace 0000000000000000 ]--- > > Signed-off-by: Maarten Lankhorst <dev@lankhorst.se> > --- > drivers/gpu/drm/drm_crtc_internal.h | 4 +++- > drivers/gpu/drm/drm_drv.c | 3 +++ > drivers/gpu/drm/drm_file.c | 5 ++++- > drivers/gpu/drm/drm_framebuffer.c | 25 +++++++++++++++++++++++++ > drivers/gpu/drm/drm_mode_config.c | 8 ++++++++ > drivers/gpu/drm/drm_property.c | 20 ++++++++++++++++++++ > 6 files changed, 63 insertions(+), 2 deletions(-) > > diff --git a/drivers/gpu/drm/drm_crtc_internal.h > b/drivers/gpu/drm/drm_crtc_internal.h > index c094092296448..56834596a496f 100644 > --- a/drivers/gpu/drm/drm_crtc_internal.h > +++ b/drivers/gpu/drm/drm_crtc_internal.h > @@ -94,6 +94,7 @@ int drm_mode_setcrtc(struct drm_device *dev, > > /* drm_mode_config.c */ > int drm_modeset_register_all(struct drm_device *dev); > +void drm_modeset_unplug_all(struct drm_device *dev); > void drm_modeset_unregister_all(struct drm_device *dev); > void drm_mode_config_validate(struct drm_device *dev); > > @@ -133,6 +134,7 @@ int drm_mode_gamma_set_ioctl(struct drm_device > *dev, > /* drm_property.c */ > void drm_property_destroy_user_blobs(struct drm_device *dev, > struct drm_file *file_priv); > +void drm_property_blob_unplug(struct drm_device *dev); > bool drm_property_change_valid_get(struct drm_property *property, > uint64_t value, > struct drm_mode_object **ref); > @@ -221,7 +223,7 @@ int drm_mode_addfb2(struct drm_device *dev, > void *data, struct drm_file *file_priv); > int drm_mode_rmfb(struct drm_device *dev, u32 fb_id, > struct drm_file *file_priv); > - > +void drm_framebuffer_unplug(struct drm_device *dev); > > /* IOCTL */ > int drm_mode_addfb_ioctl(struct drm_device *dev, > diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c > index 2915118436ce8..36276ed0b74f4 100644 > --- a/drivers/gpu/drm/drm_drv.c > +++ b/drivers/gpu/drm/drm_drv.c > @@ -493,6 +493,9 @@ void drm_dev_unplug(struct drm_device *dev) > dev->unplugged = true; > synchronize_srcu(&drm_unplug_srcu); > > + if (drm_core_check_feature(dev, DRIVER_MODESET)) > + drm_modeset_unplug_all(dev); > + I'm not 100% familiar with the modesetting code, but couldn't we be calling drm_mode_config_cleanup() as a drmm-managed cleanup? That would then be happening after the unplug, but perhaps it ends up using the wrong order? Continuing to review as if that doesn't work. > drm_dev_unregister(dev); > > /* Clear all CPU mappings pointing to this device */ > diff --git a/drivers/gpu/drm/drm_file.c b/drivers/gpu/drm/drm_file.c > index ec820686b3021..f52141f842a1f 100644 > --- a/drivers/gpu/drm/drm_file.c > +++ b/drivers/gpu/drm/drm_file.c > @@ -233,6 +233,7 @@ static void drm_events_release(struct drm_file > *file_priv) > void drm_file_free(struct drm_file *file) > { > struct drm_device *dev; > + int idx; > > if (!file) > return; > @@ -249,9 +250,11 @@ void drm_file_free(struct drm_file *file) > > drm_events_release(file); > > - if (drm_core_check_feature(dev, DRIVER_MODESET)) { > + if (drm_core_check_feature(dev, DRIVER_MODESET) && > + drm_dev_enter(dev, &idx)) { > drm_fb_release(file); > drm_property_destroy_user_blobs(dev, file); > + drm_dev_exit(idx); > } > > if (drm_core_check_feature(dev, DRIVER_SYNCOBJ)) > diff --git a/drivers/gpu/drm/drm_framebuffer.c > b/drivers/gpu/drm/drm_framebuffer.c > index 147ac19f851b2..8325bf59a5eb0 100644 > --- a/drivers/gpu/drm/drm_framebuffer.c > +++ b/drivers/gpu/drm/drm_framebuffer.c > @@ -1236,3 +1236,28 @@ void drm_framebuffer_debugfs_init(struct > drm_device *dev) > > ARRAY_SIZE(drm_framebuffer_debugfs_list)); > } > #endif > + > +/** > + * drm_framebuffer_unplug - unplug fb from file list > + * @dev: drm device > + * > + * This function is called from drm_dev_unplug() and removes all > + * the references to framebuffers from any &struct drm_file that > + * had opened one. > + * > + * This prevents a use-after-free when closing &struct drm_file. > + * > + * There is no need to call drm_framebuffer_remove, as the driver > + * is now gone and will perform it's own cleanup of framebuffers. > + */ > +void drm_framebuffer_unplug(struct drm_device *dev) > +{ > + struct drm_framebuffer *fb, *next; > + > + list_for_each_entry_safe(fb, next, &dev- > >mode_config.fb_list, head) { > + if (!list_empty(&fb->filp_head)) { > + list_del_init(&fb->filp_head); > + drm_framebuffer_put(fb); > + } > + } > +} I think this needs to be related in the docs to drm_mode_config_cleanup(). Also document in the same way why locking is not needed. > diff --git a/drivers/gpu/drm/drm_mode_config.c > b/drivers/gpu/drm/drm_mode_config.c > index 84ae8a23a3678..afe5a55276ee6 100644 > --- a/drivers/gpu/drm/drm_mode_config.c > +++ b/drivers/gpu/drm/drm_mode_config.c > @@ -68,6 +68,14 @@ int drm_modeset_register_all(struct drm_device > *dev) > return ret; > } > > +void drm_modeset_unplug_all(struct drm_device *dev) Kerneldoc > +{ > + /* With drm_dev_enter() now failing, it's safe to unplug all > file_priv->fb's and user mode blobs */ > + drm_framebuffer_unplug(dev); > + drm_property_blob_unplug(dev); > + > +} > + > void drm_modeset_unregister_all(struct drm_device *dev) > { > drm_connector_unregister_all(dev); > diff --git a/drivers/gpu/drm/drm_property.c > b/drivers/gpu/drm/drm_property.c > index f38f2c5437e68..76ff53ed28917 100644 > --- a/drivers/gpu/drm/drm_property.c > +++ b/drivers/gpu/drm/drm_property.c > @@ -1008,3 +1008,23 @@ void drm_property_change_valid_put(struct > drm_property *property, > } else if (drm_property_type_is(property, > DRM_MODE_PROP_BLOB)) > drm_property_blob_put(obj_to_blob(ref)); > } > + > +/** > + * drm_property_blob_unplug - remove all &struct drm_file references > to blobs > + * @dev: drm device > + * > + * This function is called during drm_dev_unplug(), and is intended > to remove all > + * references to property blobs held by all files, so they are not > freed at > + * file exit, but sooner. > + */ Same comment as for framebuffers. Thanks, Thomas > +void drm_property_blob_unplug(struct drm_device *dev) > +{ > + struct drm_property_blob *blob, *next; > + > + list_for_each_entry_safe(blob, next, &dev- > >mode_config.property_blob_list, head_global) { > + if (!list_empty(&blob->head_file)) { > + list_del_init(&blob->head_file); > + drm_property_blob_put(blob); > + } > + } > +} ^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-03-10 14:07 UTC | newest] Thread overview: 3+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-02-25 10:15 [PATCH 0/1] Fix use-after-free on framebuffers and property blobs when calling drm_dev_unplug Maarten Lankhorst 2026-02-25 10:15 ` [PATCH 1/1] drm: " Maarten Lankhorst 2026-03-10 14:07 ` Thomas Hellström
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).