krb5 commit [krb5-1.14]: Fix IAKERB context export/import [CVE-2015-2698]

Tom Yu tlyu at mit.edu
Thu Nov 5 15:22:40 EST 2015


https://github.com/krb5/krb5/commit/54222de30a89bfac0247dfbc1759556dc9fd2983
commit 54222de30a89bfac0247dfbc1759556dc9fd2983
Author: Greg Hudson <ghudson at mit.edu>
Date:   Sun Nov 1 22:45:21 2015 -0500

    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
    
    (cherry picked from commit 3db8dfec1ef50ddd78d6ba9503185995876a39fd)
    
    ticket: 8273
    version_fixed: 1.14

 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 97e090d..1663500 100644
--- a/src/lib/gssapi/krb5/gssapiP_krb5.h
+++ b/src/lib/gssapi/krb5/gssapiP_krb5.h
@@ -1397,6 +1397,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 c4dfdd6..aea60dc 100644
--- a/src/lib/gssapi/krb5/gssapi_krb5.c
+++ b/src/lib/gssapi/krb5/gssapi_krb5.c
@@ -970,7 +970,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 e25862d..32a341e 100644
--- a/src/lib/gssapi/krb5/iakerb.c
+++ b/src/lib/gssapi/krb5/iakerb.c
@@ -1057,7 +1057,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)
@@ -1072,13 +1072,41 @@ iakerb_gss_export_sec_context(OM_uint32 *minor_status,
     return maj;
 }
 
-/*
- * Until we implement partial context exports, there are no IAKERB 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


More information about the cvs-krb5 mailing list