rustuv: Fix a use-after-free on destruction
The uv loop was being destroyed before the async handle was being destroyed, so closing the async handle was causing a use-after-free in the uv loop. This was fixed by moving destruction of the queue's async handle to an earlier location and then actually freeing it once the loop has been dropped.
This commit is contained in:
parent
962af9198f
commit
f25c81a51a
|
@ -138,6 +138,10 @@ impl QueuePool {
|
|||
}
|
||||
Queue { queue: self.producer.clone() }
|
||||
}
|
||||
|
||||
pub fn handle(&self) -> *uvll::uv_async_t {
|
||||
unsafe { (*self.producer.packet()).handle }
|
||||
}
|
||||
}
|
||||
|
||||
impl Queue {
|
||||
|
@ -180,7 +184,9 @@ impl Drop for State {
|
|||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
uvll::uv_close(self.handle, cast::transmute(0));
|
||||
uvll::free_handle(self.handle);
|
||||
// Note that this does *not* free the handle, that is the
|
||||
// responsibility of the caller because the uv loop must be closed
|
||||
// before we deallocate this uv handle.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -67,9 +67,13 @@ impl Drop for UvEventLoop {
|
|||
fn drop(&mut self) {
|
||||
// Must first destroy the pool of handles before we destroy the loop
|
||||
// because otherwise the contained async handle will be destroyed after
|
||||
// the loop is free'd (use-after-free)
|
||||
// the loop is free'd (use-after-free). We also must free the uv handle
|
||||
// after the loop has been closed because during the closing of the loop
|
||||
// the handle is required to be used apparently.
|
||||
let handle = self.uvio.handle_pool.get_ref().handle();
|
||||
self.uvio.handle_pool.take();
|
||||
self.uvio.loop_.close();
|
||||
unsafe { uvll::free_handle(handle) }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue