Skip to content

Commit 29ab248

Browse files
brainromslp
authored andcommitted
muvm-guest, x11: fix stream reassembly
Signed-off-by: Ilya Chelyadin <[email protected]>
1 parent 87bea57 commit 29ab248

2 files changed

Lines changed: 45 additions & 24 deletions

File tree

crates/muvm/src/guest/bridge/common.rs

Lines changed: 34 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -595,13 +595,13 @@ impl<'a, P: ProtocolHandler> Client<'a, P> {
595595
identifier_sizes: [0; CROSS_DOMAIN_MAX_IDENTIFIERS],
596596
data: [0u8; CROSS_DOMAIN_SR_TAIL_SIZE],
597597
};
598+
let head_len = self.request_head.len();
598599
let recv_buf = if self.request_tail > 0 {
599600
assert!(self.request_head.is_empty());
600601
assert!(self.request_fds.is_empty());
601602
let len = self.request_tail.min(ring_msg.data.len());
602603
&mut ring_msg.data[..len]
603604
} else {
604-
let head_len = self.request_head.len();
605605
ring_msg.data[..head_len].copy_from_slice(&self.request_head);
606606
self.request_head.clear();
607607
&mut ring_msg.data[head_len..]
@@ -629,35 +629,46 @@ impl<'a, P: ProtocolHandler> Client<'a, P> {
629629
} else {
630630
return Ok(true);
631631
};
632-
let buf = &mut ring_msg.data[..len];
632+
let buf_len = head_len + len;
633+
let buf = &mut ring_msg.data[..buf_len];
634+
633635
self.debug_loop.loop_local(buf);
634636
let mut resources = Vec::new();
635637
let mut finalizers = Vec::new();
638+
639+
let mut ptr = 0;
640+
// Drain outstanding tail bytes first, then parse any remaining data.
636641
if self.request_tail > 0 {
637642
assert!(self.request_fds.is_empty());
638-
self.request_tail -= buf.len();
639-
} else {
640-
let mut ptr = 0;
641-
while ptr < buf.len() {
642-
match P::process_send_stream(self, &mut buf[ptr..])? {
643-
StreamSendResult::WantMore => break,
644-
StreamSendResult::Processed {
645-
resources: rs,
646-
finalizers: fns,
647-
consumed_bytes: msg_size,
648-
} => {
649-
ptr += msg_size;
650-
resources.extend(rs);
651-
finalizers.extend(fns);
652-
},
653-
}
654-
}
655-
if ptr < buf.len() {
656-
self.request_head = buf[ptr..].to_vec();
657-
} else {
658-
self.request_tail = ptr - buf.len();
643+
644+
let consumed = self.request_tail.min(buf.len());
645+
self.request_tail -= consumed;
646+
ptr += consumed;
647+
}
648+
649+
while ptr < buf.len() {
650+
match P::process_send_stream(self, &mut buf[ptr..])? {
651+
StreamSendResult::WantMore => break,
652+
StreamSendResult::Processed {
653+
resources: rs,
654+
finalizers: fns,
655+
consumed_bytes: msg_size,
656+
} => {
657+
ptr += msg_size;
658+
resources.extend(rs);
659+
finalizers.extend(fns);
660+
},
659661
}
660662
}
663+
664+
if ptr > buf.len() {
665+
// Track logical over-consumption
666+
self.request_tail = ptr - buf.len();
667+
} else if ptr < buf.len() {
668+
// Preserve leftovers
669+
self.request_head = buf[ptr..].to_vec();
670+
}
671+
661672
if !self.request_head.is_empty() {
662673
assert_eq!(self.request_tail, 0);
663674
}

crates/muvm/src/guest/bridge/x11.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -304,8 +304,18 @@ impl ProtocolHandler for X11ProtocolHandler {
304304
req_len = u32::from_ne_bytes(buf[4..8].try_into().unwrap()) as usize * 4;
305305
}
306306
if buf[0] == X11_OPCODE_QUERY_EXTENSION {
307+
if buf.len() < 8 {
308+
return Ok(StreamSendResult::WantMore);
309+
}
310+
307311
let namelen = u16::from_ne_bytes(buf[4..6].try_into().unwrap()) as usize;
308-
let name = String::from_utf8_lossy(&buf[8..(8 + namelen)]);
312+
let end = 8 + namelen;
313+
314+
if buf.len() < end {
315+
return Ok(StreamSendResult::WantMore);
316+
}
317+
318+
let name = String::from_utf8_lossy(&buf[8..end]);
309319
if name == "DRI3" {
310320
this.protocol_handler.dri3_qe_resp_seq = Some(this.protocol_handler.seq_no);
311321
} else if name == "SYNC" {

0 commit comments

Comments
 (0)