diff options
author | Nicolas Williams <nico@twosigma.com> | 2015-09-01 19:42:58 -0400 |
---|---|---|
committer | Tom Yu <tlyu@mit.edu> | 2015-09-16 17:24:12 -0400 |
commit | 5250332e15a873d8e5a2ec6e7bc1f82d337b9081 (patch) | |
tree | 3affd8c08fbab743375f3f241d720052660eaf48 | |
parent | 0ab7ca1d886be6223b59dc7948f7500f8872f3da (diff) | |
download | krb5-5250332e15a873d8e5a2ec6e7bc1f82d337b9081.zip krb5-5250332e15a873d8e5a2ec6e7bc1f82d337b9081.tar.gz krb5-5250332e15a873d8e5a2ec6e7bc1f82d337b9081.tar.bz2 |
Fix error handling in gss_export_sec_context()
In the mechglue gss_export_sec_context(), make sure to delete the
union context if the underlying mech context has been deleted. This
can happen if the mech's gss_export_sec_context() returns a failure
and deletes the context (not a behavior exhibited by any of our
in-tree mechanisms, but an allowed behavior for other mechs), or if we
fail to allocate space for the wrapped token.
[ghudson@mit.edu: commit message; rename exit label to "cleanup" and
make it valid for all exit cases]
(cherry picked from commit 4f35b27a9ee38ca0b557ce8e6d059924a63d4eff)
ticket: 8240
version_fixed: 1.13.3
status: resolved
-rw-r--r-- | src/lib/gssapi/mechglue/g_exp_sec_context.c | 30 |
1 files changed, 17 insertions, 13 deletions
diff --git a/src/lib/gssapi/mechglue/g_exp_sec_context.c b/src/lib/gssapi/mechglue/g_exp_sec_context.c index 03a6f2b..e5f95ad 100644 --- a/src/lib/gssapi/mechglue/g_exp_sec_context.c +++ b/src/lib/gssapi/mechglue/g_exp_sec_context.c @@ -79,9 +79,9 @@ gss_buffer_t interprocess_token; { OM_uint32 status; OM_uint32 length; - gss_union_ctx_id_t ctx; + gss_union_ctx_id_t ctx = (gss_union_ctx_id_t) *context_handle; gss_mechanism mech; - gss_buffer_desc token; + gss_buffer_desc token = GSS_C_EMPTY_BUFFER; char *buf; status = val_exp_sec_ctx_args(minor_status, @@ -94,7 +94,6 @@ gss_buffer_t interprocess_token; * call it. */ - ctx = (gss_union_ctx_id_t) *context_handle; mech = gssint_get_mechanism (ctx->mech_type); if (!mech) return GSS_S_BAD_MECH; @@ -105,15 +104,16 @@ gss_buffer_t interprocess_token; &ctx->internal_ctx_id, &token); if (status != GSS_S_COMPLETE) { map_error(minor_status, mech); - return (status); + goto cleanup; } length = token.length + 4 + ctx->mech_type->length; interprocess_token->length = length; interprocess_token->value = malloc(length); if (interprocess_token->value == 0) { - (void) gss_release_buffer(minor_status, &token); - return (GSS_S_FAILURE); + *minor_status = ENOMEM; + status = GSS_S_FAILURE; + goto cleanup; } buf = interprocess_token->value; length = ctx->mech_type->length; @@ -127,13 +127,17 @@ gss_buffer_t interprocess_token; memcpy(buf+4, ctx->mech_type->elements, (size_t) ctx->mech_type->length); memcpy(buf+4+ctx->mech_type->length, token.value, token.length); - (void) gss_release_buffer(minor_status, &token); - - free(ctx->mech_type->elements); - free(ctx->mech_type); - free(ctx); - *context_handle = 0; + status = GSS_S_COMPLETE; - return(GSS_S_COMPLETE); +cleanup: + (void) gss_release_buffer(minor_status, &token); + if (ctx->internal_ctx_id == GSS_C_NO_CONTEXT) { + /* If the mech deleted its context, delete the union context. */ + free(ctx->mech_type->elements); + free(ctx->mech_type); + free(ctx); + *context_handle = GSS_C_NO_CONTEXT; + } + return status; } #endif /*LEAN_CLIENT */ |