aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/security
diff options
context:
space:
mode:
authorGravatar Craig Tiller <ctiller@google.com>2015-06-30 11:40:41 -0700
committerGravatar Craig Tiller <ctiller@google.com>2015-06-30 11:40:41 -0700
commit991edad25ccc26499a24825cca882bc76aae41c7 (patch)
tree8e74b6d5b279408a4b00d7b922dde207b8ba13f8 /src/core/security
parentcf34343646c0d0864c89f356432a3cd1389c8f07 (diff)
SSL refcounting fixes
Handle the case where we recreate an auth context. Add (opt-in) debugging for refcounts on auth contexts.
Diffstat (limited to 'src/core/security')
-rw-r--r--src/core/security/security_connector.c13
-rw-r--r--src/core/security/security_context.c31
-rw-r--r--src/core/security/security_context.h19
-rw-r--r--src/core/security/server_auth_filter.c8
4 files changed, 55 insertions, 16 deletions
diff --git a/src/core/security/security_connector.c b/src/core/security/security_connector.c
index 5512bb177a..34cb0395a2 100644
--- a/src/core/security/security_connector.c
+++ b/src/core/security/security_connector.c
@@ -196,12 +196,12 @@ typedef struct {
static void fake_channel_destroy(grpc_security_connector *sc) {
grpc_channel_security_connector *c = (grpc_channel_security_connector *)sc;
grpc_credentials_unref(c->request_metadata_creds);
- grpc_auth_context_unref(sc->auth_context);
+ GRPC_AUTH_CONTEXT_UNREF(sc->auth_context, "connector");
gpr_free(sc);
}
static void fake_server_destroy(grpc_security_connector *sc) {
- grpc_auth_context_unref(sc->auth_context);
+ GRPC_AUTH_CONTEXT_UNREF(sc->auth_context, "connector");
gpr_free(sc);
}
@@ -242,7 +242,7 @@ static grpc_security_status fake_check_peer(grpc_security_connector *sc,
status = GRPC_SECURITY_ERROR;
goto end;
}
- grpc_auth_context_unref(sc->auth_context);
+ GRPC_AUTH_CONTEXT_UNREF(sc->auth_context, "connector");
sc->auth_context = grpc_auth_context_create(NULL, 1);
sc->auth_context->properties[0] = grpc_auth_property_init_from_cstring(
GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME,
@@ -323,7 +323,7 @@ static void ssl_channel_destroy(grpc_security_connector *sc) {
if (c->target_name != NULL) gpr_free(c->target_name);
if (c->overridden_target_name != NULL) gpr_free(c->overridden_target_name);
tsi_peer_destruct(&c->peer);
- grpc_auth_context_unref(sc->auth_context);
+ GRPC_AUTH_CONTEXT_UNREF(sc->auth_context, "connector");
gpr_free(sc);
}
@@ -333,7 +333,7 @@ static void ssl_server_destroy(grpc_security_connector *sc) {
if (c->handshaker_factory != NULL) {
tsi_ssl_handshaker_factory_destroy(c->handshaker_factory);
}
- grpc_auth_context_unref(sc->auth_context);
+ GRPC_AUTH_CONTEXT_UNREF(sc->auth_context, "connector");
gpr_free(sc);
}
@@ -437,6 +437,9 @@ static grpc_security_status ssl_check_peer(grpc_security_connector *sc,
gpr_log(GPR_ERROR, "Peer name %s is not in peer certificate", peer_name);
return GRPC_SECURITY_ERROR;
}
+ if (sc->auth_context != NULL) {
+ GRPC_AUTH_CONTEXT_UNREF(sc->auth_context, "connector");
+ }
sc->auth_context = tsi_ssl_peer_to_auth_context(peer);
return GRPC_SECURITY_OK;
}
diff --git a/src/core/security/security_context.c b/src/core/security/security_context.c
index 9aba1e7f91..4d56549f9b 100644
--- a/src/core/security/security_context.c
+++ b/src/core/security/security_context.c
@@ -89,7 +89,7 @@ grpc_client_security_context *grpc_client_security_context_create(void) {
void grpc_client_security_context_destroy(void *ctx) {
grpc_client_security_context *c = (grpc_client_security_context *)ctx;
grpc_credentials_unref(c->creds);
- grpc_auth_context_unref(c->auth_context);
+ GRPC_AUTH_CONTEXT_UNREF(c->auth_context, "client_security_context");
gpr_free(ctx);
}
@@ -104,7 +104,7 @@ grpc_server_security_context *grpc_server_security_context_create(void) {
void grpc_server_security_context_destroy(void *ctx) {
grpc_server_security_context *c = (grpc_server_security_context *)ctx;
- grpc_auth_context_unref(c->auth_context);
+ GRPC_AUTH_CONTEXT_UNREF(c->auth_context, "server_security_context");
gpr_free(ctx);
}
@@ -120,21 +120,40 @@ grpc_auth_context *grpc_auth_context_create(grpc_auth_context *chained,
memset(ctx->properties, 0, property_count * sizeof(grpc_auth_property));
ctx->property_count = property_count;
gpr_ref_init(&ctx->refcount, 1);
- if (chained != NULL) ctx->chained = grpc_auth_context_ref(chained);
+ if (chained != NULL) ctx->chained = GRPC_AUTH_CONTEXT_REF(chained, "chained");
return ctx;
}
+#ifdef GRPC_AUTH_CONTEXT_REFCOUNT_DEBUG
+grpc_auth_context *grpc_auth_context_ref(grpc_auth_context *ctx,
+ const char *file, int line,
+ const char *reason) {
+ if (ctx == NULL) return NULL;
+ gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG,
+ "AUTH_CONTEXT:%p ref %d -> %d %s", ctx, (int)ctx->refcount.count,
+ (int)ctx->refcount.count + 1, reason);
+#else
grpc_auth_context *grpc_auth_context_ref(grpc_auth_context *ctx) {
if (ctx == NULL) return NULL;
+#endif
gpr_ref(&ctx->refcount);
return ctx;
}
+#ifdef GRPC_AUTH_CONTEXT_REFCOUNT_DEBUG
+void grpc_auth_context_unref(grpc_auth_context *ctx, const char *file, int line,
+ const char *reason) {
+ if (ctx == NULL) return;
+ gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG,
+ "AUTH_CONTEXT:%p unref %d -> %d %s", ctx, (int)ctx->refcount.count,
+ (int)ctx->refcount.count - 1, reason);
+#else
void grpc_auth_context_unref(grpc_auth_context *ctx) {
if (ctx == NULL) return;
+#endif
if (gpr_unref(&ctx->refcount)) {
size_t i;
- grpc_auth_context_unref(ctx->chained);
+ GRPC_AUTH_CONTEXT_UNREF(ctx->chained, "chained");
if (ctx->properties != NULL) {
for (i = 0; i < ctx->property_count; i++) {
grpc_auth_property_reset(&ctx->properties[i]);
@@ -223,8 +242,8 @@ grpc_auth_property grpc_auth_property_init(const char *name, const char *value,
}
void grpc_auth_property_reset(grpc_auth_property *property) {
- if (property->name != NULL) gpr_free(property->name);
- if (property->value != NULL) gpr_free(property->value);
+ gpr_free(property->name);
+ gpr_free(property->value);
memset(property, 0, sizeof(grpc_auth_property));
}
diff --git a/src/core/security/security_context.h b/src/core/security/security_context.h
index d8909cd6f1..20c4390898 100644
--- a/src/core/security/security_context.h
+++ b/src/core/security/security_context.h
@@ -55,9 +55,22 @@ grpc_auth_context *grpc_auth_context_create(grpc_auth_context *chained,
size_t property_count);
/* Refcounting. */
-grpc_auth_context *grpc_auth_context_ref(
- grpc_auth_context *ctx);
-void grpc_auth_context_unref(grpc_auth_context *ctx);
+#ifdef GRPC_AUTH_CONTEXT_REFCOUNT_DEBUG
+#define GRPC_AUTH_CONTEXT_REF(p, r) \
+ grpc_auth_context_ref((p), __FILE__, __LINE__, (r))
+#define GRPC_AUTH_CONTEXT_UNREF(p, r) \
+ grpc_auth_context_unref((p), __FILE__, __LINE__, (r))
+grpc_auth_context *grpc_auth_context_ref(grpc_auth_context *policy,
+ const char *file, int line,
+ const char *reason);
+void grpc_auth_context_unref(grpc_auth_context *policy, const char *file,
+ int line, const char *reason);
+#else
+#define GRPC_AUTH_CONTEXT_REF(p, r) grpc_auth_context_ref((p))
+#define GRPC_AUTH_CONTEXT_UNREF(p, r) grpc_auth_context_unref((p))
+grpc_auth_context *grpc_auth_context_ref(grpc_auth_context *policy);
+void grpc_auth_context_unref(grpc_auth_context *policy);
+#endif
grpc_auth_property grpc_auth_property_init_from_cstring(const char *name,
const char *value);
diff --git a/src/core/security/server_auth_filter.c b/src/core/security/server_auth_filter.c
index b19160b8ed..b8639287a5 100644
--- a/src/core/security/server_auth_filter.c
+++ b/src/core/security/server_auth_filter.c
@@ -82,9 +82,13 @@ static void init_call_elem(grpc_call_element *elem,
/* Create a security context for the call and reference the auth context from
the channel. */
+ if (initial_op->context[GRPC_CONTEXT_SECURITY].value != NULL) {
+ initial_op->context[GRPC_CONTEXT_SECURITY].destroy(
+ initial_op->context[GRPC_CONTEXT_SECURITY].value);
+ }
server_ctx = grpc_server_security_context_create();
- server_ctx->auth_context =
- grpc_auth_context_ref(chand->security_connector->auth_context);
+ server_ctx->auth_context = GRPC_AUTH_CONTEXT_REF(
+ chand->security_connector->auth_context, "server_security_context");
initial_op->context[GRPC_CONTEXT_SECURITY].value = server_ctx;
initial_op->context[GRPC_CONTEXT_SECURITY].destroy =
grpc_server_security_context_destroy;