From 738e6dbc40ae5ba1075395403b63045fde4aebfe Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Tue, 15 Nov 2016 09:29:44 -0800 Subject: [PATCH] Fix use-after-free in time parse caching --- src/core/ext/transport/chttp2/transport/parsing.c | 3 ++- src/core/lib/transport/metadata.c | 7 ++++--- src/core/lib/transport/metadata.h | 4 ++-- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/parsing.c b/src/core/ext/transport/chttp2/transport/parsing.c index b9c405158f009..5efb49751c3af 100644 --- a/src/core/ext/transport/chttp2/transport/parsing.c +++ b/src/core/ext/transport/chttp2/transport/parsing.c @@ -471,7 +471,8 @@ static void on_initial_header(grpc_exec_ctx *exec_ctx, void *tp, grpc_mdstr_as_c_string(md->value)); *cached_timeout = gpr_inf_future(GPR_TIMESPAN); } - grpc_mdelem_set_user_data(md, free_timeout, cached_timeout); + cached_timeout = + grpc_mdelem_set_user_data(md, free_timeout, cached_timeout); } grpc_chttp2_incoming_metadata_buffer_set_deadline( &s->metadata_buffer[0], diff --git a/src/core/lib/transport/metadata.c b/src/core/lib/transport/metadata.c index 977b34ca86e5a..fac19b91d9e8d 100644 --- a/src/core/lib/transport/metadata.c +++ b/src/core/lib/transport/metadata.c @@ -728,8 +728,8 @@ void *grpc_mdelem_get_user_data(grpc_mdelem *md, void (*destroy_func)(void *)) { return result; } -void grpc_mdelem_set_user_data(grpc_mdelem *md, void (*destroy_func)(void *), - void *user_data) { +void *grpc_mdelem_set_user_data(grpc_mdelem *md, void (*destroy_func)(void *), + void *user_data) { internal_metadata *im = (internal_metadata *)md; GPR_ASSERT(!is_mdelem_static(md)); GPR_ASSERT((user_data == NULL) == (destroy_func == NULL)); @@ -740,11 +740,12 @@ void grpc_mdelem_set_user_data(grpc_mdelem *md, void (*destroy_func)(void *), if (destroy_func != NULL) { destroy_func(user_data); } - return; + return (void *)gpr_atm_no_barrier_load(&im->user_data); } gpr_atm_no_barrier_store(&im->user_data, (gpr_atm)user_data); gpr_atm_rel_store(&im->destroy_user_data, (gpr_atm)destroy_func); gpr_mu_unlock(&im->mu_user_data); + return user_data; } grpc_slice grpc_mdstr_as_base64_encoded_and_huffman_compressed(grpc_mdstr *gs) { diff --git a/src/core/lib/transport/metadata.h b/src/core/lib/transport/metadata.h index 8dcfbb98bb510..a4955a1ea7440 100644 --- a/src/core/lib/transport/metadata.h +++ b/src/core/lib/transport/metadata.h @@ -120,8 +120,8 @@ size_t grpc_mdelem_get_size_in_hpack_table(grpc_mdelem *elem); is used as a type tag and is checked during user_data fetch. */ void *grpc_mdelem_get_user_data(grpc_mdelem *md, void (*if_destroy_func)(void *)); -void grpc_mdelem_set_user_data(grpc_mdelem *md, void (*destroy_func)(void *), - void *user_data); +void *grpc_mdelem_set_user_data(grpc_mdelem *md, void (*destroy_func)(void *), + void *user_data); /* Reference counting */ //#define GRPC_METADATA_REFCOUNT_DEBUG