1
0
Fork 0
forked from wry/wry

clientmem: store more information about mappings

This commit is contained in:
Julian Orth 2024-09-07 17:00:08 +02:00
parent 92f7cb56fd
commit 604974c927
6 changed files with 67 additions and 18 deletions

View file

@ -1,5 +1,5 @@
use {
crate::utils::vec_ext::VecExt,
crate::{client::Client, utils::vec_ext::VecExt},
std::{
cell::Cell,
mem::MaybeUninit,
@ -8,7 +8,10 @@ use {
sync::atomic::{compiler_fence, Ordering},
},
thiserror::Error,
uapi::{c, c::raise},
uapi::{
c::{self, raise},
OwnedFd,
},
};
#[derive(Debug, Error)]
@ -22,6 +25,7 @@ pub enum ClientMemError {
}
pub struct ClientMem {
fd: Rc<OwnedFd>,
failed: Cell<bool>,
sigbus_impossible: bool,
data: *const [Cell<u8>],
@ -30,19 +34,34 @@ pub struct ClientMem {
#[derive(Clone)]
pub struct ClientMemOffset {
mem: Rc<ClientMem>,
offset: usize,
data: *const [Cell<u8>],
}
impl ClientMem {
pub fn new(fd: i32, len: usize, read_only: bool) -> Result<Self, ClientMemError> {
pub fn new(
fd: &Rc<OwnedFd>,
len: usize,
read_only: bool,
client: Option<&Client>,
) -> Result<Self, ClientMemError> {
let mut sigbus_impossible = false;
if let Ok(seals) = uapi::fcntl_get_seals(fd) {
if let Ok(seals) = uapi::fcntl_get_seals(fd.raw()) {
if seals & c::F_SEAL_SHRINK != 0 {
if let Ok(stat) = uapi::fstat(fd) {
if let Ok(stat) = uapi::fstat(fd.raw()) {
sigbus_impossible = stat.st_size as u64 >= len as u64;
}
}
}
if !sigbus_impossible {
if let Some(client) = client {
log::debug!(
"Client {} ({}) has created a shm buffer that might cause SIGBUS",
client.pid_info.comm,
client.id,
);
}
}
let data = if len == 0 {
&mut [][..]
} else {
@ -51,7 +70,7 @@ impl ClientMem {
false => c::PROT_READ | c::PROT_WRITE,
};
unsafe {
let data = c::mmap64(ptr::null_mut(), len, prot, c::MAP_SHARED, fd, 0);
let data = c::mmap64(ptr::null_mut(), len, prot, c::MAP_SHARED, fd.raw(), 0);
if data == c::MAP_FAILED {
return Err(ClientMemError::MmapFailed(uapi::Errno::default().into()));
}
@ -59,6 +78,7 @@ impl ClientMem {
}
};
Ok(Self {
fd: fd.clone(),
failed: Cell::new(false),
sigbus_impossible,
data,
@ -73,12 +93,38 @@ impl ClientMem {
let mem = unsafe { &*self.data };
ClientMemOffset {
mem: self.clone(),
offset,
data: &mem[offset..],
}
}
#[expect(dead_code)]
pub fn fd(&self) -> &Rc<OwnedFd> {
&self.fd
}
#[expect(dead_code)]
pub fn sigbus_impossible(&self) -> bool {
self.sigbus_impossible
}
}
impl ClientMemOffset {
#[expect(dead_code)]
pub fn pool(&self) -> &ClientMem {
&self.mem
}
#[expect(dead_code)]
pub fn offset(&self) -> usize {
self.offset
}
#[expect(dead_code)]
pub fn ptr(&self) -> *const [Cell<u8>] {
self.data
}
pub fn access<T, F: FnOnce(&[Cell<u8>]) -> T>(&self, f: F) -> Result<T, ClientMemError> {
unsafe {
if self.mem.sigbus_impossible {