Skip to content

Commit a49967b

Browse files
committed
fix(driver): bounds-check buffer_id in Shared::reset
BufferPoolRoot::release() drains inner.bufs via mem::take, but the Shared Rc may still be alive. When a BufferRef is dropped after release, its Drop impl upgrades the Weak successfully and calls Shared::reset with a stale buffer_id, panicking on the unchecked index into the now-empty Vec. Use get_mut (matching the existing bounds check in Shared::take) and deallocate the buffer directly when the slot no longer exists. Reproduces under macOS kqueue when closing sockets under backpressure (PUSH saturating a PULL with low HWM).
1 parent 2e1a8f6 commit a49967b

1 file changed

Lines changed: 6 additions & 2 deletions

File tree

compio-driver/src/buffer_pool.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -351,8 +351,12 @@ impl Shared {
351351
fn reset(&self, buffer_id: u16, ptr: BufPtr) {
352352
unsafe {
353353
self.with(|inner| {
354-
inner.bufs[buffer_id as usize] = Some(ptr);
355-
inner.ctrl.reset(buffer_id, ptr, inner.size);
354+
if let Some(slot) = inner.bufs.get_mut(buffer_id as usize) {
355+
*slot = Some(ptr);
356+
inner.ctrl.reset(buffer_id, ptr, inner.size);
357+
} else {
358+
(inner.alloc.deallocate)(ptr, inner.size);
359+
}
356360
})
357361
}
358362
}

0 commit comments

Comments
 (0)