From a0a7b57ec08b0697892555930aaf700da8517252 Mon Sep 17 00:00:00 2001 From: Yuchen Zeng Date: Wed, 9 Aug 2017 10:33:07 -0700 Subject: [PATCH 1/2] Fix use-after-free in oauth2_credentials --- .../security/credentials/oauth2/oauth2_credentials.c | 12 +++++++++++- .../security/credentials/oauth2/oauth2_credentials.h | 2 ++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/core/lib/security/credentials/oauth2/oauth2_credentials.c b/src/core/lib/security/credentials/oauth2/oauth2_credentials.c index ffa941bb9e9..c59e55136cb 100644 --- a/src/core/lib/security/credentials/oauth2/oauth2_credentials.c +++ b/src/core/lib/security/credentials/oauth2/oauth2_credentials.c @@ -109,6 +109,8 @@ static void oauth2_token_fetcher_destruct(grpc_exec_ctx *exec_ctx, (grpc_oauth2_token_fetcher_credentials *)creds; GRPC_MDELEM_UNREF(exec_ctx, c->access_token_md); gpr_mu_destroy(&c->mu); + grpc_pollset_set_destroy(exec_ctx, + grpc_polling_entity_pollset_set(&c->pollent)); grpc_httpcli_context_destroy(exec_ctx, &c->httpcli_context); } @@ -238,6 +240,9 @@ static void on_oauth2_token_fetcher_http_response(grpc_exec_ctx *exec_ctx, "Error occured when fetching oauth2 token.", &error, 1); } GRPC_CLOSURE_SCHED(exec_ctx, pending_request->on_request_metadata, error); + grpc_polling_entity_del_from_pollset_set( + exec_ctx, pending_request->pollent, + grpc_polling_entity_pollset_set(&c->pollent)); grpc_oauth2_pending_get_request_metadata *prev = pending_request; pending_request = pending_request->next; gpr_free(prev); @@ -278,6 +283,9 @@ static bool oauth2_token_fetcher_get_request_metadata( sizeof(*pending_request)); pending_request->md_array = md_array; pending_request->on_request_metadata = on_request_metadata; + pending_request->pollent = pollent; + grpc_polling_entity_add_to_pollset_set( + exec_ctx, pollent, grpc_polling_entity_pollset_set(&c->pollent)); pending_request->next = c->pending_requests; c->pending_requests = pending_request; bool start_fetch = false; @@ -289,7 +297,7 @@ static bool oauth2_token_fetcher_get_request_metadata( if (start_fetch) { grpc_call_credentials_ref(creds); c->fetch_func(exec_ctx, grpc_credentials_metadata_request_create(creds), - &c->httpcli_context, pollent, + &c->httpcli_context, &c->pollent, on_oauth2_token_fetcher_http_response, gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), refresh_threshold)); } @@ -334,6 +342,8 @@ static void init_oauth2_token_fetcher(grpc_oauth2_token_fetcher_credentials *c, gpr_mu_init(&c->mu); c->token_expiration = gpr_inf_past(GPR_CLOCK_REALTIME); c->fetch_func = fetch_func; + c->pollent = + grpc_polling_entity_create_from_pollset_set(grpc_pollset_set_create()); grpc_httpcli_context_init(&c->httpcli_context); } diff --git a/src/core/lib/security/credentials/oauth2/oauth2_credentials.h b/src/core/lib/security/credentials/oauth2/oauth2_credentials.h index 9d041a20eaf..d9ad6691b84 100644 --- a/src/core/lib/security/credentials/oauth2/oauth2_credentials.h +++ b/src/core/lib/security/credentials/oauth2/oauth2_credentials.h @@ -62,6 +62,7 @@ typedef void (*grpc_fetch_oauth2_func)(grpc_exec_ctx *exec_ctx, typedef struct grpc_oauth2_pending_get_request_metadata { grpc_credentials_mdelem_array *md_array; grpc_closure *on_request_metadata; + grpc_polling_entity *pollent; struct grpc_oauth2_pending_get_request_metadata *next; } grpc_oauth2_pending_get_request_metadata; @@ -74,6 +75,7 @@ typedef struct { grpc_oauth2_pending_get_request_metadata *pending_requests; grpc_httpcli_context httpcli_context; grpc_fetch_oauth2_func fetch_func; + grpc_polling_entity pollent; } grpc_oauth2_token_fetcher_credentials; // Google refresh token credentials. From 309c9de041c0c0d492bbbe3bf4dd5a46830a77b1 Mon Sep 17 00:00:00 2001 From: Yuchen Zeng Date: Wed, 9 Aug 2017 16:12:57 -0700 Subject: [PATCH 2/2] Update credentials_test --- test/core/security/credentials_test.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/test/core/security/credentials_test.c b/test/core/security/credentials_test.c index e60e398767e..441c4311353 100644 --- a/test/core/security/credentials_test.c +++ b/test/core/security/credentials_test.c @@ -311,6 +311,7 @@ typedef struct { grpc_credentials_mdelem_array md_array; grpc_closure on_request_metadata; grpc_call_credentials *creds; + grpc_polling_entity pollent; } request_metadata_state; static void check_metadata(const expected_md *expected, @@ -355,6 +356,8 @@ static void check_request_metadata(grpc_exec_ctx *exec_ctx, void *arg, GPR_ASSERT(state->md_array.size == state->expected_size); check_metadata(state->expected, &state->md_array); grpc_credentials_mdelem_array_destroy(exec_ctx, &state->md_array); + grpc_pollset_set_destroy(exec_ctx, + grpc_polling_entity_pollset_set(&state->pollent)); gpr_free(state); } @@ -365,6 +368,8 @@ static request_metadata_state *make_request_metadata_state( state->expected_error = expected_error; state->expected = expected; state->expected_size = expected_size; + state->pollent = + grpc_polling_entity_create_from_pollset_set(grpc_pollset_set_create()); GRPC_CLOSURE_INIT(&state->on_request_metadata, check_request_metadata, state, grpc_schedule_on_exec_ctx); return state; @@ -376,7 +381,7 @@ static void run_request_metadata_test(grpc_exec_ctx *exec_ctx, request_metadata_state *state) { grpc_error *error = GRPC_ERROR_NONE; if (grpc_call_credentials_get_request_metadata( - exec_ctx, creds, NULL, auth_md_ctx, &state->md_array, + exec_ctx, creds, &state->pollent, auth_md_ctx, &state->md_array, &state->on_request_metadata, &error)) { // Synchronous result. Invoke the callback directly. check_request_metadata(exec_ctx, state, error);