From fc94d1f4a06c34cf637f48c9d1c6efab09e6a52b Mon Sep 17 00:00:00 2001 From: David Garcia Quintas Date: Thu, 13 Jul 2017 20:56:13 -0700 Subject: [PATCH] Fix use-after-free in timer manager --- src/core/lib/iomgr/timer_manager.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/core/lib/iomgr/timer_manager.c b/src/core/lib/iomgr/timer_manager.c index b9bea9a2ab3..631f7935d98 100644 --- a/src/core/lib/iomgr/timer_manager.c +++ b/src/core/lib/iomgr/timer_manager.c @@ -84,7 +84,14 @@ static void start_timer_thread_and_unlock(void) { gpr_thd_options opt = gpr_thd_options_default(); gpr_thd_options_set_joinable(&opt); completed_thread *ct = gpr_malloc(sizeof(*ct)); + // The call to gpr_thd_new() has to be under the same lock used by + // gc_completed_threads(), particularly due to ct->t, which is written here + // (internally by gpr_thd_new) and read there. Otherwise it's possible for ct + // to leak through g_completed_threads and be freed in gc_completed_threads() + // before "&ct->t" is written to, causing a use-after-free. + gpr_mu_lock(&g_mu); gpr_thd_new(&ct->t, timer_thread, ct, &opt); + gpr_mu_unlock(&g_mu); } void grpc_timer_manager_tick() {