aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar David G. Quintas <dgq@google.com>2017-07-14 11:53:23 -0700
committerGravatar GitHub <noreply@github.com>2017-07-14 11:53:23 -0700
commitd4619f439d6cec68d2347e10de6617c6045a2192 (patch)
treee3e80bfb45fa7ef6737c78b1995dda8154210c15 /src
parentbf828943cb41f7e82b3db6eb48ee2609f099c765 (diff)
parentfc94d1f4a06c34cf637f48c9d1c6efab09e6a52b (diff)
Merge pull request #11819 from dgquintas/timer_manager_uaf
Fix use-after-free in timer manager
Diffstat (limited to 'src')
-rw-r--r--src/core/lib/iomgr/timer_manager.c7
1 files changed, 7 insertions, 0 deletions
diff --git a/src/core/lib/iomgr/timer_manager.c b/src/core/lib/iomgr/timer_manager.c
index b9bea9a2ab..631f7935d9 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() {