mirror of
https://github.com/rustdesk/rustdesk.git
synced 2026-09-15 00:41:01 +03:00
drm: never latch the uinput refresh slot, and bound the source stride
The uinput refresh worker released UINPUT_REFRESH_BUSY on its two normal exits only. The body locks several process-wide mutexes and does a Wayland roundtrip, so an unwind there left the flag set for the process lifetime, and every later hotplug then skipped the spawn and never reapplied the uinput ABS range: the stale-range, wrong-output symptom the refresh exists to prevent. This file already had the answer for the probe flag, one screen away, and the hazard is called out in wayland.rs. Fixing one site and not the other is the same miss as the hotplug maps. The slot is deliberately handed back and re-taken mid-loop, so the guard tracks ownership rather than releasing unconditionally: a plain RAII drop would clear a flag a replacement worker owns. drm_reader bounded only the destination (w*4*h) while the row loop reads up to (h-1)*stride + w*4, so a large stride read past the mapping and could overflow usize in y*stride. drm_render::convert already bounds stride*h; the privileged half must not be the weaker of the two. Also give the drm CI jobs a timeout, so a hung meson or vcpkg step fails in an hour instead of six.
This commit is contained in:
@@ -256,6 +256,24 @@ impl DrmReader {
|
||||
));
|
||||
}
|
||||
};
|
||||
// Bound the SOURCE extent too, not just the destination. The row loop below reads up to
|
||||
// (h-1)*stride + w*4, so a large stride reads far past the mapping however small the
|
||||
// destination is, and `y * stride` can overflow usize on the way. drm_render::convert
|
||||
// bounds stride*h the same way; the two halves of the split must agree about what they
|
||||
// are willing to touch, or the privileged half is the weaker one.
|
||||
match stride.checked_mul(h) {
|
||||
Some(sz) if sz > 0 && sz <= MAX_FRAME_BYTES => {}
|
||||
other => {
|
||||
log::warn!(
|
||||
"DRM scanout stride {stride} x {h} rows is out of range ({other:?} bytes); falling back"
|
||||
);
|
||||
(self.lib.frame_release)(self.ctx, &mut frame);
|
||||
return Err(io::Error::new(
|
||||
io::ErrorKind::Other,
|
||||
"DRM scanout stride out of range",
|
||||
));
|
||||
}
|
||||
}
|
||||
if self.buf.len() != frame_size {
|
||||
self.buf.resize(frame_size, 0);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user