clientmem: store more information about mappings
This commit is contained in:
parent
92f7cb56fd
commit
604974c927
6 changed files with 67 additions and 18 deletions
|
|
@ -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 {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue