diff options
Diffstat (limited to 'src/core/lib/security/transport/client_auth_filter.cc')
-rw-r--r-- | src/core/lib/security/transport/client_auth_filter.cc | 45 |
1 files changed, 28 insertions, 17 deletions
diff --git a/src/core/lib/security/transport/client_auth_filter.cc b/src/core/lib/security/transport/client_auth_filter.cc index 0f125e7c26..6955e8698e 100644 --- a/src/core/lib/security/transport/client_auth_filter.cc +++ b/src/core/lib/security/transport/client_auth_filter.cc @@ -32,6 +32,7 @@ #include "src/core/lib/security/context/security_context.h" #include "src/core/lib/security/credentials/credentials.h" #include "src/core/lib/security/security_connector/security_connector.h" +#include "src/core/lib/security/security_connector/ssl_utils.h" #include "src/core/lib/slice/slice_internal.h" #include "src/core/lib/slice/slice_string_helpers.h" #include "src/core/lib/surface/call.h" @@ -42,20 +43,39 @@ namespace { /* We can have a per-call credentials. */ struct call_data { + call_data(grpc_call_element* elem, const grpc_call_element_args& args) + : arena(args.arena), + owning_call(args.call_stack), + call_combiner(args.call_combiner) {} + + // This method is technically the dtor of this class. However, since + // `get_request_metadata_cancel_closure` can run in parallel to + // `destroy_call_elem`, we cannot call the dtor in them. Otherwise, + // fields will be accessed after calling dtor, and msan correctly complains + // that the memory is not initialized. + void destroy() { + grpc_credentials_mdelem_array_destroy(&md_array); + grpc_call_credentials_unref(creds); + grpc_slice_unref_internal(host); + grpc_slice_unref_internal(method); + grpc_auth_metadata_context_reset(&auth_md_context); + } + gpr_arena* arena; grpc_call_stack* owning_call; grpc_call_combiner* call_combiner; - grpc_call_credentials* creds; - grpc_slice host; - grpc_slice method; + grpc_call_credentials* creds = nullptr; + grpc_slice host = grpc_empty_slice(); + grpc_slice method = grpc_empty_slice(); /* pollset{_set} bound to this call; if we need to make external network requests, they should be done under a pollset added to this pollset_set so that work can progress when this call wants work to progress */ - grpc_polling_entity* pollent; + grpc_polling_entity* pollent = nullptr; grpc_credentials_mdelem_array md_array; - grpc_linked_mdelem md_links[MAX_CREDENTIALS_METADATA_COUNT]; - grpc_auth_metadata_context auth_md_context; + grpc_linked_mdelem md_links[MAX_CREDENTIALS_METADATA_COUNT] = {}; + grpc_auth_metadata_context auth_md_context = + grpc_auth_metadata_context(); // Zero-initialize the C struct. grpc_closure async_result_closure; grpc_closure check_call_host_cancel_closure; grpc_closure get_request_metadata_cancel_closure; @@ -333,12 +353,7 @@ static void auth_start_transport_stream_op_batch( /* Constructor for call_data */ static grpc_error* init_call_elem(grpc_call_element* elem, const grpc_call_element_args* args) { - call_data* calld = static_cast<call_data*>(elem->call_data); - calld->arena = args->arena; - calld->owning_call = args->call_stack; - calld->call_combiner = args->call_combiner; - calld->host = grpc_empty_slice(); - calld->method = grpc_empty_slice(); + new (elem->call_data) call_data(elem, *args); return GRPC_ERROR_NONE; } @@ -353,11 +368,7 @@ static void destroy_call_elem(grpc_call_element* elem, const grpc_call_final_info* final_info, grpc_closure* ignored) { call_data* calld = static_cast<call_data*>(elem->call_data); - grpc_credentials_mdelem_array_destroy(&calld->md_array); - grpc_call_credentials_unref(calld->creds); - grpc_slice_unref_internal(calld->host); - grpc_slice_unref_internal(calld->method); - grpc_auth_metadata_context_reset(&calld->auth_md_context); + calld->destroy(); } /* Constructor for channel_data */ |