313 lines
10 KiB
Plaintext
313 lines
10 KiB
Plaintext
$NetBSD: patch-2015-001-patch-r110,v 1.1 2015/02/25 22:28:58 tez Exp $
|
|
|
|
Patch for MITKRB5-SA-2015-001.txt backported
|
|
based on http://web.mit.edu/kerberos/advisories/2015-001-patch-r111.txt
|
|
Fixes:
|
|
http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-5352
|
|
http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-9421
|
|
http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-9422
|
|
http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-9423
|
|
|
|
|
|
--- ./kadmin/server/kadm_rpc_svc.c.orig 2015-02-25 19:03:47.134238800 +0000
|
|
+++ ./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>
|
|
@@ -301,14 +301,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) {
|
|
|
|
--- ./lib/gssapi/krb5/context_time.c.orig 2015-02-25 19:49:12.558472400 +0000
|
|
+++ ./lib/gssapi/krb5/context_time.c
|
|
@@ -40,7 +40,7 @@ krb5_gss_context_time(minor_status, cont
|
|
|
|
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);
|
|
}
|
|
|
|
--- ./lib/gssapi/krb5/export_sec_context.c.orig 2015-02-25 20:12:11.511021400 +0000
|
|
+++ ./lib/gssapi/krb5/export_sec_context.c
|
|
@@ -45,6 +45,11 @@ krb5_gss_export_sec_context(minor_status
|
|
*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)
|
|
|
|
--- ./lib/gssapi/krb5/gssapiP_krb5.h.orig 2015-02-25 20:13:50.580912000 +0000
|
|
+++ ./lib/gssapi/krb5/gssapiP_krb5.h
|
|
@@ -202,6 +202,7 @@ typedef struct _krb5_gss_ctx_id_rec {
|
|
unsigned int big_endian : 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;
|
|
|
|
--- ./lib/gssapi/krb5/gssapi_krb5.c.orig 2015-02-25 20:15:28.221874100 +0000
|
|
+++ ./lib/gssapi/krb5/gssapi_krb5.c
|
|
@@ -369,7 +369,7 @@ krb5_gss_inquire_sec_context_by_oid (OM_
|
|
|
|
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)/
|
|
|
|
--- ./lib/gssapi/krb5/inq_context.c.orig 2015-02-25 20:17:05.258340000 +0000
|
|
+++ ./lib/gssapi/krb5/inq_context.c
|
|
@@ -105,7 +105,7 @@ krb5_gss_inquire_context(minor_status, c
|
|
|
|
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);
|
|
}
|
|
|
|
--- ./lib/gssapi/krb5/k5seal.c.orig 2015-02-25 20:18:07.402899400 +0000
|
|
+++ ./lib/gssapi/krb5/k5seal.c
|
|
@@ -347,7 +347,7 @@ kg_seal(minor_status, context_handle, co
|
|
|
|
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);
|
|
}
|
|
|
|
--- ./lib/gssapi/krb5/k5sealiov.c.orig 2015-02-25 20:19:26.092234800 +0000
|
|
+++ ./lib/gssapi/krb5/k5sealiov.c
|
|
@@ -285,7 +285,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;
|
|
}
|
|
|
|
--- ./lib/gssapi/krb5/k5unseal.c.orig 2013-11-06 20:52:23.000000000 +0000
|
|
+++ ./lib/gssapi/krb5/k5unseal.c
|
|
@@ -487,7 +487,7 @@ kg_unseal(minor_status, context_handle,
|
|
|
|
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);
|
|
}
|
|
|
|
--- ./lib/gssapi/krb5/k5unsealiov.c.orig 2013-11-06 20:52:23.000000000 +0000
|
|
+++ ./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;
|
|
}
|
|
|
|
--- ./lib/gssapi/krb5/lucid_context.c.orig 2015-02-25 20:27:11.529478500 +0000
|
|
+++ ./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,
|
|
|
|
--- ./lib/gssapi/krb5/prf.c.orig 2015-02-25 20:28:38.970661400 +0000
|
|
+++ ./lib/gssapi/krb5/prf.c
|
|
@@ -60,6 +60,10 @@ krb5_gss_pseudo_random(OM_uint32 *minor_
|
|
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:
|
|
|
|
--- ./lib/gssapi/krb5/process_context_token.c.orig 2015-02-25 20:29:45.187213100 +0000
|
|
+++ ./lib/gssapi/krb5/process_context_token.c
|
|
@@ -39,11 +39,18 @@ krb5_gss_process_context_token(minor_sta
|
|
|
|
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_sta
|
|
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);
|
|
}
|
|
|
|
--- ./lib/gssapi/krb5/wrap_size_limit.c.orig 2015-02-25 20:32:00.325325300 +0000
|
|
+++ ./lib/gssapi/krb5/wrap_size_limit.c
|
|
@@ -95,7 +95,7 @@ krb5_gss_wrap_size_limit(minor_status, c
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
--- ./lib/kadm5/kadm_rpc_xdr.c.orig 2015-02-25 20:48:14.376390200 +0000
|
|
+++ ./lib/kadm5/kadm_rpc_xdr.c
|
|
@@ -320,6 +320,7 @@ bool_t xdr_krb5_tl_data(XDR *xdrs, krb5_
|
|
free(tl);
|
|
tl = tl2;
|
|
}
|
|
+ *tl_data_head = NULL;
|
|
break;
|
|
|
|
case XDR_ENCODE:
|
|
@@ -1067,6 +1068,7 @@ xdr_krb5_principal(XDR *xdrs, krb5_princ
|
|
case XDR_FREE:
|
|
if(*objp != NULL)
|
|
krb5_free_principal(context, *objp);
|
|
+ *objp = NULL;
|
|
break;
|
|
}
|
|
return TRUE;
|
|
|
|
--- ./lib/rpc/auth_gssapi_misc.c.orig 2015-02-25 20:51:31.250618000 +0000
|
|
+++ ./lib/rpc/auth_gssapi_misc.c
|
|
@@ -321,7 +321,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;
|
|
}
|
|
|
|
--- ./lib/rpc/svc_auth_gss.c.orig 2015-02-25 20:52:40.715734700 +0000
|
|
+++ ./lib/rpc/svc_auth_gss.c
|
|
@@ -68,16 +68,6 @@ extern const gss_OID_desc * const gss_me
|
|
|
|
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_badverf_func log_badverf = NULL;
|
|
@@ -235,16 +225,8 @@ svcauth_gss_accept_sec_context(struct sv
|
|
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;
|
|
@@ -516,8 +498,6 @@ gssrpc__svcauth_gss(struct svc_req *rqst
|
|
|
|
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;
|
|
@@ -527,7 +507,6 @@ gssrpc__svcauth_gss(struct svc_req *rqst
|
|
|
|
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);
|
|
|