From f93fd05a97081626dbd78c4553b6c2e78eeba920 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Tue, 2 Jun 2015 08:15:33 -0700 Subject: [PATCH] Fix use-after-free --- src/core/channel/client_channel.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/core/channel/client_channel.c b/src/core/channel/client_channel.c index ac348515045..1eda23b7918 100644 --- a/src/core/channel/client_channel.c +++ b/src/core/channel/client_channel.c @@ -372,12 +372,24 @@ static void init_call_elem(grpc_call_element *elem, /* Destructor for call_data */ static void destroy_call_elem(grpc_call_element *elem) { call_data *calld = elem->call_data; + channel_data *chand = elem->channel_data; /* if the call got activated, we need to destroy the child stack also, and remove it from the in-flight requests tracked by the child_entry we picked */ - if (calld->state == CALL_ACTIVE) { - grpc_child_call_destroy(calld->s.active.child_call); + gpr_mu_lock(&chand->mu); + switch (calld->state) { + case CALL_ACTIVE: + gpr_mu_unlock(&chand->mu); + grpc_child_call_destroy(calld->s.active.child_call); + break; + case CALL_WAITING: + remove_waiting_child(chand, calld); + gpr_mu_unlock(&chand->mu); + break; + default: + gpr_mu_unlock(&chand->mu); + break; } GPR_ASSERT(calld->state != CALL_WAITING); }