From 518095c7c2254e6799b8e9996708b3c5421ceeb5 Mon Sep 17 00:00:00 2001 From: Julian Orth Date: Fri, 27 Feb 2026 20:06:22 +0100 Subject: [PATCH] shm: limit data accessed by ClientMemOffset --- src/cli/input.rs | 7 +++---- src/clientmem.rs | 4 ++-- src/ifs/jay_input.rs | 5 +++-- src/ifs/wl_buffer.rs | 5 +++-- src/ifs/wl_seat/zwp_virtual_keyboard_v1.rs | 15 +++++---------- src/ifs/zwlr_gamma_control_v1.rs | 11 +++++------ src/it/tests/t0040_virtual_keyboard.rs | 5 +++-- 7 files changed, 24 insertions(+), 28 deletions(-) diff --git a/src/cli/input.rs b/src/cli/input.rs index 2506cbb0..62e76487 100644 --- a/src/cli/input.rs +++ b/src/cli/input.rs @@ -427,10 +427,9 @@ impl Input { async fn handle_keymap(&self, input: JayInputId) -> Vec { let data = Rc::new(RefCell::new(Vec::new())); jay_input::Keymap::handle(&self.tc, input, data.clone(), |d, map| { - let mem = Rc::new( - ClientMem::new_private(&map.keymap, map.keymap_len as _, true, None, None).unwrap(), - ) - .offset(0); + let len = map.keymap_len as _; + let mem = Rc::new(ClientMem::new_private(&map.keymap, len, true, None, None).unwrap()) + .offset(0, len); mem.read(d.borrow_mut().deref_mut()).unwrap(); }); self.tc.round_trip().await; diff --git a/src/clientmem.rs b/src/clientmem.rs index 8cb6a4fa..f19b212f 100644 --- a/src/clientmem.rs +++ b/src/clientmem.rs @@ -131,12 +131,12 @@ impl ClientMem { self.data.len() } - pub fn offset(self: &Rc, offset: usize) -> ClientMemOffset { + pub fn offset(self: &Rc, offset: usize, len: usize) -> ClientMemOffset { let mem = unsafe { &*self.data }; ClientMemOffset { mem: self.clone(), offset, - data: &mem[offset..], + data: &mem[offset..][..len], } } diff --git a/src/ifs/jay_input.rs b/src/ifs/jay_input.rs index a06a2505..cfac6e6c 100644 --- a/src/ifs/jay_input.rs +++ b/src/ifs/jay_input.rs @@ -197,14 +197,15 @@ impl JayInput { where F: FnOnce(&Rc) -> Result<(), JayInputError>, { + let len = len as _; let cm = Rc::new(ClientMem::new_private( keymap, - len as _, + len, true, Some(&self.client), None, )?) - .offset(0); + .offset(0, len); let mut map = vec![]; cm.read(&mut map)?; self.or_error(|| { diff --git a/src/ifs/wl_buffer.rs b/src/ifs/wl_buffer.rs index c698eef1..331dc9f2 100644 --- a/src/ifs/wl_buffer.rs +++ b/src/ifs/wl_buffer.rs @@ -147,7 +147,8 @@ impl WlBuffer { if required > mem.len() as u64 { return Err(WlBufferError::OutOfBounds); } - let mem = Rc::new(mem.offset(offset)); + let size = bytes as usize; + let mem = Rc::new(mem.offset(offset, size)); let min_row_size = width as u64 * format.bpp as u64; if (stride as u64) < min_row_size { return Err(WlBufferError::StrideTooSmall); @@ -155,7 +156,7 @@ impl WlBuffer { let udmabuf_impossible = !mem.pool().is_sealed_memfd(); let dmabuf_buffer_params = match udmabuf { None => DmabufBufferParams { - size: bytes as usize, + size, udmabuf: None, udmabuf_offset: 0, udmabuf_size: 0, diff --git a/src/ifs/wl_seat/zwp_virtual_keyboard_v1.rs b/src/ifs/wl_seat/zwp_virtual_keyboard_v1.rs index 07fb90db..ceaec57b 100644 --- a/src/ifs/wl_seat/zwp_virtual_keyboard_v1.rs +++ b/src/ifs/wl_seat/zwp_virtual_keyboard_v1.rs @@ -58,18 +58,13 @@ impl ZwpVirtualKeyboardV1RequestHandler for ZwpVirtualKeyboardV1 { if req.size > MAX_SIZE { return Err(ZwpVirtualKeyboardV1Error::OversizedKeymap); } - let client_mem = ClientMem::new_private( - &req.fd, - req.size as usize - 1, - true, - Some(&self.client), - None, - ) - .map(Rc::new) - .map_err(ZwpVirtualKeyboardV1Error::MapKeymap)?; + let size = req.size as usize - 1; + let client_mem = ClientMem::new_private(&req.fd, size, true, Some(&self.client), None) + .map(Rc::new) + .map_err(ZwpVirtualKeyboardV1Error::MapKeymap)?; let mut map = vec![]; client_mem - .offset(0) + .offset(0, size) .read(&mut map) .map_err(ZwpVirtualKeyboardV1Error::ReadKeymap)?; let map = self diff --git a/src/ifs/zwlr_gamma_control_v1.rs b/src/ifs/zwlr_gamma_control_v1.rs index 0e361702..8467c6d1 100644 --- a/src/ifs/zwlr_gamma_control_v1.rs +++ b/src/ifs/zwlr_gamma_control_v1.rs @@ -111,22 +111,21 @@ impl ZwlrGammaControlV1RequestHandler for ZwlrGammaControlV1 { return Ok(()); }; - // 3 color channels - let data_size = gamma_lut_size * 3; + // 3 color channels of u16 + let data_size = size_of::() * (3 * gamma_lut_size) as usize; let mut gamma_lut = vec![]; Rc::new(ClientMem::new_private( &req.fd, - (2 * data_size) as _, + data_size, true, Some(&self.client), None, )?) - .offset(0) + .offset(0, data_size) .read(&mut gamma_lut)?; - let gamma_lut = &gamma_lut[..data_size as _]; - let gamma_lut = wayland_gamma_lut_to_drm_gamma_lut(gamma_lut); + let gamma_lut = wayland_gamma_lut_to_drm_gamma_lut(&gamma_lut); let gamma_lut = Rc::new(BackendGammaLut::new(gamma_lut)); if node.set_gamma_lut(Some(gamma_lut)).is_err() { fail(); diff --git a/src/it/tests/t0040_virtual_keyboard.rs b/src/it/tests/t0040_virtual_keyboard.rs index b8d125cc..bcb0db4b 100644 --- a/src/it/tests/t0040_virtual_keyboard.rs +++ b/src/it/tests/t0040_virtual_keyboard.rs @@ -149,8 +149,9 @@ async fn test(run: Rc) -> TestResult { } fn read_keymap(fd: &Rc, size: usize) -> String { - let client_mem = ClientMem::new_private(fd, size - 1, true, None, None).unwrap(); - let client_mem = Rc::new(client_mem).offset(0); + let size = size - 1; + let client_mem = ClientMem::new_private(fd, size, true, None, None).unwrap(); + let client_mem = Rc::new(client_mem).offset(0, size); let mut v = vec![]; client_mem.read(&mut v).unwrap(); v.as_bstr().to_string()