CVE-2025-71305
Description
In the Linux kernel, the following vulnerability has been resolved:
drm/display/dp_mst: Add protection against 0 vcpi
When releasing a timeslot there is a slight chance we may end up with the wrong payload mask due to overflow if the delayed_destroy_work ends up coming into play after a DP 2.1 monitor gets disconnected which causes vcpi to become 0 then we try to make the payload = ~BIT(vcpi - 1) which is a negative shift. VCPI id should never really be 0 hence skip changing the payload mask if VCPI is 0.
Otherwise it leads to <7> [515.287237] xe 0000:03:00.0: [drm:drm_dp_mst_get_port_malloc [drm_display_helper]] port ffff888126ce9000 (3) <4> [515.287267] -----------[ cut here ]----------- <3> [515.287268] UBSAN: shift-out-of-bounds in ../drivers/gpu/drm/display/drm_dp_mst_topology.c:4575:36 <3> [515.287271] shift exponent -1 is negative <4> [515.287275] CPU: 7 UID: 0 PID: 3108 Comm: kworker/u64:33 Tainted: G S U 6.17.0-rc6-lgci-xe-xe-3795-3e79699fa1b216e92+ #1 PREEMPT(voluntary) <4> [515.287279] Tainted: [S]=CPU_OUT_OF_SPEC, [U]=USER <4> [515.287279] Hardware name: ASUS System Product Name/PRIME Z790-P WIFI, BIOS 1645 03/15/2024 <4> [515.287281] Workqueue: drm_dp_mst_wq drm_dp_delayed_destroy_work [drm_display_helper] <4> [515.287303] Call Trace: <4> [515.287304] <4> [515.287306] dump_stack_lvl+0xc1/0xf0 <4> [515.287313] dump_stack+0x10/0x20 <4> [515.287316] __ubsan_handle_shift_out_of_bounds+0x133/0x2e0 <4> [515.287324] ? drm_atomic_get_private_obj_state+0x186/0x1d0 <4> [515.287333] drm_dp_atomic_release_time_slots.cold+0x17/0x3d [drm_display_helper] <4> [515.287355] mst_connector_atomic_check+0x159/0x180 [xe] <4> [515.287546] drm_atomic_helper_check_modeset+0x4d9/0xfa0 <4> [515.287550] ? __ww_mutex_lock.constprop.0+0x6f/0x1a60 <4> [515.287562] intel_atomic_check+0x119/0x2b80 [xe] <4> [515.287740] ? find_held_lock+0x31/0x90 <4> [515.287747] ? lock_release+0xce/0x2a0 <4> [515.287754] drm_atomic_check_only+0x6a2/0xb40 <4> [515.287758] ? drm_atomic_add_affected_connectors+0x12b/0x140 <4> [515.287765] drm_atomic_commit+0x6e/0xf0 <4> [515.287766] ? _pfx__drm_printfn_info+0x10/0x10 <4> [515.287774] drm_client_modeset_commit_atomic+0x25c/0x2b0 <4> [515.287794] drm_client_modeset_commit_locked+0x60/0x1b0 <4> [515.287795] ? mutex_lock_nested+0x1b/0x30 <4> [515.287801] drm_client_modeset_commit+0x26/0x50 <4> [515.287804] __drm_fb_helper_restore_fbdev_mode_unlocked+0xdc/0x110 <4> [515.287810] drm_fb_helper_hotplug_event+0x120/0x140 <4> [515.287814] drm_fbdev_client_hotplug+0x28/0xd0 <4> [515.287819] drm_client_hotplug+0x6c/0xf0 <4> [515.287824] drm_client_dev_hotplug+0x9e/0xd0 <4> [515.287829] drm_kms_helper_hotplug_event+0x1a/0x30 <4> [515.287834] drm_dp_delayed_destroy_work+0x3df/0x410 [drm_display_helper] <4> [515.287861] process_one_work+0x22b/0x6f0 <4> [515.287874] worker_thread+0x1e8/0x3d0 <4> [515.287879] ? __pfx_worker_thread+0x10/0x10 <4> [515.287882] kthread+0x11c/0x250 <4> [515.287886] ? __pfx_kthread+0x10/0x10 <4> [515.287890] ret_from_fork+0x2d7/0x310 <4> [515.287894] ? __pfx_kthread+0x10/0x10 <4> [515.287897] ret_from_fork_asm+0x1a/0x30
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
A shift-out-of-bounds vulnerability in Linux kernel's DP MST handling occurs when vcpi becomes 0, causing a negative shift when computing payload mask.
Vulnerability
In the Linux kernel, the DisplayPort Multi-Stream Transport (DP MST) timeslot release code in drivers/gpu/drm/display/drm_dp_mst_topology.c can reach a shift-out-of-bounds condition when vcpi (virtual channel payload identifier) becomes 0. This happens after a DP 2.1 monitor disconnection triggers delayed_destroy_work, which may cause the payload mask to be computed as ~BIT(vcpi - 1) — a negative shift when vcpi is 0. The bug is present in drm_dp_atomic_release_time_slots (line 4575) and affects versions prior to the fix commit ac9a7c329a5610051fc476644c9b9145a5965ecb [1].
Exploitation
An attacker requires physical or logical access to cause a DP 2.1 monitor disconnection while the kernel's delayed destroy workqueue is processing. No special privileges are needed; a user with the ability to hot-unplug a DisplayPort monitor can trigger the race condition. The code path is reachable via mst_connector_atomic_check and drm_dp_delayed_destroy_work [1].
Impact
Successful exploitation results in an undefined behavior due to the negative shift, leading to a kernel crash (UBSAN shift-out-of-bounds) and denial of service. The bug does not elevate privileges but can cause system instability or a panic. The crash trace shows the issue occurs in the Xe driver (Intel GPU driver) but affects any kernel using the shared DP MST helper code [1].
Mitigation
The fix was merged into the Linux kernel stable tree as commit ac9a7c329a5610051fc476644c9b9145a5965ecb [1]. This commit adds a check to skip changing the payload mask if vcpi is 0. Users should update to a kernel version containing this fix. No workarounds are documented; users are advised to apply the patch or wait for their distribution to backport it.
AI Insight generated on May 27, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected products
1Patches
12d6afc7539ce0drm/display/dp_mst: Add protection against 0 vcpi
1 file changed · +2 −2
drivers/gpu/drm/display/drm_dp_mst_topology.c+2 −2 modifieddiff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c b/drivers/gpu/drm/display/drm_dp_mst_topology.c index 64e5c176d5cce9..be749dcad3b585 100644 --- a/drivers/gpu/drm/display/drm_dp_mst_topology.c +++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c @@ -4572,7 +4572,8 @@ int drm_dp_atomic_release_time_slots(struct drm_atomic_state *state, if (!payload->delete) { payload->pbn = 0; payload->delete = true; - topology_state->payload_mask &= ~BIT(payload->vcpi - 1); + if (payload->vcpi > 0) + topology_state->payload_mask &= ~BIT(payload->vcpi - 1); } return 0; -- cgit 1.3-korg
95dbd525efcedrm/display/dp_mst: Add protection against 0 vcpi
1 file changed · +2 −2
drivers/gpu/drm/display/drm_dp_mst_topology.c+2 −2 modifieddiff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c b/drivers/gpu/drm/display/drm_dp_mst_topology.c index a4d84a2c8b4eca..65722f4b30ae84 100644 --- a/drivers/gpu/drm/display/drm_dp_mst_topology.c +++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c @@ -4464,7 +4464,8 @@ int drm_dp_atomic_release_time_slots(struct drm_atomic_state *state, if (!payload->delete) { payload->pbn = 0; payload->delete = true; - topology_state->payload_mask &= ~BIT(payload->vcpi - 1); + if (payload->vcpi > 0) + topology_state->payload_mask &= ~BIT(payload->vcpi - 1); } return 0; -- cgit 1.3-korg
ac9a7c329a56drm/display/dp_mst: Add protection against 0 vcpi
1 file changed · +2 −2
drivers/gpu/drm/display/drm_dp_mst_topology.c+2 −2 modifieddiff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c b/drivers/gpu/drm/display/drm_dp_mst_topology.c index 21ff7ef7ce920f..d4a5489d010c4d 100644 --- a/drivers/gpu/drm/display/drm_dp_mst_topology.c +++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c @@ -4527,7 +4527,8 @@ int drm_dp_atomic_release_time_slots(struct drm_atomic_state *state, if (!payload->delete) { payload->pbn = 0; payload->delete = true; - topology_state->payload_mask &= ~BIT(payload->vcpi - 1); + if (payload->vcpi > 0) + topology_state->payload_mask &= ~BIT(payload->vcpi - 1); } return 0; -- cgit 1.3-korg
3f44cdb5371fdrm/display/dp_mst: Add protection against 0 vcpi
1 file changed · +2 −2
drivers/gpu/drm/display/drm_dp_mst_topology.c+2 −2 modifieddiff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c b/drivers/gpu/drm/display/drm_dp_mst_topology.c index 3e5f721d754005..997f2489f00f3b 100644 --- a/drivers/gpu/drm/display/drm_dp_mst_topology.c +++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c @@ -4571,7 +4571,8 @@ int drm_dp_atomic_release_time_slots(struct drm_atomic_state *state, if (!payload->delete) { payload->pbn = 0; payload->delete = true; - topology_state->payload_mask &= ~BIT(payload->vcpi - 1); + if (payload->vcpi > 0) + topology_state->payload_mask &= ~BIT(payload->vcpi - 1); } return 0; -- cgit 1.3-korg
342ccffd9f77drm/display/dp_mst: Add protection against 0 vcpi
1 file changed · +2 −2
drivers/gpu/drm/display/drm_dp_mst_topology.c+2 −2 modifieddiff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c b/drivers/gpu/drm/display/drm_dp_mst_topology.c index 64e5c176d5cce9..be749dcad3b585 100644 --- a/drivers/gpu/drm/display/drm_dp_mst_topology.c +++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c @@ -4572,7 +4572,8 @@ int drm_dp_atomic_release_time_slots(struct drm_atomic_state *state, if (!payload->delete) { payload->pbn = 0; payload->delete = true; - topology_state->payload_mask &= ~BIT(payload->vcpi - 1); + if (payload->vcpi > 0) + topology_state->payload_mask &= ~BIT(payload->vcpi - 1); } return 0; -- cgit 1.3-korg
4d2ccdea18b5drm/display/dp_mst: Add protection against 0 vcpi
1 file changed · +2 −2
drivers/gpu/drm/display/drm_dp_mst_topology.c+2 −2 modifieddiff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c b/drivers/gpu/drm/display/drm_dp_mst_topology.c index 64e5c176d5cce9..be749dcad3b585 100644 --- a/drivers/gpu/drm/display/drm_dp_mst_topology.c +++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c @@ -4572,7 +4572,8 @@ int drm_dp_atomic_release_time_slots(struct drm_atomic_state *state, if (!payload->delete) { payload->pbn = 0; payload->delete = true; - topology_state->payload_mask &= ~BIT(payload->vcpi - 1); + if (payload->vcpi > 0) + topology_state->payload_mask &= ~BIT(payload->vcpi - 1); } return 0; -- cgit 1.3-korg
95dbd525efcedrm/display/dp_mst: Add protection against 0 vcpi
1 file changed · +2 −2
drivers/gpu/drm/display/drm_dp_mst_topology.c+2 −2 modifieddiff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c b/drivers/gpu/drm/display/drm_dp_mst_topology.c index a4d84a2c8b4eca..65722f4b30ae84 100644 --- a/drivers/gpu/drm/display/drm_dp_mst_topology.c +++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c @@ -4464,7 +4464,8 @@ int drm_dp_atomic_release_time_slots(struct drm_atomic_state *state, if (!payload->delete) { payload->pbn = 0; payload->delete = true; - topology_state->payload_mask &= ~BIT(payload->vcpi - 1); + if (payload->vcpi > 0) + topology_state->payload_mask &= ~BIT(payload->vcpi - 1); } return 0; -- cgit 1.3-korg
d6afc7539ce0drm/display/dp_mst: Add protection against 0 vcpi
1 file changed · +2 −2
drivers/gpu/drm/display/drm_dp_mst_topology.c+2 −2 modifieddiff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c b/drivers/gpu/drm/display/drm_dp_mst_topology.c index 64e5c176d5cce9..be749dcad3b585 100644 --- a/drivers/gpu/drm/display/drm_dp_mst_topology.c +++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c @@ -4572,7 +4572,8 @@ int drm_dp_atomic_release_time_slots(struct drm_atomic_state *state, if (!payload->delete) { payload->pbn = 0; payload->delete = true; - topology_state->payload_mask &= ~BIT(payload->vcpi - 1); + if (payload->vcpi > 0) + topology_state->payload_mask &= ~BIT(payload->vcpi - 1); } return 0; -- cgit 1.3-korg
3f44cdb5371fdrm/display/dp_mst: Add protection against 0 vcpi
1 file changed · +2 −2
drivers/gpu/drm/display/drm_dp_mst_topology.c+2 −2 modifieddiff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c b/drivers/gpu/drm/display/drm_dp_mst_topology.c index 3e5f721d754005..997f2489f00f3b 100644 --- a/drivers/gpu/drm/display/drm_dp_mst_topology.c +++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c @@ -4571,7 +4571,8 @@ int drm_dp_atomic_release_time_slots(struct drm_atomic_state *state, if (!payload->delete) { payload->pbn = 0; payload->delete = true; - topology_state->payload_mask &= ~BIT(payload->vcpi - 1); + if (payload->vcpi > 0) + topology_state->payload_mask &= ~BIT(payload->vcpi - 1); } return 0; -- cgit 1.3-korg
342ccffd9f77drm/display/dp_mst: Add protection against 0 vcpi
1 file changed · +2 −2
drivers/gpu/drm/display/drm_dp_mst_topology.c+2 −2 modifieddiff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c b/drivers/gpu/drm/display/drm_dp_mst_topology.c index 64e5c176d5cce9..be749dcad3b585 100644 --- a/drivers/gpu/drm/display/drm_dp_mst_topology.c +++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c @@ -4572,7 +4572,8 @@ int drm_dp_atomic_release_time_slots(struct drm_atomic_state *state, if (!payload->delete) { payload->pbn = 0; payload->delete = true; - topology_state->payload_mask &= ~BIT(payload->vcpi - 1); + if (payload->vcpi > 0) + topology_state->payload_mask &= ~BIT(payload->vcpi - 1); } return 0; -- cgit 1.3-korg
4d2ccdea18b5drm/display/dp_mst: Add protection against 0 vcpi
1 file changed · +2 −2
drivers/gpu/drm/display/drm_dp_mst_topology.c+2 −2 modifieddiff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c b/drivers/gpu/drm/display/drm_dp_mst_topology.c index 64e5c176d5cce9..be749dcad3b585 100644 --- a/drivers/gpu/drm/display/drm_dp_mst_topology.c +++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c @@ -4572,7 +4572,8 @@ int drm_dp_atomic_release_time_slots(struct drm_atomic_state *state, if (!payload->delete) { payload->pbn = 0; payload->delete = true; - topology_state->payload_mask &= ~BIT(payload->vcpi - 1); + if (payload->vcpi > 0) + topology_state->payload_mask &= ~BIT(payload->vcpi - 1); } return 0; -- cgit 1.3-korg
ac9a7c329a56drm/display/dp_mst: Add protection against 0 vcpi
1 file changed · +2 −2
drivers/gpu/drm/display/drm_dp_mst_topology.c+2 −2 modifieddiff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c b/drivers/gpu/drm/display/drm_dp_mst_topology.c index 21ff7ef7ce920f..d4a5489d010c4d 100644 --- a/drivers/gpu/drm/display/drm_dp_mst_topology.c +++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c @@ -4527,7 +4527,8 @@ int drm_dp_atomic_release_time_slots(struct drm_atomic_state *state, if (!payload->delete) { payload->pbn = 0; payload->delete = true; - topology_state->payload_mask &= ~BIT(payload->vcpi - 1); + if (payload->vcpi > 0) + topology_state->payload_mask &= ~BIT(payload->vcpi - 1); } return 0; -- cgit 1.3-korg
Vulnerability mechanics
Root cause
"Missing guard against a zero vcpi value in drm_dp_atomic_release_time_slots causes a negative shift operation (BIT(vcpi - 1)) when vcpi is 0."
Attack vector
An attacker with physical access can trigger this by disconnecting a DP 2.1 MST monitor while the delayed_destroy_work is still pending. The workqueue callback drm_dp_delayed_destroy_work eventually calls drm_dp_atomic_release_time_slots, where payload->vcpi may already be 0. The expression ~BIT(vcpi - 1) then computes BIT(-1), which is a negative shift exponent, causing a UBSAN shift-out-of-bounds error [patch_id=2662190]. The bug is reachable from the kernel workqueue drm_dp_mst_wq and does not require any special privileges beyond the ability to hot-unplug a DP MST display.
Affected code
The vulnerable function is `drm_dp_atomic_release_time_slots` in `drivers/gpu/drm/display/drm_dp_mst_topology.c` [patch_id=2662190]. The faulting line is `topology_state->payload_mask &= ~BIT(payload->vcpi - 1)` at line 4572 (or 4464/4527 depending on kernel version), where `payload->vcpi` can be 0, making the shift exponent -1.
What the fix does
The patch adds a guard condition `if (payload->vcpi > 0)` before the `topology_state->payload_mask &= ~BIT(payload->vcpi - 1)` operation [patch_id=2662190]. This ensures that when vcpi is 0 (which can happen after a DP 2.1 monitor disconnect races with delayed_destroy_work), the payload mask is left unchanged instead of performing an undefined negative shift. The commit message explains that VCPI id should never really be 0, so skipping the mask update in that case is safe.
Preconditions
- inputA DP 2.1 MST monitor must be connected and then disconnected while delayed_destroy_work is pending
- configThe kernel must have CONFIG_UBSAN enabled to observe the crash (though undefined behavior occurs regardless)
Generated on May 27, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
6- git.kernel.org/stable/c/342ccffd9f77fc29fe1c05fd145e4d842bd2feaanvd
- git.kernel.org/stable/c/3f44cdb5371faf225af37d5caba8f21ec0572469nvd
- git.kernel.org/stable/c/4d2ccdea18b564e3f73e3e543854acea64e6277dnvd
- git.kernel.org/stable/c/95dbd525efce2a9e9e1c50ad15213de644c85ad0nvd
- git.kernel.org/stable/c/ac9a7c329a5610051fc476644c9b9145a5965ecbnvd
- git.kernel.org/stable/c/d6afc7539ce06dadfa5b4787b3cfe79b95d8f67anvd
News mentions
0No linked articles in our index yet.