Skip to content

Commit c68f41b

Browse files
author
Luna
committed
x11: Limit returned shm buffer size
1 parent a958a18 commit c68f41b

File tree

1 file changed

+30
-8
lines changed

1 file changed

+30
-8
lines changed

src/x11.rs

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -422,10 +422,10 @@ impl ShmBuffer {
422422
fn alloc_segment(
423423
&mut self,
424424
conn: &impl Connection,
425-
size: usize,
425+
buffer_size: usize,
426426
) -> Result<(), PushBufferError> {
427427
// Round the size up to the next power of two to prevent frequent reallocations.
428-
let size = size.next_power_of_two();
428+
let size = buffer_size.next_power_of_two();
429429

430430
// Get the size of the segment currently in use.
431431
let needs_realloc = match self.seg {
@@ -435,8 +435,10 @@ impl ShmBuffer {
435435

436436
// Reallocate if necessary.
437437
if needs_realloc {
438-
let new_seg = ShmSegment::new(size)?;
438+
let new_seg = ShmSegment::new(size, buffer_size)?;
439439
self.associate(conn, new_seg)?;
440+
} else if let Some((ref mut seg, _)) = self.seg {
441+
seg.set_buffer_size(buffer_size);
440442
}
441443

442444
Ok(())
@@ -451,8 +453,10 @@ impl ShmBuffer {
451453
unsafe fn as_ref(&self) -> &[u32] {
452454
match self.seg.as_ref() {
453455
Some((seg, _)) => {
456+
let buffer_size = seg.buffer_size();
457+
454458
// SAFETY: No other code should be able to access the segment.
455-
bytemuck::cast_slice(unsafe { seg.as_ref() })
459+
bytemuck::cast_slice(unsafe { &seg.as_ref()[..buffer_size] })
456460
}
457461
None => {
458462
// Nothing has been allocated yet.
@@ -470,8 +474,10 @@ impl ShmBuffer {
470474
unsafe fn as_mut(&mut self) -> &mut [u32] {
471475
match self.seg.as_mut() {
472476
Some((seg, _)) => {
477+
let buffer_size = seg.buffer_size();
478+
473479
// SAFETY: No other code should be able to access the segment.
474-
bytemuck::cast_slice_mut(unsafe { seg.as_mut() })
480+
bytemuck::cast_slice_mut(unsafe { &mut seg.as_mut()[..buffer_size] })
475481
}
476482
None => {
477483
// Nothing has been allocated yet.
@@ -528,11 +534,12 @@ struct ShmSegment {
528534
id: i32,
529535
ptr: NonNull<i8>,
530536
size: usize,
537+
buffer_size: usize,
531538
}
532539

533540
impl ShmSegment {
534541
/// Create a new `ShmSegment` with the given size.
535-
fn new(size: usize) -> io::Result<Self> {
542+
fn new(size: usize, buffer_size: usize) -> io::Result<Self> {
536543
unsafe {
537544
// Create the shared memory segment.
538545
let id = shmget(IPC_PRIVATE, size, 0o600);
@@ -552,7 +559,12 @@ impl ShmSegment {
552559
}
553560
};
554561

555-
Ok(Self { id, ptr, size })
562+
Ok(Self {
563+
id,
564+
ptr,
565+
size,
566+
buffer_size,
567+
})
556568
}
557569
}
558570

@@ -574,6 +586,16 @@ impl ShmSegment {
574586
unsafe { slice::from_raw_parts_mut(self.ptr.as_ptr(), self.size) }
575587
}
576588

589+
/// Set the size of the buffer for this shared memory segment.
590+
fn set_buffer_size(&mut self, buffer_size: usize) {
591+
self.buffer_size = buffer_size
592+
}
593+
594+
/// Get the size of the buffer for this shared memory segment.
595+
fn buffer_size(&self) -> usize {
596+
self.buffer_size
597+
}
598+
577599
/// Get the size of this shared memory segment.
578600
fn size(&self) -> usize {
579601
self.size
@@ -624,7 +646,7 @@ impl Drop for X11Impl {
624646
/// Test to see if SHM is available.
625647
fn is_shm_available(c: &impl Connection) -> bool {
626648
// Create a small SHM segment.
627-
let seg = match ShmSegment::new(0x1000) {
649+
let seg = match ShmSegment::new(0x1000, 0x1000) {
628650
Ok(seg) => seg,
629651
Err(_) => return false,
630652
};

0 commit comments

Comments
 (0)