Skip to content

Commit 91a459c

Browse files
committed
muvm-guest: pwbridge: actually read fd indexes in the Transport msg
The message payload contains indexes for the attached file descriptors. We must use them instead of relying on the order, which was never guaranteed, and *actually* differs in practice between architectures in compilers because current PipeWire code calls the fd-attaching function inside of function call arguments, which *don't* have a defined evaluation order in the C language standard. Signed-off-by: Val Packett <[email protected]>
1 parent 51c3960 commit 91a459c

2 files changed

Lines changed: 40 additions & 5 deletions

File tree

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -419,7 +419,7 @@ pub trait MessageResourceFinalizer {
419419
fn finalize(self, client: &mut Client<Self::Handler>) -> Result<()>;
420420
}
421421

422-
#[derive(Debug)]
422+
#[derive(Debug, Clone)]
423423
pub struct CrossDomainResource {
424424
pub identifier: u32,
425425
pub identifier_type: u32,

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

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ const CROSS_DOMAIN_CMD_READ: u8 = 6;
2121
const CROSS_DOMAIN_CMD_WRITE: u8 = 7;
2222

2323
const SPA_TYPE_STRUCT: u32 = 14;
24+
const SPA_TYPE_FD: u32 = 18;
2425

2526
const PW_OPC_CORE_CREATE_OBJECT: u8 = 6;
2627
const PW_OPC_CORE_ADD_MEM: u8 = 6;
@@ -53,6 +54,10 @@ fn read_u32(data: &[u8], at: usize) -> u32 {
5354
u32::from_ne_bytes(data[at..(at + 4)].try_into().unwrap())
5455
}
5556

57+
fn read_u64(data: &[u8], at: usize) -> u64 {
58+
u64::from_ne_bytes(data[at..(at + 8)].try_into().unwrap())
59+
}
60+
5661
#[derive(Debug)]
5762
struct CoreCreateObject<'a> {
5863
obj_type: &'a CStr,
@@ -115,6 +120,27 @@ impl<'a> ClientUpdateProperties<'a> {
115120
}
116121
}
117122

123+
#[derive(Debug)]
124+
struct ClientNodeTransport {
125+
readfd: u64,
126+
writefd: u64,
127+
// .. don't care about the remaining ones
128+
}
129+
130+
impl ClientNodeTransport {
131+
fn new(data: &[u8]) -> Self {
132+
let ty = read_u32(data, 4);
133+
assert_eq!(ty, SPA_TYPE_STRUCT);
134+
let readfd_ty = read_u32(data, 12);
135+
assert_eq!(readfd_ty, SPA_TYPE_FD);
136+
let readfd = read_u64(data, 16);
137+
let writefd_ty = read_u32(data, 28);
138+
assert_eq!(writefd_ty, SPA_TYPE_FD);
139+
let writefd = read_u64(data, 32);
140+
ClientNodeTransport { readfd, writefd }
141+
}
142+
}
143+
118144
struct PipeWireHeader {
119145
id: u32,
120146
opcode: u8,
@@ -267,10 +293,19 @@ impl ProtocolHandler for PipeWireProtocolHandler {
267293
let rsc = resources.pop_front().ok_or(Errno::EIO)?;
268294
fds.push(Self::create_guest_to_host_eventfd(this, hdr.id, rsc)?);
269295
} else if hdr.opcode == PW_OPC_CLIENT_NODE_TRANSPORT {
270-
let rsc1 = resources.pop_front().ok_or(Errno::EIO)?;
271-
fds.push(Self::create_host_to_guest_eventfd(this, hdr.id, rsc1)?);
272-
let rsc2 = resources.pop_front().ok_or(Errno::EIO)?;
273-
fds.push(Self::create_guest_to_host_eventfd(this, hdr.id, rsc2)?);
296+
let msg = ClientNodeTransport::new(&data[PipeWireHeader::SIZE..]);
297+
let writefd_rsc = resources.get(msg.writefd as _).ok_or(Errno::EIO)?;
298+
fds.push(Self::create_guest_to_host_eventfd(
299+
this,
300+
hdr.id,
301+
writefd_rsc.clone(),
302+
)?);
303+
let readfd_rsc = resources.get(msg.readfd as _).ok_or(Errno::EIO)?;
304+
fds.push(Self::create_host_to_guest_eventfd(
305+
this,
306+
hdr.id,
307+
readfd_rsc.clone(),
308+
)?);
274309
} else {
275310
unimplemented!()
276311
}

0 commit comments

Comments
 (0)