diff options
| author | Alex Crichton <alex@alexcrichton.com> | 2013-12-15 00:56:29 -0800 |
|---|---|---|
| committer | Alex Crichton <alex@alexcrichton.com> | 2013-12-24 19:59:54 -0800 |
| commit | e121d7556cc577c7a89acb3a609fcafcc8fc9204 (patch) | |
| tree | c5a1889e9e5f219178c3696a33dfdc4144a28a13 /src | |
| parent | 51c03c1f35f6b076928a1e5b94ec81e6d00c3ac2 (diff) | |
| download | rust-e121d7556cc577c7a89acb3a609fcafcc8fc9204.tar.gz rust-e121d7556cc577c7a89acb3a609fcafcc8fc9204.zip | |
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.
Diffstat (limited to 'src')
| -rw-r--r-- | src/librustuv/uvio.rs | 10 |
1 files changed, 7 insertions, 3 deletions
diff --git a/src/librustuv/uvio.rs b/src/librustuv/uvio.rs index 210ee2fc451..ea0e76b7327 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()) } } |
