Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-12-SP4:GA
krb5-mini.34410
0109-Preserve-GSS-context-on-init-accept-failur...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 0109-Preserve-GSS-context-on-init-accept-failure.patch of Package krb5-mini.34410
commit 56f7b1bc95a2a3eeb420e069e7655fb181ade5cf Author: Greg Hudson <ghudson@mit.edu> Date: Fri Jul 14 13:02:46 2017 -0400 Preserve GSS context on init/accept failure After gss_init_sec_context() or gss_accept_sec_context() has created a context, don't delete the mechglue context on failures from subsequent calls, even if the mechanism deletes the mech-specific context (which is allowed by RFC 2744 but not preferred). Check for union contexts with no mechanism context in each GSS function which accepts a gss_ctx_id_t. CVE-2017-11462: RFC 2744 permits a GSS-API implementation to delete an existing security context on a second or subsequent call to gss_init_sec_context() or gss_accept_sec_context() if the call results in an error. This API behavior has been found to be dangerous, leading to the possibility of memory errors in some callers. For safety, GSS-API implementations should instead preserve existing security contexts on error until the caller deletes them. All versions of MIT krb5 prior to this change may delete acceptor contexts on error. Versions 1.13.4 through 1.13.7, 1.14.1 through 1.14.5, and 1.15 through 1.15.1 may also delete initiator contexts on error. ticket: 8598 (new) target_version: 1.15-next target_version: 1.14-next tags: pullup diff --git a/src/lib/gssapi/mechglue/g_accept_sec_context.c b/src/lib/gssapi/mechglue/g_accept_sec_context.c index b8f128b..8f2b7e4 100644 --- a/src/lib/gssapi/mechglue/g_accept_sec_context.c +++ b/src/lib/gssapi/mechglue/g_accept_sec_context.c @@ -185,6 +185,8 @@ gss_cred_id_t * d_cred; } else { union_ctx_id = (gss_union_ctx_id_t)*context_handle; selected_mech = union_ctx_id->mech_type; + if (union_ctx_id->internal_ctx_id == GSS_C_NO_CONTEXT) + return (GSS_S_NO_CONTEXT); } /* Now create a new context if we didn't get one. */ @@ -203,9 +205,6 @@ gss_cred_id_t * d_cred; free(union_ctx_id); return (status); } - - /* set the new context handle to caller's data */ - *context_handle = (gss_ctx_id_t)union_ctx_id; } /* @@ -243,8 +242,10 @@ gss_cred_id_t * d_cred; d_cred ? &tmp_d_cred : NULL); /* If there's more work to do, keep going... */ - if (status == GSS_S_CONTINUE_NEEDED) + if (status == GSS_S_CONTINUE_NEEDED) { + *context_handle = (gss_ctx_id_t)union_ctx_id; return GSS_S_CONTINUE_NEEDED; + } /* if the call failed, return with failure */ if (status != GSS_S_COMPLETE) { @@ -330,14 +331,22 @@ gss_cred_id_t * d_cred; *mech_type = gssint_get_public_oid(actual_mech); if (ret_flags != NULL) *ret_flags = temp_ret_flags; - return (status); + *context_handle = (gss_ctx_id_t)union_ctx_id; + return GSS_S_COMPLETE; } else { status = GSS_S_BAD_MECH; } error_out: - if (union_ctx_id) { + /* + * RFC 2744 5.1 requires that we not create a context on a failed first + * call to accept, and recommends that on a failed subsequent call we + * make the caller responsible for calling gss_delete_sec_context. + * Even if the mech deleted its context, keep the union context around + * for the caller to delete. + */ + if (union_ctx_id && *context_handle == GSS_C_NO_CONTEXT) { if (union_ctx_id->mech_type) { if (union_ctx_id->mech_type->elements) free(union_ctx_id->mech_type->elements); @@ -350,7 +359,6 @@ error_out: GSS_C_NO_BUFFER); } free(union_ctx_id); - *context_handle = GSS_C_NO_CONTEXT; } if (src_name) diff --git a/src/lib/gssapi/mechglue/g_complete_auth_token.c b/src/lib/gssapi/mechglue/g_complete_auth_token.c index 9181551..4bcb47e 100644 --- a/src/lib/gssapi/mechglue/g_complete_auth_token.c +++ b/src/lib/gssapi/mechglue/g_complete_auth_token.c @@ -52,6 +52,8 @@ gss_complete_auth_token (OM_uint32 *minor_status, */ ctx = (gss_union_ctx_id_t) context_handle; + if (ctx->internal_ctx_id == GSS_C_NO_CONTEXT) + return GSS_S_NO_CONTEXT; mech = gssint_get_mechanism (ctx->mech_type); if (mech != NULL) { diff --git a/src/lib/gssapi/mechglue/g_context_time.c b/src/lib/gssapi/mechglue/g_context_time.c index 2ff8d09..c947e76 100644 --- a/src/lib/gssapi/mechglue/g_context_time.c +++ b/src/lib/gssapi/mechglue/g_context_time.c @@ -58,6 +58,8 @@ OM_uint32 * time_rec; */ ctx = (gss_union_ctx_id_t) context_handle; + if (ctx->internal_ctx_id == GSS_C_NO_CONTEXT) + return (GSS_S_NO_CONTEXT); mech = gssint_get_mechanism (ctx->mech_type); if (mech) { diff --git a/src/lib/gssapi/mechglue/g_delete_sec_context.c b/src/lib/gssapi/mechglue/g_delete_sec_context.c index 4bf0dec..574ff02 100644 --- a/src/lib/gssapi/mechglue/g_delete_sec_context.c +++ b/src/lib/gssapi/mechglue/g_delete_sec_context.c @@ -87,12 +87,14 @@ gss_buffer_t output_token; if (GSSINT_CHK_LOOP(ctx)) return (GSS_S_CALL_INACCESSIBLE_READ | GSS_S_NO_CONTEXT); - status = gssint_delete_internal_sec_context(minor_status, - ctx->mech_type, - &ctx->internal_ctx_id, - output_token); - if (status) - return status; + if (ctx->internal_ctx_id != GSS_C_NO_CONTEXT) { + status = gssint_delete_internal_sec_context(minor_status, + ctx->mech_type, + &ctx->internal_ctx_id, + output_token); + if (status) + return status; + } /* now free up the space for the union context structure */ free(ctx->mech_type->elements); diff --git a/src/lib/gssapi/mechglue/g_exp_sec_context.c b/src/lib/gssapi/mechglue/g_exp_sec_context.c index e5f95ad..24accf1 100644 --- a/src/lib/gssapi/mechglue/g_exp_sec_context.c +++ b/src/lib/gssapi/mechglue/g_exp_sec_context.c @@ -89,6 +89,9 @@ gss_buffer_t interprocess_token; if (status != GSS_S_COMPLETE) return (status); + if (ctx->internal_ctx_id == GSS_C_NO_CONTEXT) + return (GSS_S_NO_CONTEXT); + /* * select the approprate underlying mechanism routine and * call it. diff --git a/src/lib/gssapi/mechglue/g_init_sec_context.c b/src/lib/gssapi/mechglue/g_init_sec_context.c index aaae767..f3d4363 100644 --- a/src/lib/gssapi/mechglue/g_init_sec_context.c +++ b/src/lib/gssapi/mechglue/g_init_sec_context.c @@ -192,8 +192,13 @@ OM_uint32 * time_rec; /* copy the supplied context handle */ union_ctx_id->internal_ctx_id = GSS_C_NO_CONTEXT; - } else + } else { union_ctx_id = (gss_union_ctx_id_t)*context_handle; + if (union_ctx_id->internal_ctx_id == GSS_C_NO_CONTEXT) { + status = GSS_S_NO_CONTEXT; + goto end; + } + } /* * get the appropriate cred handle from the union cred struct. @@ -223,12 +228,13 @@ OM_uint32 * time_rec; time_rec); if (status != GSS_S_COMPLETE && status != GSS_S_CONTINUE_NEEDED) { - /* - * the spec says (the preferred) method is to delete all - * context info on the first call to init, and on all - * subsequent calls make the caller responsible for - * calling gss_delete_sec_context - */ + /* + * RFC 2744 5.19 requires that we not create a context on a failed + * first call to init, and recommends that on a failed subsequent call + * we make the caller responsible for calling gss_delete_sec_context. + * Even if the mech deleted its context, keep the union context around + * for the caller to delete. + */ map_error(minor_status, mech); if (*context_handle == GSS_C_NO_CONTEXT) { free(union_ctx_id->mech_type->elements); diff --git a/src/lib/gssapi/mechglue/g_inq_context.c b/src/lib/gssapi/mechglue/g_inq_context.c index d3fb343..470ccc3 100644 --- a/src/lib/gssapi/mechglue/g_inq_context.c +++ b/src/lib/gssapi/mechglue/g_inq_context.c @@ -104,6 +104,8 @@ gss_inquire_context( */ ctx = (gss_union_ctx_id_t) context_handle; + if (ctx->internal_ctx_id == GSS_C_NO_CONTEXT) + return (GSS_S_NO_CONTEXT); mech = gssint_get_mechanism (ctx->mech_type); if (!mech || !mech->gss_inquire_context || !mech->gss_display_name || diff --git a/src/lib/gssapi/mechglue/g_prf.c b/src/lib/gssapi/mechglue/g_prf.c index fcca3e4..9e168ad 100644 --- a/src/lib/gssapi/mechglue/g_prf.c +++ b/src/lib/gssapi/mechglue/g_prf.c @@ -59,6 +59,8 @@ gss_pseudo_random (OM_uint32 *minor_status, */ ctx = (gss_union_ctx_id_t) context_handle; + if (ctx->internal_ctx_id == GSS_C_NO_CONTEXT) + return GSS_S_NO_CONTEXT; mech = gssint_get_mechanism (ctx->mech_type); if (mech != NULL) { diff --git a/src/lib/gssapi/mechglue/g_process_context.c b/src/lib/gssapi/mechglue/g_process_context.c index bc260ae..3968b5d 100644 --- a/src/lib/gssapi/mechglue/g_process_context.c +++ b/src/lib/gssapi/mechglue/g_process_context.c @@ -61,6 +61,8 @@ gss_buffer_t token_buffer; */ ctx = (gss_union_ctx_id_t) context_handle; + if (ctx->internal_ctx_id == GSS_C_NO_CONTEXT) + return (GSS_S_NO_CONTEXT); mech = gssint_get_mechanism (ctx->mech_type); if (mech) { diff --git a/src/lib/gssapi/mechglue/g_seal.c b/src/lib/gssapi/mechglue/g_seal.c index f17241c..3db1ee0 100644 --- a/src/lib/gssapi/mechglue/g_seal.c +++ b/src/lib/gssapi/mechglue/g_seal.c @@ -92,6 +92,8 @@ gss_wrap( OM_uint32 *minor_status, */ ctx = (gss_union_ctx_id_t) context_handle; + if (ctx->internal_ctx_id == GSS_C_NO_CONTEXT) + return (GSS_S_NO_CONTEXT); mech = gssint_get_mechanism (ctx->mech_type); if (mech) { @@ -226,6 +228,8 @@ gss_wrap_size_limit(OM_uint32 *minor_status, */ ctx = (gss_union_ctx_id_t) context_handle; + if (ctx->internal_ctx_id == GSS_C_NO_CONTEXT) + return (GSS_S_NO_CONTEXT); mech = gssint_get_mechanism (ctx->mech_type); if (!mech) diff --git a/src/lib/gssapi/mechglue/g_sign.c b/src/lib/gssapi/mechglue/g_sign.c index 86d641a..03fbd8c 100644 --- a/src/lib/gssapi/mechglue/g_sign.c +++ b/src/lib/gssapi/mechglue/g_sign.c @@ -94,6 +94,8 @@ gss_buffer_t msg_token; */ ctx = (gss_union_ctx_id_t) context_handle; + if (ctx->internal_ctx_id == GSS_C_NO_CONTEXT) + return (GSS_S_NO_CONTEXT); mech = gssint_get_mechanism (ctx->mech_type); if (mech) { diff --git a/src/lib/gssapi/mechglue/g_unseal.c b/src/lib/gssapi/mechglue/g_unseal.c index 3e8053c..c208635 100644 --- a/src/lib/gssapi/mechglue/g_unseal.c +++ b/src/lib/gssapi/mechglue/g_unseal.c @@ -76,6 +76,8 @@ gss_qop_t * qop_state; * call it. */ ctx = (gss_union_ctx_id_t) context_handle; + if (ctx->internal_ctx_id == GSS_C_NO_CONTEXT) + return (GSS_S_NO_CONTEXT); mech = gssint_get_mechanism (ctx->mech_type); if (mech) { diff --git a/src/lib/gssapi/mechglue/g_unwrap_aead.c b/src/lib/gssapi/mechglue/g_unwrap_aead.c index e78bff2..0682bd8 100644 --- a/src/lib/gssapi/mechglue/g_unwrap_aead.c +++ b/src/lib/gssapi/mechglue/g_unwrap_aead.c @@ -186,6 +186,8 @@ gss_qop_t *qop_state; * call it. */ ctx = (gss_union_ctx_id_t) context_handle; + if (ctx->internal_ctx_id == GSS_C_NO_CONTEXT) + return (GSS_S_NO_CONTEXT); mech = gssint_get_mechanism (ctx->mech_type); if (!mech) diff --git a/src/lib/gssapi/mechglue/g_unwrap_iov.c b/src/lib/gssapi/mechglue/g_unwrap_iov.c index c0dd314..599be2c 100644 --- a/src/lib/gssapi/mechglue/g_unwrap_iov.c +++ b/src/lib/gssapi/mechglue/g_unwrap_iov.c @@ -89,6 +89,8 @@ int iov_count; */ ctx = (gss_union_ctx_id_t) context_handle; + if (ctx->internal_ctx_id == GSS_C_NO_CONTEXT) + return (GSS_S_NO_CONTEXT); mech = gssint_get_mechanism (ctx->mech_type); if (mech) { @@ -128,6 +130,8 @@ gss_verify_mic_iov(OM_uint32 *minor_status, gss_ctx_id_t context_handle, /* Select the approprate underlying mechanism routine and call it. */ ctx = (gss_union_ctx_id_t)context_handle; + if (ctx->internal_ctx_id == GSS_C_NO_CONTEXT) + return GSS_S_NO_CONTEXT; mech = gssint_get_mechanism(ctx->mech_type); if (mech == NULL) return GSS_S_BAD_MECH; diff --git a/src/lib/gssapi/mechglue/g_verify.c b/src/lib/gssapi/mechglue/g_verify.c index 1578ae1..8996fce 100644 --- a/src/lib/gssapi/mechglue/g_verify.c +++ b/src/lib/gssapi/mechglue/g_verify.c @@ -65,6 +65,8 @@ gss_qop_t * qop_state; */ ctx = (gss_union_ctx_id_t) context_handle; + if (ctx->internal_ctx_id == GSS_C_NO_CONTEXT) + return (GSS_S_NO_CONTEXT); mech = gssint_get_mechanism (ctx->mech_type); if (mech) { diff --git a/src/lib/gssapi/mechglue/g_wrap_aead.c b/src/lib/gssapi/mechglue/g_wrap_aead.c index 96cdf3c..7fe3b7b 100644 --- a/src/lib/gssapi/mechglue/g_wrap_aead.c +++ b/src/lib/gssapi/mechglue/g_wrap_aead.c @@ -256,6 +256,8 @@ gss_buffer_t output_message_buffer; * call it. */ ctx = (gss_union_ctx_id_t)context_handle; + if (ctx->internal_ctx_id == GSS_C_NO_CONTEXT) + return (GSS_S_NO_CONTEXT); mech = gssint_get_mechanism (ctx->mech_type); if (!mech) return (GSS_S_BAD_MECH); diff --git a/src/lib/gssapi/mechglue/g_wrap_iov.c b/src/lib/gssapi/mechglue/g_wrap_iov.c index 40cd98f..14447c4 100644 --- a/src/lib/gssapi/mechglue/g_wrap_iov.c +++ b/src/lib/gssapi/mechglue/g_wrap_iov.c @@ -93,6 +93,8 @@ int iov_count; */ ctx = (gss_union_ctx_id_t) context_handle; + if (ctx->internal_ctx_id == GSS_C_NO_CONTEXT) + return (GSS_S_NO_CONTEXT); mech = gssint_get_mechanism (ctx->mech_type); if (mech) { @@ -151,6 +153,8 @@ int iov_count; */ ctx = (gss_union_ctx_id_t) context_handle; + if (ctx->internal_ctx_id == GSS_C_NO_CONTEXT) + return (GSS_S_NO_CONTEXT); mech = gssint_get_mechanism (ctx->mech_type); if (mech) { @@ -190,6 +194,8 @@ gss_get_mic_iov(OM_uint32 *minor_status, gss_ctx_id_t context_handle, /* Select the approprate underlying mechanism routine and call it. */ ctx = (gss_union_ctx_id_t)context_handle; + if (ctx->internal_ctx_id == GSS_C_NO_CONTEXT) + return GSS_S_NO_CONTEXT; mech = gssint_get_mechanism(ctx->mech_type); if (mech == NULL) return GSS_S_BAD_MECH; @@ -218,6 +224,8 @@ gss_get_mic_iov_length(OM_uint32 *minor_status, gss_ctx_id_t context_handle, /* Select the approprate underlying mechanism routine and call it. */ ctx = (gss_union_ctx_id_t)context_handle; + if (ctx->internal_ctx_id == GSS_C_NO_CONTEXT) + return GSS_S_NO_CONTEXT; mech = gssint_get_mechanism(ctx->mech_type); if (mech == NULL) return GSS_S_BAD_MECH; -- 2.14.2
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor