From c74e97faa9ad835134949df282f9c153c2d2b9bb Mon Sep 17 00:00:00 2001 From: Roland Mainz Date: Wed, 4 Feb 2015 12:02:36 +0100 Subject: [PATCH] * Wed Feb 4 2015 Roland Mainz - 1.13-8 - fix for CVE-2014-5352 (#1179856) "gss_process_context_token() incorrectly frees context (MITKRB5-SA-2015-001)" - fix for CVE-2014-9421 (#1179857) "kadmind doubly frees partial deserialization results (MITKRB5-SA-2015-001)" - fix for CVE-2014-9422 (#1179861) "kadmind incorrectly validates server principal name (MITKRB5-SA-2015-001)" - fix for CVE-2014-9423 (#1179863) "libgssrpc server applications leak uninitialized bytes (MITKRB5-SA-2015-001)" --- krb5.spec | 14 +- ...014_9423_2014_5352_fixed_whitespaces.patch | 324 ++++++++++++++++++ 2 files changed, 337 insertions(+), 1 deletion(-) create mode 100644 krb5_cve_2014_9421_2014_9422_2014_9423_2014_5352_fixed_whitespaces.patch diff --git a/krb5.spec b/krb5.spec index 4cee9a6..c8d9b89 100644 --- a/krb5.spec +++ b/krb5.spec @@ -43,7 +43,7 @@ Summary: The Kerberos network authentication system Name: krb5 Version: 1.13 -Release: 7%{?dist} +Release: 8%{?dist} # - Maybe we should explode from the now-available-to-everybody tarball instead? # http://web.mit.edu/kerberos/dist/krb5/1.13/krb5-1.13-signed.tar # - The sources below are stored in a lookaside cache. Upload with @@ -98,6 +98,7 @@ Patch137: krb5-CVE_2014_5353_fix_LDAP_misused_policy_name_crash.patch Patch138: krb5-CVE_2014_5354_support_keyless_principals_in_LDAP.patch Patch139: krb5-1.13_kinit_C_loop_krb5bug243.patch Patch140: krb5-1.14-Support-KDC_ERR_MORE_PREAUTH_DATA_REQUIRED.patch +Patch141: krb5_cve_2014_9421_2014_9422_2014_9423_2014_5352_fixed_whitespaces.patch License: MIT URL: http://web.mit.edu/kerberos/www/ @@ -323,6 +324,7 @@ ln NOTICE LICENSE %patch138 -p1 %patch139 -p1 -b .krb5_1_13_kinit_C_loop_krb5bug243 %patch140 -p1 -b .krb5-1.14-support-kdc_err_more_preauth_data_required +%patch141 -p1 -b .krb5_cve_2014_9421_2014_9422_2014_9423_2014_5352_fixed_whitespaces # Take the execute bit off of documentation. chmod -x doc/krb5-protocol/*.txt doc/ccapi/*.html @@ -995,6 +997,16 @@ exit 0 %changelog +* Wed Feb 4 2015 Roland Mainz - 1.13-8 +- fix for CVE-2014-5352 (#1179856) "gss_process_context_token() + incorrectly frees context (MITKRB5-SA-2015-001)" +- fix for CVE-2014-9421 (#1179857) "kadmind doubly frees partial + deserialization results (MITKRB5-SA-2015-001)" +- fix for CVE-2014-9422 (#1179861) "kadmind incorrectly + validates server principal name (MITKRB5-SA-2015-001)" +- fix for CVE-2014-9423 (#1179863) "libgssrpc server applications + leak uninitialized bytes (MITKRB5-SA-2015-001)" + * Wed Feb 4 2015 Roland Mainz - 1.13-7 - Remove "python-sphinx-latex" and "tar" from the build requirements to fix build failures on F22 machines. diff --git a/krb5_cve_2014_9421_2014_9422_2014_9423_2014_5352_fixed_whitespaces.patch b/krb5_cve_2014_9421_2014_9422_2014_9423_2014_5352_fixed_whitespaces.patch new file mode 100644 index 0000000..b0c047b --- /dev/null +++ b/krb5_cve_2014_9421_2014_9422_2014_9423_2014_5352_fixed_whitespaces.patch @@ -0,0 +1,324 @@ +diff -r -u krb5-1.13/src/kadmin/server/kadm_rpc_svc.c krb5-1.13/src/kadmin/server/kadm_rpc_svc.c +--- krb5-1.13/src/kadmin/server/kadm_rpc_svc.c 2014-10-16 01:55:10.000000000 +0200 ++++ krb5-1.13/src/kadmin/server/kadm_rpc_svc.c 2015-02-04 11:29:00.891062971 +0100 +@@ -4,7 +4,7 @@ + * + */ + +-#include ++#include + #include + #include /* for gss_nt_krb5_name */ + #include +@@ -296,14 +296,8 @@ + c1 = krb5_princ_component(kctx, princ, 0); + c2 = krb5_princ_component(kctx, princ, 1); + realm = krb5_princ_realm(kctx, princ); +- if (strncmp(handle->params.realm, realm->data, realm->length) == 0 +- && strncmp("kadmin", c1->data, c1->length) == 0) { +- +- if (strncmp("history", c2->data, c2->length) == 0) +- goto fail_princ; +- else +- success = 1; +- } ++ success = data_eq_string(*realm, handle->params.realm) && ++ data_eq_string(*c1, "kadmin") && !data_eq_string(*c2, "history"); + + fail_princ: + if (!success) { +diff -r -u krb5-1.13/src/lib/gssapi/krb5/context_time.c krb5-1.13/src/lib/gssapi/krb5/context_time.c +--- krb5-1.13/src/lib/gssapi/krb5/context_time.c 2014-10-16 01:55:10.000000000 +0200 ++++ krb5-1.13/src/lib/gssapi/krb5/context_time.c 2015-02-04 11:29:00.891062971 +0100 +@@ -40,7 +40,7 @@ + + ctx = (krb5_gss_ctx_id_rec *) context_handle; + +- if (! ctx->established) { ++ if (ctx->terminated || !ctx->established) { + *minor_status = KG_CTX_INCOMPLETE; + return(GSS_S_NO_CONTEXT); + } +diff -r -u krb5-1.13/src/lib/gssapi/krb5/export_sec_context.c krb5-1.13/src/lib/gssapi/krb5/export_sec_context.c +--- krb5-1.13/src/lib/gssapi/krb5/export_sec_context.c 2014-10-16 01:55:10.000000000 +0200 ++++ krb5-1.13/src/lib/gssapi/krb5/export_sec_context.c 2015-02-04 11:29:00.892063013 +0100 +@@ -45,6 +45,11 @@ + *minor_status = 0; + + ctx = (krb5_gss_ctx_id_t) *context_handle; ++ if (ctx->terminated) { ++ *minor_status = KG_CTX_INCOMPLETE; ++ return (GSS_S_NO_CONTEXT); ++ } ++ + context = ctx->k5_context; + kret = krb5_gss_ser_init(context); + if (kret) +diff -r -u krb5-1.13/src/lib/gssapi/krb5/gssapi_krb5.c krb5-1.13/src/lib/gssapi/krb5/gssapi_krb5.c +--- krb5-1.13/src/lib/gssapi/krb5/gssapi_krb5.c 2014-10-16 01:55:10.000000000 +0200 ++++ krb5-1.13/src/lib/gssapi/krb5/gssapi_krb5.c 2015-02-04 11:29:00.893063056 +0100 +@@ -369,7 +369,7 @@ + + ctx = (krb5_gss_ctx_id_rec *) context_handle; + +- if (!ctx->established) ++ if (ctx->terminated || !ctx->established) + return GSS_S_NO_CONTEXT; + + for (i = 0; i < sizeof(krb5_gss_inquire_sec_context_by_oid_ops)/ +diff -r -u krb5-1.13/src/lib/gssapi/krb5/gssapiP_krb5.h krb5-1.13/src/lib/gssapi/krb5/gssapiP_krb5.h +--- krb5-1.13/src/lib/gssapi/krb5/gssapiP_krb5.h 2014-10-16 01:55:10.000000000 +0200 ++++ krb5-1.13/src/lib/gssapi/krb5/gssapiP_krb5.h 2015-02-04 11:29:00.893063056 +0100 +@@ -206,6 +206,7 @@ + unsigned int established : 1; + unsigned int have_acceptor_subkey : 1; + unsigned int seed_init : 1; /* XXX tested but never actually set */ ++ unsigned int terminated : 1; + OM_uint32 gss_flags; + unsigned char seed[16]; + krb5_gss_name_t here; +diff -r -u krb5-1.13/src/lib/gssapi/krb5/inq_context.c krb5-1.13/src/lib/gssapi/krb5/inq_context.c +--- krb5-1.13/src/lib/gssapi/krb5/inq_context.c 2014-10-16 01:55:10.000000000 +0200 ++++ krb5-1.13/src/lib/gssapi/krb5/inq_context.c 2015-02-04 11:29:00.895063144 +0100 +@@ -105,7 +105,7 @@ + + ctx = (krb5_gss_ctx_id_rec *) context_handle; + +- if (! ctx->established) { ++ if (ctx->terminated || !ctx->established) { + *minor_status = KG_CTX_INCOMPLETE; + return(GSS_S_NO_CONTEXT); + } +diff -r -u krb5-1.13/src/lib/gssapi/krb5/k5seal.c krb5-1.13/src/lib/gssapi/krb5/k5seal.c +--- krb5-1.13/src/lib/gssapi/krb5/k5seal.c 2014-10-16 01:55:10.000000000 +0200 ++++ krb5-1.13/src/lib/gssapi/krb5/k5seal.c 2015-02-04 11:29:00.896063191 +0100 +@@ -342,7 +342,7 @@ + + ctx = (krb5_gss_ctx_id_rec *) context_handle; + +- if (! ctx->established) { ++ if (ctx->terminated || !ctx->established) { + *minor_status = KG_CTX_INCOMPLETE; + return(GSS_S_NO_CONTEXT); + } +diff -r -u krb5-1.13/src/lib/gssapi/krb5/k5sealiov.c krb5-1.13/src/lib/gssapi/krb5/k5sealiov.c +--- krb5-1.13/src/lib/gssapi/krb5/k5sealiov.c 2014-10-16 01:55:10.000000000 +0200 ++++ krb5-1.13/src/lib/gssapi/krb5/k5sealiov.c 2015-02-04 11:29:00.896063191 +0100 +@@ -281,7 +281,7 @@ + } + + ctx = (krb5_gss_ctx_id_rec *)context_handle; +- if (!ctx->established) { ++ if (ctx->terminated || !ctx->established) { + *minor_status = KG_CTX_INCOMPLETE; + return GSS_S_NO_CONTEXT; + } +diff -r -u krb5-1.13/src/lib/gssapi/krb5/k5unseal.c krb5-1.13/src/lib/gssapi/krb5/k5unseal.c +--- krb5-1.13/src/lib/gssapi/krb5/k5unseal.c 2014-10-16 01:55:10.000000000 +0200 ++++ krb5-1.13/src/lib/gssapi/krb5/k5unseal.c 2015-02-04 11:29:00.897063240 +0100 +@@ -492,7 +492,7 @@ + + ctx = (krb5_gss_ctx_id_rec *) context_handle; + +- if (! ctx->established) { ++ if (ctx->terminated || !ctx->established) { + *minor_status = KG_CTX_INCOMPLETE; + return(GSS_S_NO_CONTEXT); + } +diff -r -u krb5-1.13/src/lib/gssapi/krb5/k5unsealiov.c krb5-1.13/src/lib/gssapi/krb5/k5unsealiov.c +--- krb5-1.13/src/lib/gssapi/krb5/k5unsealiov.c 2014-10-16 01:55:10.000000000 +0200 ++++ krb5-1.13/src/lib/gssapi/krb5/k5unsealiov.c 2015-02-04 11:29:00.897063240 +0100 +@@ -625,7 +625,7 @@ + OM_uint32 code; + + ctx = (krb5_gss_ctx_id_rec *)context_handle; +- if (!ctx->established) { ++ if (ctx->terminated || !ctx->established) { + *minor_status = KG_CTX_INCOMPLETE; + return GSS_S_NO_CONTEXT; + } +diff -r -u krb5-1.13/src/lib/gssapi/krb5/lucid_context.c krb5-1.13/src/lib/gssapi/krb5/lucid_context.c +--- krb5-1.13/src/lib/gssapi/krb5/lucid_context.c 2014-10-16 01:55:10.000000000 +0200 ++++ krb5-1.13/src/lib/gssapi/krb5/lucid_context.c 2015-02-04 11:29:00.897063240 +0100 +@@ -75,6 +75,11 @@ + *minor_status = 0; + *data_set = GSS_C_NO_BUFFER_SET; + ++ if (ctx->terminated || !ctx->established) { ++ *minor_status = KG_CTX_INCOMPLETE; ++ return GSS_S_NO_CONTEXT; ++ } ++ + retval = generic_gss_oid_decompose(minor_status, + GSS_KRB5_EXPORT_LUCID_SEC_CONTEXT_OID, + GSS_KRB5_EXPORT_LUCID_SEC_CONTEXT_OID_LENGTH, +diff -r -u krb5-1.13/src/lib/gssapi/krb5/prf.c krb5-1.13/src/lib/gssapi/krb5/prf.c +--- krb5-1.13/src/lib/gssapi/krb5/prf.c 2014-10-16 01:55:10.000000000 +0200 ++++ krb5-1.13/src/lib/gssapi/krb5/prf.c 2015-02-04 11:29:00.899063344 +0100 +@@ -58,6 +58,10 @@ + ns.data = NULL; + + ctx = (krb5_gss_ctx_id_t)context; ++ if (ctx->terminated || !ctx->established) { ++ *minor_status = KG_CTX_INCOMPLETE; ++ return GSS_S_NO_CONTEXT; ++ } + + switch (prf_key) { + case GSS_C_PRF_KEY_FULL: +diff -r -u krb5-1.13/src/lib/gssapi/krb5/process_context_token.c krb5-1.13/src/lib/gssapi/krb5/process_context_token.c +--- krb5-1.13/src/lib/gssapi/krb5/process_context_token.c 2014-10-16 01:55:10.000000000 +0200 ++++ krb5-1.13/src/lib/gssapi/krb5/process_context_token.c 2015-02-04 11:29:00.899063344 +0100 +@@ -39,11 +39,18 @@ + + ctx = (krb5_gss_ctx_id_t) context_handle; + +- if (! ctx->established) { ++ if (ctx->terminated || !ctx->established) { + *minor_status = KG_CTX_INCOMPLETE; + return(GSS_S_NO_CONTEXT); + } + ++ /* We only support context deletion tokens for now, and RFC 4121 does not ++ * define a context deletion token. */ ++ if (ctx->proto) { ++ *minor_status = 0; ++ return(GSS_S_DEFECTIVE_TOKEN); ++ } ++ + /* "unseal" the token */ + + if (GSS_ERROR(majerr = kg_unseal(minor_status, context_handle, +@@ -52,8 +59,8 @@ + KG_TOK_DEL_CTX))) + return(majerr); + +- /* that's it. delete the context */ +- +- return(krb5_gss_delete_sec_context(minor_status, &context_handle, +- GSS_C_NO_BUFFER)); ++ /* Mark the context as terminated, but do not delete it (as that would ++ * leave the caller with a dangling context handle). */ ++ ctx->terminated = 1; ++ return(GSS_S_COMPLETE); + } +diff -r -u krb5-1.13/src/lib/gssapi/krb5/wrap_size_limit.c krb5-1.13/src/lib/gssapi/krb5/wrap_size_limit.c +--- krb5-1.13/src/lib/gssapi/krb5/wrap_size_limit.c 2014-10-16 01:55:10.000000000 +0200 ++++ krb5-1.13/src/lib/gssapi/krb5/wrap_size_limit.c 2015-02-04 11:29:00.899063344 +0100 +@@ -95,7 +95,7 @@ + } + + ctx = (krb5_gss_ctx_id_rec *) context_handle; +- if (! ctx->established) { ++ if (ctx->terminated || !ctx->established) { + *minor_status = KG_CTX_INCOMPLETE; + return(GSS_S_NO_CONTEXT); + } +diff -r -u krb5-1.13/src/lib/gssapi/mechglue/mglueP.h krb5-1.13/src/lib/gssapi/mechglue/mglueP.h +--- krb5-1.13/src/lib/gssapi/mechglue/mglueP.h 2014-10-16 01:55:10.000000000 +0200 ++++ krb5-1.13/src/lib/gssapi/mechglue/mglueP.h 2015-02-04 11:29:00.901063453 +0100 +@@ -25,7 +25,6 @@ + */ + typedef struct gss_union_ctx_id_struct { + struct gss_union_ctx_id_struct *loopback; +- struct gss_union_ctx_id_struct *interposer; + gss_OID mech_type; + gss_ctx_id_t internal_ctx_id; + } gss_union_ctx_id_desc, *gss_union_ctx_id_t; +diff -r -u krb5-1.13/src/lib/kadm5/kadm_rpc_xdr.c krb5-1.13/src/lib/kadm5/kadm_rpc_xdr.c +--- krb5-1.13/src/lib/kadm5/kadm_rpc_xdr.c 2014-10-16 01:55:10.000000000 +0200 ++++ krb5-1.13/src/lib/kadm5/kadm_rpc_xdr.c 2015-02-04 11:29:00.901063453 +0100 +@@ -320,6 +320,7 @@ + free(tl); + tl = tl2; + } ++ *tl_data_head = NULL; + break; + + case XDR_ENCODE: +@@ -1096,6 +1097,7 @@ + case XDR_FREE: + if(*objp != NULL) + krb5_free_principal(context, *objp); ++ *objp = NULL; + break; + } + return TRUE; +diff -r -u krb5-1.13/src/lib/rpc/auth_gssapi_misc.c krb5-1.13/src/lib/rpc/auth_gssapi_misc.c +--- krb5-1.13/src/lib/rpc/auth_gssapi_misc.c 2014-10-16 01:55:10.000000000 +0200 ++++ krb5-1.13/src/lib/rpc/auth_gssapi_misc.c 2015-02-04 11:29:00.901063453 +0100 +@@ -322,7 +322,6 @@ + if (! (*xdr_func)(&temp_xdrs, xdr_ptr)) { + PRINTF(("gssapi_unwrap_data: deserializing arguments failed\n")); + gss_release_buffer(minor, &out_buf); +- xdr_free(xdr_func, xdr_ptr); + XDR_DESTROY(&temp_xdrs); + return FALSE; + } +diff -r -u krb5-1.13/src/lib/rpc/svc_auth_gss.c krb5-1.13/src/lib/rpc/svc_auth_gss.c +--- krb5-1.13/src/lib/rpc/svc_auth_gss.c 2014-10-16 01:55:10.000000000 +0200 ++++ krb5-1.13/src/lib/rpc/svc_auth_gss.c 2015-02-04 11:29:00.903063567 +0100 +@@ -65,16 +65,6 @@ + + extern SVCAUTH svc_auth_none; + +-/* +- * from mit-krb5-1.2.1 mechglue/mglueP.h: +- * Array of context IDs typed by mechanism OID +- */ +-typedef struct gss_union_ctx_id_t { +- gss_OID mech_type; +- gss_ctx_id_t internal_ctx_id; +-} gss_union_ctx_id_desc, *gss_union_ctx_id_t; +- +- + static auth_gssapi_log_badauth_func log_badauth = NULL; + static caddr_t log_badauth_data = NULL; + static auth_gssapi_log_badauth2_func log_badauth2 = NULL; +@@ -239,16 +229,8 @@ + gd->ctx = GSS_C_NO_CONTEXT; + goto errout; + } +- /* +- * ANDROS: krb5 mechglue returns ctx of size 8 - two pointers, +- * one to the mechanism oid, one to the internal_ctx_id +- */ +- if ((gr->gr_ctx.value = mem_alloc(sizeof(gss_union_ctx_id_desc))) == NULL) { +- fprintf(stderr, "svcauth_gss_accept_context: out of memory\n"); +- goto errout; +- } +- memcpy(gr->gr_ctx.value, gd->ctx, sizeof(gss_union_ctx_id_desc)); +- gr->gr_ctx.length = sizeof(gss_union_ctx_id_desc); ++ gr->gr_ctx.value = "xxxx"; ++ gr->gr_ctx.length = 4; + + /* gr->gr_win = 0x00000005; ANDROS: for debugging linux kernel version... */ + gr->gr_win = sizeof(gd->seqmask) * 8; +@@ -520,8 +502,6 @@ + + if (!svcauth_gss_nextverf(rqst, htonl(gr.gr_win))) { + gss_release_buffer(&min_stat, &gr.gr_token); +- mem_free(gr.gr_ctx.value, +- sizeof(gss_union_ctx_id_desc)); + ret_freegc (AUTH_FAILED); + } + *no_dispatch = TRUE; +@@ -531,7 +511,6 @@ + + gss_release_buffer(&min_stat, &gr.gr_token); + gss_release_buffer(&min_stat, &gd->checksum); +- mem_free(gr.gr_ctx.value, sizeof(gss_union_ctx_id_desc)); + if (!call_stat) + ret_freegc (AUTH_FAILED); + +diff -r -u krb5-1.13/src/tests/gssapi/t_prf.c krb5-1.13/src/tests/gssapi/t_prf.c +--- krb5-1.13/src/tests/gssapi/t_prf.c 2014-10-16 01:55:10.000000000 +0200 ++++ krb5-1.13/src/tests/gssapi/t_prf.c 2015-02-04 11:29:00.903063567 +0100 +@@ -127,6 +127,7 @@ + uctx.mech_type = &mech_krb5; + uctx.internal_ctx_id = (gss_ctx_id_t)&kgctx; + kgctx.k5_context = NULL; ++ kgctx.established = 1; + kgctx.have_acceptor_subkey = 1; + kb1.contents = k1buf; + kb2.contents = k2buf;