aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorNicolas Williams <nico@twosigma.com>2015-09-01 19:42:58 -0400
committerTom Yu <tlyu@mit.edu>2015-09-16 17:24:12 -0400
commit5250332e15a873d8e5a2ec6e7bc1f82d337b9081 (patch)
tree3affd8c08fbab743375f3f241d720052660eaf48 /src
parent0ab7ca1d886be6223b59dc7948f7500f8872f3da (diff)
downloadkrb5-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
Diffstat (limited to 'src')
-rw-r--r--src/lib/gssapi/mechglue/g_exp_sec_context.c30
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 */