From e121d7556cc577c7a89acb3a609fcafcc8fc9204 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Sun, 15 Dec 2013 00:56:29 -0800 Subject: [PATCH] rustuv: Fix a use-after-free bug The queue has an async handle which must be destroyed before the loop is destroyed, so use a little bit of an option dance to get around this requirement. --- src/librustuv/uvio.rs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/librustuv/uvio.rs b/src/librustuv/uvio.rs index 210ee2fc4511..ea0e76b73271 100644 --- a/src/librustuv/uvio.rs +++ b/src/librustuv/uvio.rs @@ -57,7 +57,7 @@ impl UvEventLoop { UvEventLoop { uvio: UvIoFactory { loop_: loop_, - handle_pool: handle_pool, + handle_pool: Some(handle_pool), } } } @@ -65,6 +65,10 @@ impl UvEventLoop { 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) + self.uvio.handle_pool.take(); self.uvio.loop_.close(); } } @@ -117,14 +121,14 @@ fn test_callback_run_once() { pub struct UvIoFactory { loop_: Loop, - priv handle_pool: ~QueuePool, + priv handle_pool: Option<~QueuePool>, } impl UvIoFactory { pub fn uv_loop<'a>(&mut self) -> *uvll::uv_loop_t { self.loop_.handle } pub fn make_handle(&mut self) -> HomeHandle { - HomeHandle::new(self.id(), &mut *self.handle_pool) + HomeHandle::new(self.id(), &mut **self.handle_pool.get_mut_ref()) } }