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<u32> 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.
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
|
|
||||||
use super::{ConnectorInfo, ModeInfo};
|
use super::{ConnectorInfo, ConnectorStatus, ModeInfo};
|
||||||
|
|
||||||
/// Maximum pixel clock in kHz that the display engine supports.
|
/// Maximum pixel clock in kHz that the display engine supports.
|
||||||
const MAX_PIXEL_CLOCK_KHZ: u32 = 600_000;
|
const MAX_PIXEL_CLOCK_KHZ: u32 = 600_000;
|
||||||
@@ -125,7 +125,7 @@ pub enum AtomicCheckResult {
|
|||||||
/// Validate the atomic state against hardware constraints.
|
/// Validate the atomic state against hardware constraints.
|
||||||
pub fn atomic_check(
|
pub fn atomic_check(
|
||||||
state: &AtomicState,
|
state: &AtomicState,
|
||||||
_available_connectors: &[ConnectorInfo],
|
available_connectors: &[ConnectorInfo],
|
||||||
) -> AtomicCheckResult {
|
) -> AtomicCheckResult {
|
||||||
for crtc in &state.crtc_states {
|
for crtc in &state.crtc_states {
|
||||||
if !crtc.active {
|
if !crtc.active {
|
||||||
@@ -175,6 +175,22 @@ pub fn atomic_check(
|
|||||||
reason: "active CRTC has no framebuffer assigned".into(),
|
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
|
AtomicCheckResult::Ok
|
||||||
|
|||||||
Reference in New Issue
Block a user