From 5e5ef30a0414c3dd1df95d4bb7ae274747f808bf Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Thu, 9 Feb 2017 08:46:49 -0800 Subject: Add double-allocation protection --- src/core/lib/surface/call.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/core/lib/surface/call.c b/src/core/lib/surface/call.c index 77ee6b7753..18509dadff 100644 --- a/src/core/lib/surface/call.c +++ b/src/core/lib/surface/call.c @@ -1016,13 +1016,20 @@ static batch_control *allocate_batch_control(grpc_call *call, int op_slot = batch_slot_for_op(ops[i].op); slot = GPR_MIN(slot, op_slot); } - return &call->active_batches[slot]; + batch_control *bctl = &call->active_batches[slot]; + if (bctl->call != NULL) { + return NULL; + } + memset(bctl, 0, sizeof(*bctl)); + bctl->call = call; + return bctl; } static void finish_batch_completion(grpc_exec_ctx *exec_ctx, void *user_data, grpc_cq_completion *storage) { batch_control *bctl = user_data; grpc_call *call = bctl->call; + bctl->call = NULL; GRPC_CALL_INTERNAL_UNREF(exec_ctx, call, "completion"); } @@ -1351,8 +1358,9 @@ static grpc_call_error call_start_batch(grpc_exec_ctx *exec_ctx, /* TODO(ctiller): this feels like it could be made lock-free */ bctl = allocate_batch_control(call, ops, nops); - memset(bctl, 0, sizeof(*bctl)); - bctl->call = call; + if (bctl == NULL) { + return GRPC_CALL_ERROR_TOO_MANY_OPERATIONS; + } bctl->notify_tag = notify_tag; bctl->is_notify_tag_closure = (uint8_t)(is_notify_tag_closure != 0); -- cgit v1.2.3