Skip to content

Commit e121d75

Browse files
committed
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.
1 parent 51c03c1 commit e121d75

File tree

1 file changed

+7
-3
lines changed

1 file changed

+7
-3
lines changed

src/librustuv/uvio.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,14 +57,18 @@ impl UvEventLoop {
5757
UvEventLoop {
5858
uvio: UvIoFactory {
5959
loop_: loop_,
60-
handle_pool: handle_pool,
60+
handle_pool: Some(handle_pool),
6161
}
6262
}
6363
}
6464
}
6565

6666
impl Drop for UvEventLoop {
6767
fn drop(&mut self) {
68+
// Must first destroy the pool of handles before we destroy the loop
69+
// because otherwise the contained async handle will be destroyed after
70+
// the loop is free'd (use-after-free)
71+
self.uvio.handle_pool.take();
6872
self.uvio.loop_.close();
6973
}
7074
}
@@ -117,14 +121,14 @@ fn test_callback_run_once() {
117121

118122
pub struct UvIoFactory {
119123
loop_: Loop,
120-
priv handle_pool: ~QueuePool,
124+
priv handle_pool: Option<~QueuePool>,
121125
}
122126

123127
impl UvIoFactory {
124128
pub fn uv_loop<'a>(&mut self) -> *uvll::uv_loop_t { self.loop_.handle }
125129

126130
pub fn make_handle(&mut self) -> HomeHandle {
127-
HomeHandle::new(self.id(), &mut *self.handle_pool)
131+
HomeHandle::new(self.id(), &mut **self.handle_pool.get_mut_ref())
128132
}
129133
}
130134

0 commit comments

Comments
 (0)