| From aa769c8c6905d1abfac66d4d1b0fc73740ccbe7d Mon Sep 17 00:00:00 2001 |
| From: Greg Hudson <ghudson@mit.edu> |
| Date: Sat, 14 Nov 2015 02:47:04 -0500 |
| Subject: [PATCH 4/4] Fix IAKERB context export/import [CVE-2015-2698] |
| |
| The patches for CVE-2015-2696 contained a regression in the newly |
| added IAKERB iakerb_gss_export_sec_context() function, which could |
| cause it to corrupt memory. Fix the regression by properly |
| dereferencing the context_handle pointer before casting it. |
| |
| Also, the patches did not implement an IAKERB gss_import_sec_context() |
| function, under the erroneous belief that an exported IAKERB context |
| would be tagged as a krb5 context. Implement it now to allow IAKERB |
| contexts to be successfully exported and imported after establishment. |
| |
| CVE-2015-2698: |
| |
| In any MIT krb5 release with the patches for CVE-2015-2696 applied, an |
| application which calls gss_export_sec_context() may experience memory |
| corruption if the context was established using the IAKERB mechanism. |
| Historically, some vulnerabilities of this nature can be translated |
| into remote code execution, though the necessary exploits must be |
| tailored to the individual application and are usually quite |
| complicated. |
| |
| CVSSv2 Vector: AV:N/AC:H/Au:S/C:C/I:C/A:C/E:POC/RL:OF/RC:C |
| |
| ticket: 8273 (new) |
| target_version: 1.14 |
| tags: pullup |
| |
| Backport upstream commit: |
| https://github.com/krb5/krb5/commit/3db8dfec1ef50ddd78d6ba9503185995876a39fd |
| |
| Upstream-Status: Backport |
| --- |
| src/lib/gssapi/krb5/gssapiP_krb5.h | 5 +++++ |
| src/lib/gssapi/krb5/gssapi_krb5.c | 2 +- |
| src/lib/gssapi/krb5/iakerb.c | 42 +++++++++++++++++++++++++++++++------- |
| 3 files changed, 41 insertions(+), 8 deletions(-) |
| |
| diff --git a/src/lib/gssapi/krb5/gssapiP_krb5.h b/src/lib/gssapi/krb5/gssapiP_krb5.h |
| index 05dc321..ac53662 100644 |
| --- a/src/lib/gssapi/krb5/gssapiP_krb5.h |
| +++ b/src/lib/gssapi/krb5/gssapiP_krb5.h |
| @@ -1396,6 +1396,11 @@ OM_uint32 KRB5_CALLCONV |
| iakerb_gss_export_sec_context(OM_uint32 *minor_status, |
| gss_ctx_id_t *context_handle, |
| gss_buffer_t interprocess_token); |
| + |
| +OM_uint32 KRB5_CALLCONV |
| +iakerb_gss_import_sec_context(OM_uint32 *minor_status, |
| + const gss_buffer_t interprocess_token, |
| + gss_ctx_id_t *context_handle); |
| #endif /* LEAN_CLIENT */ |
| |
| OM_uint32 KRB5_CALLCONV |
| diff --git a/src/lib/gssapi/krb5/gssapi_krb5.c b/src/lib/gssapi/krb5/gssapi_krb5.c |
| index 9a23656..d7ba279 100644 |
| --- a/src/lib/gssapi/krb5/gssapi_krb5.c |
| +++ b/src/lib/gssapi/krb5/gssapi_krb5.c |
| @@ -945,7 +945,7 @@ static struct gss_config iakerb_mechanism = { |
| NULL, |
| #else |
| iakerb_gss_export_sec_context, |
| - NULL, |
| + iakerb_gss_import_sec_context, |
| #endif |
| krb5_gss_inquire_cred_by_mech, |
| krb5_gss_inquire_names_for_mech, |
| diff --git a/src/lib/gssapi/krb5/iakerb.c b/src/lib/gssapi/krb5/iakerb.c |
| index 4662bd9..48beaee 100644 |
| --- a/src/lib/gssapi/krb5/iakerb.c |
| +++ b/src/lib/gssapi/krb5/iakerb.c |
| @@ -1061,7 +1061,7 @@ iakerb_gss_export_sec_context(OM_uint32 *minor_status, |
| gss_buffer_t interprocess_token) |
| { |
| OM_uint32 maj; |
| - iakerb_ctx_id_t ctx = (iakerb_ctx_id_t)context_handle; |
| + iakerb_ctx_id_t ctx = (iakerb_ctx_id_t)*context_handle; |
| |
| /* We don't currently support exporting partially established contexts. */ |
| if (!ctx->established) |
| @@ -1076,13 +1076,41 @@ iakerb_gss_export_sec_context(OM_uint32 *minor_status, |
| return maj; |
| } |
| |
| -/* |
| - * Until we implement partial context exports, there are no SPNEGO exported |
| - * context tokens, only tokens for the underlying krb5 context. So we do not |
| - * need to implement an iakerb_gss_import_sec_context() yet; it would be |
| - * unreachable except via a manually constructed token. |
| - */ |
| +OM_uint32 KRB5_CALLCONV |
| +iakerb_gss_import_sec_context(OM_uint32 *minor_status, |
| + gss_buffer_t interprocess_token, |
| + gss_ctx_id_t *context_handle) |
| +{ |
| + OM_uint32 maj, tmpmin; |
| + krb5_error_code code; |
| + gss_ctx_id_t gssc; |
| + krb5_gss_ctx_id_t kctx; |
| + iakerb_ctx_id_t ctx; |
| + |
| + maj = krb5_gss_import_sec_context(minor_status, interprocess_token, &gssc); |
| + if (maj != GSS_S_COMPLETE) |
| + return maj; |
| + kctx = (krb5_gss_ctx_id_t)gssc; |
| + |
| + if (!kctx->established) { |
| + /* We don't currently support importing partially established |
| + * contexts. */ |
| + krb5_gss_delete_sec_context(&tmpmin, &gssc, GSS_C_NO_BUFFER); |
| + return GSS_S_FAILURE; |
| + } |
| |
| + code = iakerb_alloc_context(&ctx, kctx->initiate); |
| + if (code != 0) { |
| + krb5_gss_delete_sec_context(&tmpmin, &gssc, GSS_C_NO_BUFFER); |
| + *minor_status = code; |
| + return GSS_S_FAILURE; |
| + } |
| + |
| + ctx->gssc = gssc; |
| + ctx->established = 1; |
| + *context_handle = (gss_ctx_id_t)ctx; |
| + return GSS_S_COMPLETE; |
| +} |
| #endif /* LEAN_CLIENT */ |
| |
| OM_uint32 KRB5_CALLCONV |
| -- |
| 1.9.1 |
| |