[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#776981: marked as done (unblock: krb5/1.12.1+dfsg-17)



Your message dated Tue, 03 Feb 2015 20:34:40 +0100
with message-id <54D122D0.60404@thykier.net>
and subject line Re: Bug#776981: unblock: krb5/1.12.1+dfsg-17
has caused the Debian Bug report #776981,
regarding unblock: krb5/1.12.1+dfsg-17
to be marked as done.

This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.

(NB: If you are a system administrator and have no idea what this
message is talking about, this may indicate a serious mail system
misconfiguration somewhere. Please contact owner@bugs.debian.org
immediately.)


-- 
776981: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=776981
Debian Bug Tracking System
Contact owner@bugs.debian.org with problems
--- Begin Message ---
Package: release.debian.org
Severity: normal
User: release.debian.org@packages.debian.org
Usertags: unblock

Please unblock package krb5

This version includes the upstream official patch for
mitkrb5-sa-2015-001, a series of security vulnerabilities made public
today.  I've received permission from the security team to upload a
backport of this patch to stable-security.

diff --git a/debian/.git-dpm b/debian/.git-dpm
index 423df28..237c3b1 100644
--- a/debian/.git-dpm
+++ b/debian/.git-dpm
@@ -1,6 +1,6 @@
 # see git-dpm(1) from git-dpm package
-877ad027ca2103f3ac2f581451fdd347a76b8981
-877ad027ca2103f3ac2f581451fdd347a76b8981
+769a3f26c919339002ef2936592a90d144d0e238
+769a3f26c919339002ef2936592a90d144d0e238
 00dec38e79dd6436e9efed873df00e6ea11fdd0e
 00dec38e79dd6436e9efed873df00e6ea11fdd0e
 krb5_1.12.1+dfsg.orig.tar.gz
diff --git a/debian/changelog b/debian/changelog
index 226cc36..c8a284c 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,14 @@
+krb5 (1.12.1+dfsg-17) unstable; urgency=high
+
+  * MITKRB5-SA-2015-001
+    - CVE-2014-5352: gss_process_context_token() incorrectly frees context
+    - CVE-2014-9421: kadmind doubly frees partial deserialization results
+    - CVE-2014-9422: kadmind incorrectly validates server principal name  
+      - CVE-2014-9423: libgssrpc server applications leak uninitialized bytes
+
+
+ -- Sam Hartman <hartmans@debian.org>  Tue, 03 Feb 2015 10:29:35 -0500
+
 krb5 (1.12.1+dfsg-16) unstable; urgency=medium
 
   * Import upstream patches for CVE-2014-5353 and CVE-2014-5354,
diff --git a/debian/patches/series b/debian/patches/series
index 9d19440..721cb89 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -26,3 +26,4 @@ upstream/0025-Fix-build-on-systems-without-RTM_OLD.patch
 upstream/0026-Remove-rtm_type_name.patch
 upstream/0027-Fix-LDAP-misused-policy-name-crash-CVE-2014-5353.patch
 0028-Support-keyless-principals-in-LDAP-CVE-2014-5354.patch
+upstream/0029-MITKRB5-SA-2015-0001.patch
diff --git a/debian/patches/upstream/0029-MITKRB5-SA-2015-0001.patch b/debian/patches/upstream/0029-MITKRB5-SA-2015-0001.patch
new file mode 100644
index 0000000..c8183a3
--- /dev/null
+++ b/debian/patches/upstream/0029-MITKRB5-SA-2015-0001.patch
@@ -0,0 +1,397 @@
+From 769a3f26c919339002ef2936592a90d144d0e238 Mon Sep 17 00:00:00 2001
+From: Sam Hartman <hartmans@debian.org>
+Date: Tue, 3 Feb 2015 10:26:16 -0500
+Subject: MITKRB5-SA-2015-0001
+
+Topic: Vulnerabilities in kadmind, libgssrpc, gss_process_context_token
+
+CVE-2014-5352: gss_process_context_token() incorrectly frees context
+
+CVSSv2 Vector: AV:N/AC:L/Au:S/C:C/I:C/A:C/E:POC/RL:OF/RC:C
+
+CVSSv2 Base Score:      9.0
+
+Access Vector:          Network
+Access Complexity:      Low
+Authentication:         Single
+Confidentiality Impact: Complete
+Integrity Impact:       Complete
+Availability Impact:    Complete
+
+CVSSv2 Temporal Score:  7.0
+
+Exploitability:         Proof-of-Concept
+Remediation Level:      Official Fix
+Report Confidence:      Confirmed
+
+CVE-2014-9421: kadmind doubly frees partial deserialization results
+
+CVSSv2 Vector: AV:N/AC:L/Au:S/C:C/I:C/A:C/E:POC/RL:OF/RC:C
+CVSSv2 Base Score:      9.0
+CVSSv2 Temporal Score:  7.0
+
+CVE-2014-9422: kadmind incorrectly validates server principal name
+
+CVSSv2 Vector: AV:N/AC:H/Au:S/C:P/I:P/A:C/E:POC/RL:OF/RC:C
+CVSSv2 Base Score:      6.1
+CVSSv2 Temporal Score:  4.8
+
+CVE-2014-9423: libgssrpc server applications leak uninitialized bytes
+
+CVSSv2 Vector: AV:N/AC:L/Au:N/C:P/I:N/A:N/E:H/RL:OF/RC:C
+CVSSv2 Base Score:      5.0
+CVSSv2 Temporal Score:  4.4
+
+Patch-Category: upstream
+---
+ src/kadmin/server/kadm_rpc_svc.c            | 12 +++---------
+ src/lib/gssapi/krb5/context_time.c          |  2 +-
+ src/lib/gssapi/krb5/export_sec_context.c    |  5 +++++
+ src/lib/gssapi/krb5/gssapiP_krb5.h          |  1 +
+ src/lib/gssapi/krb5/gssapi_krb5.c           |  2 +-
+ src/lib/gssapi/krb5/inq_context.c           |  2 +-
+ src/lib/gssapi/krb5/k5seal.c                |  2 +-
+ src/lib/gssapi/krb5/k5sealiov.c             |  2 +-
+ src/lib/gssapi/krb5/k5unseal.c              |  2 +-
+ src/lib/gssapi/krb5/k5unsealiov.c           |  2 +-
+ src/lib/gssapi/krb5/lucid_context.c         |  5 +++++
+ src/lib/gssapi/krb5/prf.c                   |  4 ++++
+ src/lib/gssapi/krb5/process_context_token.c | 17 ++++++++++++-----
+ src/lib/gssapi/krb5/wrap_size_limit.c       |  2 +-
+ src/lib/gssapi/mechglue/mglueP.h            |  1 -
+ src/lib/kadm5/kadm_rpc_xdr.c                |  2 ++
+ src/lib/rpc/auth_gssapi_misc.c              |  1 -
+ src/lib/rpc/svc_auth_gss.c                  | 25 ++-----------------------
+ 18 files changed, 42 insertions(+), 47 deletions(-)
+
+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);
+ 
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);
 



unblock krb5/1.12.1+dfsg-17

-- System Information:
Debian Release: jessie/sid
  APT prefers stable-updates
  APT policy: (500, 'stable-updates'), (500, 'stable'), (250, 'testing'), (200, 'unstable')
Architecture: amd64 (x86_64)

Kernel: Linux 3.16-2-amd64 (SMP w/4 CPU cores)
Locale: LANG=en_US.utf8, LC_CTYPE=en_US.utf8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash

--- End Message ---
--- Begin Message ---
On 2015-02-03 20:18, Sam Hartman wrote:
> Package: release.debian.org
> Severity: normal
> User: release.debian.org@packages.debian.org
> Usertags: unblock
> 
> Please unblock package krb5
> 
> This version includes the upstream official patch for
> mitkrb5-sa-2015-001, a series of security vulnerabilities made public
> today.  I've received permission from the security team to upload a
> backport of this patch to stable-security.
> 
> [...]
> 
> unblock krb5/1.12.1+dfsg-17
> 
> [...]

Unblocked, thanks.

~Niels

--- End Message ---

Reply to: