Patrick Williams | b48b7b4 | 2016-08-17 15:04:38 -0500 | [diff] [blame^] | 1 | From aa769c8c6905d1abfac66d4d1b0fc73740ccbe7d Mon Sep 17 00:00:00 2001 |
| 2 | From: Greg Hudson <ghudson@mit.edu> |
| 3 | Date: Sat, 14 Nov 2015 02:47:04 -0500 |
| 4 | Subject: [PATCH 4/4] Fix IAKERB context export/import [CVE-2015-2698] |
| 5 | |
| 6 | The patches for CVE-2015-2696 contained a regression in the newly |
| 7 | added IAKERB iakerb_gss_export_sec_context() function, which could |
| 8 | cause it to corrupt memory. Fix the regression by properly |
| 9 | dereferencing the context_handle pointer before casting it. |
| 10 | |
| 11 | Also, the patches did not implement an IAKERB gss_import_sec_context() |
| 12 | function, under the erroneous belief that an exported IAKERB context |
| 13 | would be tagged as a krb5 context. Implement it now to allow IAKERB |
| 14 | contexts to be successfully exported and imported after establishment. |
| 15 | |
| 16 | CVE-2015-2698: |
| 17 | |
| 18 | In any MIT krb5 release with the patches for CVE-2015-2696 applied, an |
| 19 | application which calls gss_export_sec_context() may experience memory |
| 20 | corruption if the context was established using the IAKERB mechanism. |
| 21 | Historically, some vulnerabilities of this nature can be translated |
| 22 | into remote code execution, though the necessary exploits must be |
| 23 | tailored to the individual application and are usually quite |
| 24 | complicated. |
| 25 | |
| 26 | CVSSv2 Vector: AV:N/AC:H/Au:S/C:C/I:C/A:C/E:POC/RL:OF/RC:C |
| 27 | |
| 28 | ticket: 8273 (new) |
| 29 | target_version: 1.14 |
| 30 | tags: pullup |
| 31 | |
| 32 | Backport upstream commit: |
| 33 | https://github.com/krb5/krb5/commit/3db8dfec1ef50ddd78d6ba9503185995876a39fd |
| 34 | |
| 35 | Upstream-Status: Backport |
| 36 | --- |
| 37 | src/lib/gssapi/krb5/gssapiP_krb5.h | 5 +++++ |
| 38 | src/lib/gssapi/krb5/gssapi_krb5.c | 2 +- |
| 39 | src/lib/gssapi/krb5/iakerb.c | 42 +++++++++++++++++++++++++++++++------- |
| 40 | 3 files changed, 41 insertions(+), 8 deletions(-) |
| 41 | |
| 42 | diff --git a/src/lib/gssapi/krb5/gssapiP_krb5.h b/src/lib/gssapi/krb5/gssapiP_krb5.h |
| 43 | index 05dc321..ac53662 100644 |
| 44 | --- a/src/lib/gssapi/krb5/gssapiP_krb5.h |
| 45 | +++ b/src/lib/gssapi/krb5/gssapiP_krb5.h |
| 46 | @@ -1396,6 +1396,11 @@ OM_uint32 KRB5_CALLCONV |
| 47 | iakerb_gss_export_sec_context(OM_uint32 *minor_status, |
| 48 | gss_ctx_id_t *context_handle, |
| 49 | gss_buffer_t interprocess_token); |
| 50 | + |
| 51 | +OM_uint32 KRB5_CALLCONV |
| 52 | +iakerb_gss_import_sec_context(OM_uint32 *minor_status, |
| 53 | + const gss_buffer_t interprocess_token, |
| 54 | + gss_ctx_id_t *context_handle); |
| 55 | #endif /* LEAN_CLIENT */ |
| 56 | |
| 57 | OM_uint32 KRB5_CALLCONV |
| 58 | diff --git a/src/lib/gssapi/krb5/gssapi_krb5.c b/src/lib/gssapi/krb5/gssapi_krb5.c |
| 59 | index 9a23656..d7ba279 100644 |
| 60 | --- a/src/lib/gssapi/krb5/gssapi_krb5.c |
| 61 | +++ b/src/lib/gssapi/krb5/gssapi_krb5.c |
| 62 | @@ -945,7 +945,7 @@ static struct gss_config iakerb_mechanism = { |
| 63 | NULL, |
| 64 | #else |
| 65 | iakerb_gss_export_sec_context, |
| 66 | - NULL, |
| 67 | + iakerb_gss_import_sec_context, |
| 68 | #endif |
| 69 | krb5_gss_inquire_cred_by_mech, |
| 70 | krb5_gss_inquire_names_for_mech, |
| 71 | diff --git a/src/lib/gssapi/krb5/iakerb.c b/src/lib/gssapi/krb5/iakerb.c |
| 72 | index 4662bd9..48beaee 100644 |
| 73 | --- a/src/lib/gssapi/krb5/iakerb.c |
| 74 | +++ b/src/lib/gssapi/krb5/iakerb.c |
| 75 | @@ -1061,7 +1061,7 @@ iakerb_gss_export_sec_context(OM_uint32 *minor_status, |
| 76 | gss_buffer_t interprocess_token) |
| 77 | { |
| 78 | OM_uint32 maj; |
| 79 | - iakerb_ctx_id_t ctx = (iakerb_ctx_id_t)context_handle; |
| 80 | + iakerb_ctx_id_t ctx = (iakerb_ctx_id_t)*context_handle; |
| 81 | |
| 82 | /* We don't currently support exporting partially established contexts. */ |
| 83 | if (!ctx->established) |
| 84 | @@ -1076,13 +1076,41 @@ iakerb_gss_export_sec_context(OM_uint32 *minor_status, |
| 85 | return maj; |
| 86 | } |
| 87 | |
| 88 | -/* |
| 89 | - * Until we implement partial context exports, there are no SPNEGO exported |
| 90 | - * context tokens, only tokens for the underlying krb5 context. So we do not |
| 91 | - * need to implement an iakerb_gss_import_sec_context() yet; it would be |
| 92 | - * unreachable except via a manually constructed token. |
| 93 | - */ |
| 94 | +OM_uint32 KRB5_CALLCONV |
| 95 | +iakerb_gss_import_sec_context(OM_uint32 *minor_status, |
| 96 | + gss_buffer_t interprocess_token, |
| 97 | + gss_ctx_id_t *context_handle) |
| 98 | +{ |
| 99 | + OM_uint32 maj, tmpmin; |
| 100 | + krb5_error_code code; |
| 101 | + gss_ctx_id_t gssc; |
| 102 | + krb5_gss_ctx_id_t kctx; |
| 103 | + iakerb_ctx_id_t ctx; |
| 104 | + |
| 105 | + maj = krb5_gss_import_sec_context(minor_status, interprocess_token, &gssc); |
| 106 | + if (maj != GSS_S_COMPLETE) |
| 107 | + return maj; |
| 108 | + kctx = (krb5_gss_ctx_id_t)gssc; |
| 109 | + |
| 110 | + if (!kctx->established) { |
| 111 | + /* We don't currently support importing partially established |
| 112 | + * contexts. */ |
| 113 | + krb5_gss_delete_sec_context(&tmpmin, &gssc, GSS_C_NO_BUFFER); |
| 114 | + return GSS_S_FAILURE; |
| 115 | + } |
| 116 | |
| 117 | + code = iakerb_alloc_context(&ctx, kctx->initiate); |
| 118 | + if (code != 0) { |
| 119 | + krb5_gss_delete_sec_context(&tmpmin, &gssc, GSS_C_NO_BUFFER); |
| 120 | + *minor_status = code; |
| 121 | + return GSS_S_FAILURE; |
| 122 | + } |
| 123 | + |
| 124 | + ctx->gssc = gssc; |
| 125 | + ctx->established = 1; |
| 126 | + *context_handle = (gss_ctx_id_t)ctx; |
| 127 | + return GSS_S_COMPLETE; |
| 128 | +} |
| 129 | #endif /* LEAN_CLIENT */ |
| 130 | |
| 131 | OM_uint32 KRB5_CALLCONV |
| 132 | -- |
| 133 | 1.9.1 |
| 134 | |