diff options
Diffstat (limited to 'app-crypt/mit-krb5/files')
-rw-r--r-- | app-crypt/mit-krb5/files/2015-001-patch-r113.patch | 343 | ||||
-rw-r--r-- | app-crypt/mit-krb5/files/mit-krb5-CVE-2014-5353.patch | 19 | ||||
-rw-r--r-- | app-crypt/mit-krb5/files/mit-krb5-CVE-2014-5354.patch | 56 |
3 files changed, 418 insertions, 0 deletions
diff --git a/app-crypt/mit-krb5/files/2015-001-patch-r113.patch b/app-crypt/mit-krb5/files/2015-001-patch-r113.patch new file mode 100644 index 000000000000..455735ba41c8 --- /dev/null +++ b/app-crypt/mit-krb5/files/2015-001-patch-r113.patch @@ -0,0 +1,343 @@ +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 7e807cc..a0e8625 100644 +--- a/src/lib/gssapi/krb5/gssapiP_krb5.h ++++ b/src/lib/gssapi/krb5/gssapiP_krb5.h +@@ -206,6 +206,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 6456b23..77b7fff 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 7665cba..f1c74dd 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 a129670..b53e348 100644 +--- a/src/lib/gssapi/krb5/k5sealiov.c ++++ b/src/lib/gssapi/krb5/k5sealiov.c +@@ -281,7 +281,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 0573958..673c883 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 f34d802..8b67042 100644 +--- a/src/lib/gssapi/krb5/k5unsealiov.c ++++ b/src/lib/gssapi/krb5/k5unsealiov.c +@@ -625,7 +625,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 85df7fd..449e71f 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 e19291f..e897074 100644 +--- a/src/lib/gssapi/krb5/prf.c ++++ b/src/lib/gssapi/krb5/prf.c +@@ -58,6 +58,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 09a3534..b81c4a3 100644 +--- a/src/lib/rpc/svc_auth_gss.c ++++ b/src/lib/rpc/svc_auth_gss.c +@@ -65,16 +65,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; +@@ -239,16 +229,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; +@@ -520,8 +502,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; +@@ -531,7 +511,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/tests/gssapi/t_prf.c b/src/tests/gssapi/t_prf.c +index 254f8fb..7f04899 100644 +--- a/src/tests/gssapi/t_prf.c ++++ b/src/tests/gssapi/t_prf.c +@@ -127,6 +127,7 @@ main(int argc, char *argv[]) + 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; diff --git a/app-crypt/mit-krb5/files/mit-krb5-CVE-2014-5353.patch b/app-crypt/mit-krb5/files/mit-krb5-CVE-2014-5353.patch new file mode 100644 index 000000000000..8f8712beec5f --- /dev/null +++ b/app-crypt/mit-krb5/files/mit-krb5-CVE-2014-5353.patch @@ -0,0 +1,19 @@ +diff --git a/src/plugins/kdb/ldap/libkdb_ldap/ldap_pwd_policy.c b/src/plugins/kdb/ldap/libkdb_ldap/ldap_pwd_policy.c +index 522773e..6779f51 100644 +--- a/src/plugins/kdb/ldap/libkdb_ldap/ldap_pwd_policy.c ++++ b/src/plugins/kdb/ldap/libkdb_ldap/ldap_pwd_policy.c +@@ -314,10 +314,11 @@ krb5_ldap_get_password_policy_from_dn(krb5_context context, char *pol_name, + LDAP_SEARCH(pol_dn, LDAP_SCOPE_BASE, "(objectclass=krbPwdPolicy)", password_policy_attributes); + + ent=ldap_first_entry(ld, result); +- if (ent != NULL) { +- if ((st = populate_policy(context, ld, ent, pol_name, *policy)) != 0) +- goto cleanup; ++ if (ent == NULL) { ++ st = KRB5_KDB_NOENTRY; ++ goto cleanup; + } ++ st = populate_policy(context, ld, ent, pol_name, *policy); + + cleanup: + ldap_msgfree(result); diff --git a/app-crypt/mit-krb5/files/mit-krb5-CVE-2014-5354.patch b/app-crypt/mit-krb5/files/mit-krb5-CVE-2014-5354.patch new file mode 100644 index 000000000000..3ec02bed0d8e --- /dev/null +++ b/app-crypt/mit-krb5/files/mit-krb5-CVE-2014-5354.patch @@ -0,0 +1,56 @@ +diff --git a/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal2.c b/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal2.c +index 3e560d9..10b5982 100644 +--- a/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal2.c ++++ b/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal2.c +@@ -406,14 +406,14 @@ krb5_encode_krbsecretkey(krb5_key_data *key_data_in, int n_key_data, + int num_versions = 1; + int i, j, last; + krb5_error_code err = 0; +- krb5_key_data *key_data; ++ krb5_key_data *key_data = NULL; + +- if (n_key_data <= 0) ++ if (n_key_data < 0) + return NULL; + + /* Make a shallow copy of the key data so we can alter it. */ + key_data = k5calloc(n_key_data, sizeof(*key_data), &err); +- if (key_data_in == NULL) ++ if (key_data == NULL) + goto cleanup; + memcpy(key_data, key_data_in, n_key_data * sizeof(*key_data)); + +@@ -467,9 +467,8 @@ krb5_encode_krbsecretkey(krb5_key_data *key_data_in, int n_key_data, + free(key_data); + if (err != 0) { + if (ret != NULL) { +- for (i = 0; i <= num_versions; i++) +- if (ret[i] != NULL) +- free (ret[i]); ++ for (i = 0; ret[i] != NULL; i++) ++ free (ret[i]); + free (ret); + ret = NULL; + } +@@ -1036,9 +1035,19 @@ krb5_ldap_put_principal(krb5_context context, krb5_db_entry *entry, + bersecretkey = krb5_encode_krbsecretkey (entry->key_data, + entry->n_key_data, mkvno); + +- if ((st=krb5_add_ber_mem_ldap_mod(&mods, "krbprincipalkey", +- LDAP_MOD_REPLACE | LDAP_MOD_BVALUES, bersecretkey)) != 0) ++ if (bersecretkey == NULL) { ++ st = ENOMEM; + goto cleanup; ++ } ++ /* An empty list of bervals is only accepted for modify operations, ++ * not add operations. */ ++ if (bersecretkey[0] != NULL || !create_standalone_prinicipal) { ++ st = krb5_add_ber_mem_ldap_mod(&mods, "krbprincipalkey", ++ LDAP_MOD_REPLACE | LDAP_MOD_BVALUES, ++ bersecretkey); ++ if (st != 0) ++ goto cleanup; ++ } + + if (!(entry->mask & KADM5_PRINCIPAL)) { + memset(strval, 0, sizeof(strval)); |