From 32993a9ee51dde8794f2f492f4cda9720ca36333 Mon Sep 17 00:00:00 2001 From: Admin Pupkin Date: Tue, 9 Jun 2026 14:56:46 +0300 Subject: [PATCH] redox-drm: validate connector state in atomic_check (Gap 8 fix) atomic_check previously ignored the _available_connectors parameter (prevented by underscore prefix). The CRTC state's connectors: Vec field declared which connectors to bind, but atomic_check never verified they actually existed or were connected. This allowed client commits to reference phantom or disconnected connectors and silently produce invalid state. Fix: use the available_connectors slice to validate that each referenced connector ID exists in hardware and has connection status Connected. Return CrtcNotFound or ConnectorDisconnected respectively so the kernel rejects invalid commits with a clear error rather than producing a malformed display state. This unblocks libdrm drmModeAtomicCommit callers that rely on DRM_MODE_ATOMIC_ALLOW_MODESET returning success only for valid connector configurations. --- .../gpu/redox-drm/source/src/kms/atomic.rs | 20 +++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/local/recipes/gpu/redox-drm/source/src/kms/atomic.rs b/local/recipes/gpu/redox-drm/source/src/kms/atomic.rs index 4ac0376d87..3d9bffbd39 100644 --- a/local/recipes/gpu/redox-drm/source/src/kms/atomic.rs +++ b/local/recipes/gpu/redox-drm/source/src/kms/atomic.rs @@ -1,6 +1,6 @@ -use super::{ConnectorInfo, ModeInfo}; +use super::{ConnectorInfo, ConnectorStatus, ModeInfo}; /// Maximum pixel clock in kHz that the display engine supports. const MAX_PIXEL_CLOCK_KHZ: u32 = 600_000; @@ -125,7 +125,7 @@ pub enum AtomicCheckResult { /// Validate the atomic state against hardware constraints. pub fn atomic_check( state: &AtomicState, - _available_connectors: &[ConnectorInfo], + available_connectors: &[ConnectorInfo], ) -> AtomicCheckResult { for crtc in &state.crtc_states { if !crtc.active { @@ -175,6 +175,22 @@ pub fn atomic_check( reason: "active CRTC has no framebuffer assigned".into(), }; } + + for conn_id in &crtc.connectors { + match available_connectors.iter().find(|c| c.id == *conn_id) { + None => { + return AtomicCheckResult::CrtcNotFound { + crtc_id: *conn_id, + }; + } + Some(conn) if conn.connection != ConnectorStatus::Connected => { + return AtomicCheckResult::ConnectorDisconnected { + connector_id: *conn_id, + }; + } + Some(_) => {} + } + } } AtomicCheckResult::Ok