Skip to content

Commit 1e1bc76

Browse files
valpackettslp
authored andcommitted
rutabaga: do not rely on seals to detect read-only shm fds
Some compositors send read-only but not sealed memfds (at least wlroots does so for dmabuf feedback), so seal-based permission detection would result in mapping RO memory as RW and the guest application crashing. Fix by properly checking the access mode. Keep seal detection because e.g. Smithay based compositors do send O_RDWR but write-sealed memfds. Upstream rutabaga does not do any detection yet, but defaults to RO for all shm/memfd (!!) and RW for dmabuf. Signed-off-by: Val Packett <val@invisiblethingslab.com>
1 parent 285551f commit 1e1bc76

1 file changed

Lines changed: 15 additions & 6 deletions

File tree

  • src/rutabaga_gfx/src/cross_domain

src/rutabaga_gfx/src/cross_domain/mod.rs

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1122,15 +1122,27 @@ impl RutabagaContext for CrossDomainContext {
11221122
.remove(&item_id)
11231123
.ok_or(RutabagaError::InvalidCrossDomainItemId)?;
11241124

1125+
fn access_mode(descriptor: &SafeDescriptor) -> RutabagaResult<u32> {
1126+
Ok(
1127+
match fcntl(descriptor.as_fd(), FcntlArg::F_GETFL)? & libc::O_ACCMODE {
1128+
libc::O_RDWR => RUTABAGA_MAP_ACCESS_RW,
1129+
libc::O_WRONLY => RUTABAGA_MAP_ACCESS_WRITE,
1130+
_ => RUTABAGA_MAP_ACCESS_READ,
1131+
// (there is a "secret fourth option" O_WRONLY|O_RDWR meaning "no access", very unlikely we'd see it)
1132+
},
1133+
)
1134+
}
1135+
11251136
// Items that are removed from the table after one usage.
11261137
match item {
11271138
CrossDomainItem::ShmBlob(descriptor) => {
11281139
#[allow(unused_mut)]
1129-
let mut access = RUTABAGA_MAP_ACCESS_RW;
1140+
let mut access = access_mode(&descriptor)?;
1141+
// Some compositors actually do send descriptors that are O_RDWR but write-sealed (!)
11301142
#[cfg(target_os = "linux")]
11311143
if fcntl(&descriptor, FcntlArg::F_GET_SEALS)? & libc::F_SEAL_WRITE != 0 {
11321144
access &= !RUTABAGA_MAP_ACCESS_WRITE;
1133-
};
1145+
}
11341146

11351147
let hnd = RutabagaHandle {
11361148
os_handle: descriptor,
@@ -1156,10 +1168,7 @@ impl RutabagaContext for CrossDomainContext {
11561168
})
11571169
}
11581170
CrossDomainItem::DmaBuf(descriptor) => {
1159-
let mut access = RUTABAGA_MAP_ACCESS_READ;
1160-
if fcntl(descriptor.as_fd(), FcntlArg::F_GETFL)? & libc::O_WRONLY != 0 {
1161-
access |= RUTABAGA_MAP_ACCESS_WRITE;
1162-
}
1171+
let access = access_mode(&descriptor)?;
11631172

11641173
let hnd = RutabagaHandle {
11651174
os_handle: descriptor,

0 commit comments

Comments
 (0)