[krb5/f21] * Wed Feb 4 2015 Roland Mainz <rmainz at redhat.com> - 1.12.2-14 - fix for CVE-2014-5352 (#1179856) "gs
Roland Mainz
gisburn at fedoraproject.org
Wed Feb 4 17:05:30 UTC 2015
commit 602c3cf5c66ea45a776924bb73c3ce6fe8c1db85
Author: Roland Mainz <rmainz at redhat.com>
Date: Wed Feb 4 18:04:56 2015 +0100
* Wed Feb 4 2015 Roland Mainz <rmainz at redhat.com> - 1.12.2-14
- 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 +-
...422_2014_9423_2014_5352_krb5-1.12.2-final.patch | 331 ++++++++++++++++++++
2 files changed, 344 insertions(+), 1 deletions(-)
---
diff --git a/krb5.spec b/krb5.spec
index c497465..8e0abca 100644
--- a/krb5.spec
+++ b/krb5.spec
@@ -41,7 +41,7 @@
Summary: The Kerberos network authentication system
Name: krb5
Version: 1.12.2
-Release: 13%{?dist}
+Release: 14%{?dist}
# Maybe we should explode from the now-available-to-everybody tarball instead?
# http://web.mit.edu/kerberos/dist/krb5/1.12/krb5-1.12.2-signed.tar
Source0: krb5-%{version}.tar.gz
@@ -132,6 +132,7 @@ Patch320: krb5-CVE_2014_5353_fix_LDAP_misused_policy_name_crash.patch
Patch321: krb5-CVE_2014_5354_support_keyless_principals_in_LDAP.patch
Patch322: krb5-1.13_kinit_C_loop_krb5bug243.patch
Patch323: krb5-1.14-Support-KDC_ERR_MORE_PREAUTH_DATA_REQUIRED.patch
+Patch324: krb5_cve_2014_9421_2014_9422_2014_9423_2014_5352_krb5-1.12.2-final.patch
License: MIT
URL: http://web.mit.edu/kerberos/www/
@@ -402,6 +403,7 @@ chmod u+x src/util/paste-kdcproxy.py
%patch321 -p1
%patch322 -p1 -b .krb5_1_13_kinit_C_loop_krb5bug243
%patch323 -p1 -b .krb5-1.14-support-kdc_err_more_preauth_data_required
+%patch324 -p1 -b .krb5_cve_2014_9421_2014_9422_2014_9423_2014_5352_krb5-1.12.2-final
# Take the execute bit off of documentation.
chmod -x doc/krb5-protocol/*.txt doc/ccapi/*.html
@@ -1081,6 +1083,16 @@ exit 0
%changelog
+* Wed Feb 4 2015 Roland Mainz <rmainz at redhat.com> - 1.12.2-14
+- 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 <rmainz at redhat.com> - 1.12.2-13
- Support KDC_ERR_MORE_PREAUTH_DATA_REQUIRED (RT#8063)
diff --git a/krb5_cve_2014_9421_2014_9422_2014_9423_2014_5352_krb5-1.12.2-final.patch b/krb5_cve_2014_9421_2014_9422_2014_9423_2014_5352_krb5-1.12.2-final.patch
new file mode 100644
index 0000000..c7bb9a2
--- /dev/null
+++ b/krb5_cve_2014_9421_2014_9422_2014_9423_2014_5352_krb5-1.12.2-final.patch
@@ -0,0 +1,331 @@
+diff --git a/src/kadmin/server/kadm_rpc_svc.c b/src/kadmin/server/kadm_rpc_svc.c
+index 3837931..f4d2a7c 100644
+--- a/src/kadmin/server/kadm_rpc_svc.c
++++ b/src/kadmin/server/kadm_rpc_svc.c
+@@ -4,7 +4,7 @@
+ *
+ */
+
+-#include <k5-platform.h>
++#include <k5-int.h>
+ #include <gssrpc/rpc.h>
+ #include <gssapi/gssapi_krb5.h> /* for gss_nt_krb5_name */
+ #include <syslog.h>
+@@ -296,14 +296,8 @@ check_rpcsec_auth(struct svc_req *rqstp)
+ 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 --git a/src/lib/gssapi/krb5/context_time.c b/src/lib/gssapi/krb5/context_time.c
+index b3d1db0..a18cfb0 100644
+--- a/src/lib/gssapi/krb5/context_time.c
++++ b/src/lib/gssapi/krb5/context_time.c
+@@ -40,7 +40,7 @@ krb5_gss_context_time(minor_status, context_handle, time_rec)
+
+ 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 --git a/src/lib/gssapi/krb5/export_sec_context.c b/src/lib/gssapi/krb5/export_sec_context.c
+index 18a3a34..1b3de68 100644
+--- a/src/lib/gssapi/krb5/export_sec_context.c
++++ b/src/lib/gssapi/krb5/export_sec_context.c
+@@ -45,6 +45,11 @@ krb5_gss_export_sec_context(minor_status, context_handle, interprocess_token)
+ *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 --git a/src/lib/gssapi/krb5/gssapiP_krb5.h b/src/lib/gssapi/krb5/gssapiP_krb5.h
+index 0167816..42d16ad 100644
+--- a/src/lib/gssapi/krb5/gssapiP_krb5.h
++++ b/src/lib/gssapi/krb5/gssapiP_krb5.h
+@@ -204,6 +204,7 @@ typedef struct _krb5_gss_ctx_id_rec {
+ 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 --git a/src/lib/gssapi/krb5/gssapi_krb5.c b/src/lib/gssapi/krb5/gssapi_krb5.c
+index a408259..088219a 100644
+--- a/src/lib/gssapi/krb5/gssapi_krb5.c
++++ b/src/lib/gssapi/krb5/gssapi_krb5.c
+@@ -369,7 +369,7 @@ krb5_gss_inquire_sec_context_by_oid (OM_uint32 *minor_status,
+
+ 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 --git a/src/lib/gssapi/krb5/inq_context.c b/src/lib/gssapi/krb5/inq_context.c
+index eacb0fd..096df2a 100644
+--- a/src/lib/gssapi/krb5/inq_context.c
++++ b/src/lib/gssapi/krb5/inq_context.c
+@@ -105,7 +105,7 @@ krb5_gss_inquire_context(minor_status, context_handle, initiator_name,
+
+ 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 --git a/src/lib/gssapi/krb5/k5seal.c b/src/lib/gssapi/krb5/k5seal.c
+index bd1e2a6..b11b615 100644
+--- a/src/lib/gssapi/krb5/k5seal.c
++++ b/src/lib/gssapi/krb5/k5seal.c
+@@ -342,7 +342,7 @@ kg_seal(minor_status, context_handle, conf_req_flag, qop_req,
+
+ 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 --git a/src/lib/gssapi/krb5/k5sealiov.c b/src/lib/gssapi/krb5/k5sealiov.c
+index 0b99a77..0f80095 100644
+--- a/src/lib/gssapi/krb5/k5sealiov.c
++++ b/src/lib/gssapi/krb5/k5sealiov.c
+@@ -284,7 +284,7 @@ kg_seal_iov(OM_uint32 *minor_status,
+ }
+
+ 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 --git a/src/lib/gssapi/krb5/k5unseal.c b/src/lib/gssapi/krb5/k5unseal.c
+index b65c83c..9e78550 100644
+--- a/src/lib/gssapi/krb5/k5unseal.c
++++ b/src/lib/gssapi/krb5/k5unseal.c
+@@ -492,7 +492,7 @@ kg_unseal(minor_status, context_handle, input_token_buffer,
+
+ 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 --git a/src/lib/gssapi/krb5/k5unsealiov.c b/src/lib/gssapi/krb5/k5unsealiov.c
+index 8d6a2da..191de2c 100644
+--- a/src/lib/gssapi/krb5/k5unsealiov.c
++++ b/src/lib/gssapi/krb5/k5unsealiov.c
+@@ -628,7 +628,7 @@ kg_unseal_iov(OM_uint32 *minor_status,
+ 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 --git a/src/lib/gssapi/krb5/lucid_context.c b/src/lib/gssapi/krb5/lucid_context.c
+index dc129e1..50d8cc9 100644
+--- a/src/lib/gssapi/krb5/lucid_context.c
++++ b/src/lib/gssapi/krb5/lucid_context.c
+@@ -75,6 +75,11 @@ gss_krb5int_export_lucid_sec_context(
+ *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 --git a/src/lib/gssapi/krb5/prf.c b/src/lib/gssapi/krb5/prf.c
+index a0fbcda..4831f9f 100644
+--- a/src/lib/gssapi/krb5/prf.c
++++ b/src/lib/gssapi/krb5/prf.c
+@@ -60,6 +60,10 @@ krb5_gss_pseudo_random(OM_uint32 *minor_status,
+ 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 --git a/src/lib/gssapi/krb5/process_context_token.c b/src/lib/gssapi/krb5/process_context_token.c
+index ae33180..a672f48 100644
+--- a/src/lib/gssapi/krb5/process_context_token.c
++++ b/src/lib/gssapi/krb5/process_context_token.c
+@@ -39,11 +39,18 @@ krb5_gss_process_context_token(minor_status, context_handle,
+
+ 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 @@ krb5_gss_process_context_token(minor_status, context_handle,
+ 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 --git a/src/lib/gssapi/krb5/wrap_size_limit.c b/src/lib/gssapi/krb5/wrap_size_limit.c
+index 7bc4221..ed5c599 100644
+--- a/src/lib/gssapi/krb5/wrap_size_limit.c
++++ b/src/lib/gssapi/krb5/wrap_size_limit.c
+@@ -95,7 +95,7 @@ krb5_gss_wrap_size_limit(minor_status, context_handle, conf_req_flag,
+ }
+
+ 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 --git a/src/lib/gssapi/mechglue/mglueP.h b/src/lib/gssapi/mechglue/mglueP.h
+index e56b9c1..2b5145e 100644
+--- a/src/lib/gssapi/mechglue/mglueP.h
++++ b/src/lib/gssapi/mechglue/mglueP.h
+@@ -25,7 +25,6 @@ do { \
+ */
+ 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 --git a/src/lib/kadm5/kadm_rpc_xdr.c b/src/lib/kadm5/kadm_rpc_xdr.c
+index 42ac783..975f94c 100644
+--- a/src/lib/kadm5/kadm_rpc_xdr.c
++++ b/src/lib/kadm5/kadm_rpc_xdr.c
+@@ -320,6 +320,7 @@ bool_t xdr_krb5_tl_data(XDR *xdrs, krb5_tl_data **tl_data_head)
+ free(tl);
+ tl = tl2;
+ }
++ *tl_data_head = NULL;
+ break;
+
+ case XDR_ENCODE:
+@@ -1096,6 +1097,7 @@ xdr_krb5_principal(XDR *xdrs, krb5_principal *objp)
+ case XDR_FREE:
+ if(*objp != NULL)
+ krb5_free_principal(context, *objp);
++ *objp = NULL;
+ break;
+ }
+ return TRUE;
+diff --git a/src/lib/rpc/auth_gssapi_misc.c b/src/lib/rpc/auth_gssapi_misc.c
+index 53bdb98..a05ea19 100644
+--- a/src/lib/rpc/auth_gssapi_misc.c
++++ b/src/lib/rpc/auth_gssapi_misc.c
+@@ -322,7 +322,6 @@ bool_t auth_gssapi_unwrap_data(
+ 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 --git a/src/lib/rpc/svc_auth_gss.c b/src/lib/rpc/svc_auth_gss.c
+index 8da7003..ea8149b 100644
+--- a/src/lib/rpc/svc_auth_gss.c
++++ b/src/lib/rpc/svc_auth_gss.c
+@@ -68,16 +68,6 @@ extern const gss_OID_desc * const gss_mech_spkm3;
+
+ 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;
+@@ -242,16 +232,8 @@ svcauth_gss_accept_sec_context(struct svc_req *rqst,
+ 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;
+@@ -523,8 +505,6 @@ gssrpc__svcauth_gss(struct svc_req *rqst, struct rpc_msg *msg,
+
+ 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;
+@@ -534,7 +514,6 @@ gssrpc__svcauth_gss(struct svc_req *rqst, struct rpc_msg *msg,
+
+ 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);
+
More information about the scm-commits
mailing list