diff options
author | Mark H Weaver <mhw@netris.org> | 2016-02-04 02:02:20 -0500 |
---|---|---|
committer | Mark H Weaver <mhw@netris.org> | 2016-02-10 10:41:11 -0500 |
commit | 16114c3494026b908b116bf93b9eee5d871860ef (patch) | |
tree | efca01aac6efa9edfd3f2ec3bed86859a91b66af /gnu/packages/patches | |
parent | 42395bf5143b39a7b79520a94e825be472692482 (diff) |
gnu: mit-krb5: Update to 1.13.3; add fixes for CVE-2015-{8629,8630,8631}.
* gnu/packages/patches/mit-krb5-CVE-2015-2695-pt1.patch,
gnu/packages/patches/mit-krb5-CVE-2015-2695-pt2.patch,
gnu/packages/patches/mit-krb5-CVE-2015-2696.patch,
gnu/packages/patches/mit-krb5-CVE-2015-2697.patch,
gnu/packages/patches/mit-krb5-CVE-2015-2698-pt1.patch,
gnu/packages/patches/mit-krb5-CVE-2015-2698-pt2.patch: Delete files.
* gnu/packages/patches/mit-krb5-CVE-2015-8629.patch,
gnu/packages/patches/mit-krb5-CVE-2015-8630.patch,
gnu/packages/patches/mit-krb5-CVE-2015-8631.patch,
gnu/packages/patches/mit-krb5-init-context-null-spnego.patch: New files.
* gnu-system.am (dist_patch_DATA): Adjust accordingly.
* gnu/packages/mit-krb5.scm (mit-krb5): Update to 1.13.3.
[source]: Update URI to download conventional .tar.gz file. Add patches.
[native-inputs]: Remove old patches-as-inputs.
[arguments]: Remove hacks needed to cope with the older unconventional
tarball that contained an inner source tarball and signature: Remove
#:modules argument, and the custom 'unpack' and 'apply-patches' phases.
Diffstat (limited to 'gnu/packages/patches')
-rw-r--r-- | gnu/packages/patches/mit-krb5-CVE-2015-2695-pt1.patch | 569 | ||||
-rw-r--r-- | gnu/packages/patches/mit-krb5-CVE-2015-2695-pt2.patch | 65 | ||||
-rw-r--r-- | gnu/packages/patches/mit-krb5-CVE-2015-2696.patch | 736 | ||||
-rw-r--r-- | gnu/packages/patches/mit-krb5-CVE-2015-2697.patch | 55 | ||||
-rw-r--r-- | gnu/packages/patches/mit-krb5-CVE-2015-2698-pt1.patch | 43 | ||||
-rw-r--r-- | gnu/packages/patches/mit-krb5-CVE-2015-2698-pt2.patch | 132 | ||||
-rw-r--r-- | gnu/packages/patches/mit-krb5-CVE-2015-8629.patch | 51 | ||||
-rw-r--r-- | gnu/packages/patches/mit-krb5-CVE-2015-8630.patch | 81 | ||||
-rw-r--r-- | gnu/packages/patches/mit-krb5-CVE-2015-8631.patch | 576 | ||||
-rw-r--r-- | gnu/packages/patches/mit-krb5-init-context-null-spnego.patch | 49 |
10 files changed, 757 insertions, 1600 deletions
diff --git a/gnu/packages/patches/mit-krb5-CVE-2015-2695-pt1.patch b/gnu/packages/patches/mit-krb5-CVE-2015-2695-pt1.patch deleted file mode 100644 index 0f5603e228..0000000000 --- a/gnu/packages/patches/mit-krb5-CVE-2015-2695-pt1.patch +++ /dev/null @@ -1,569 +0,0 @@ -Copied from Debian. - -From b813d5811432faed844a2dfd3daecde914978f2c Mon Sep 17 00:00:00 2001 -From: Nicolas Williams <nico@twosigma.com> -Date: Mon, 14 Sep 2015 12:27:52 -0400 -Subject: Fix SPNEGO context aliasing bugs [CVE-2015-2695] - -The SPNEGO mechanism currently replaces its context handle with the -mechanism context handle upon establishment, under the assumption that -most GSS functions are only called after context establishment. This -assumption is incorrect, and can lead to aliasing violations for some -programs. Maintain the SPNEGO context structure after context -establishment and refer to it in all GSS methods. Add initiate and -opened flags to the SPNEGO context structure for use in -gss_inquire_context() prior to context establishment. - -CVE-2015-2695: - -In MIT krb5 1.5 and later, applications which call -gss_inquire_context() on a partially-established SPNEGO context can -cause the GSS-API library to read from a pointer using the wrong type, -generally causing a process crash. This bug may go unnoticed, because -the most common SPNEGO authentication scenario establishes the context -after just one call to gss_accept_sec_context(). Java server -applications using the native JGSS provider are vulnerable to this -bug. A carefully crafted SPNEGO packet might allow the -gss_inquire_context() call to succeed with attacker-determined -results, but applications should not make access control decisions -based on gss_inquire_context() results prior to context establishment. - - CVSSv2 Vector: AV:N/AC:M/Au:N/C:N/I:N/A:C/E:POC/RL:OF/RC:C - -[ghudson@mit.edu: several bugfixes, style changes, and edge-case -behavior changes; commit message and CVE description] - -ticket: 8244 -target_version: 1.14 -tags: pullup - -(cherry picked from commit b51b33f2bc5d1497ddf5bd107f791c101695000d) -Patch-Category: upstream ---- - src/lib/gssapi/spnego/gssapiP_spnego.h | 2 + - src/lib/gssapi/spnego/spnego_mech.c | 254 ++++++++++++++++++++++++--------- - 2 files changed, 192 insertions(+), 64 deletions(-) - -diff --git a/src/lib/gssapi/spnego/gssapiP_spnego.h b/src/lib/gssapi/spnego/gssapiP_spnego.h -index bc23f56..8e05736 100644 ---- a/src/lib/gssapi/spnego/gssapiP_spnego.h -+++ b/src/lib/gssapi/spnego/gssapiP_spnego.h -@@ -102,6 +102,8 @@ typedef struct { - int firstpass; - int mech_complete; - int nego_done; -+ int initiate; -+ int opened; - OM_uint32 ctx_flags; - gss_name_t internal_name; - gss_OID actual_mech; -diff --git a/src/lib/gssapi/spnego/spnego_mech.c b/src/lib/gssapi/spnego/spnego_mech.c -index 6e39c37..a1072b0 100644 ---- a/src/lib/gssapi/spnego/spnego_mech.c -+++ b/src/lib/gssapi/spnego/spnego_mech.c -@@ -104,7 +104,7 @@ static OM_uint32 get_negotiable_mechs(OM_uint32 *, spnego_gss_cred_id_t, - gss_cred_usage_t, gss_OID_set *); - static void release_spnego_ctx(spnego_gss_ctx_id_t *); - static void check_spnego_options(spnego_gss_ctx_id_t); --static spnego_gss_ctx_id_t create_spnego_ctx(void); -+static spnego_gss_ctx_id_t create_spnego_ctx(int); - static int put_mech_set(gss_OID_set mechSet, gss_buffer_t buf); - static int put_input_token(unsigned char **, gss_buffer_t, unsigned int); - static int put_mech_oid(unsigned char **, gss_OID_const, unsigned int); -@@ -442,7 +442,7 @@ check_spnego_options(spnego_gss_ctx_id_t spnego_ctx) - } - - static spnego_gss_ctx_id_t --create_spnego_ctx(void) -+create_spnego_ctx(int initiate) - { - spnego_gss_ctx_id_t spnego_ctx = NULL; - spnego_ctx = (spnego_gss_ctx_id_t) -@@ -465,6 +465,8 @@ create_spnego_ctx(void) - spnego_ctx->mic_rcvd = 0; - spnego_ctx->mech_complete = 0; - spnego_ctx->nego_done = 0; -+ spnego_ctx->opened = 0; -+ spnego_ctx->initiate = initiate; - spnego_ctx->internal_name = GSS_C_NO_NAME; - spnego_ctx->actual_mech = GSS_C_NO_OID; - -@@ -630,7 +632,7 @@ init_ctx_new(OM_uint32 *minor_status, - OM_uint32 ret; - spnego_gss_ctx_id_t sc = NULL; - -- sc = create_spnego_ctx(); -+ sc = create_spnego_ctx(1); - if (sc == NULL) - return GSS_S_FAILURE; - -@@ -647,10 +649,7 @@ init_ctx_new(OM_uint32 *minor_status, - ret = GSS_S_FAILURE; - goto cleanup; - } -- /* -- * The actual context is not yet determined, set the output -- * context handle to refer to the spnego context itself. -- */ -+ - sc->ctx_handle = GSS_C_NO_CONTEXT; - *ctx = (gss_ctx_id_t)sc; - sc = NULL; -@@ -1091,16 +1090,11 @@ cleanup: - } - gss_release_buffer(&tmpmin, &mechtok_out); - if (ret == GSS_S_COMPLETE) { -- /* -- * Now, switch the output context to refer to the -- * negotiated mechanism's context. -- */ -- *context_handle = (gss_ctx_id_t)spnego_ctx->ctx_handle; -+ spnego_ctx->opened = 1; - if (actual_mech != NULL) - *actual_mech = spnego_ctx->actual_mech; - if (ret_flags != NULL) - *ret_flags = spnego_ctx->ctx_flags; -- release_spnego_ctx(&spnego_ctx); - } else if (ret != GSS_S_CONTINUE_NEEDED) { - if (spnego_ctx != NULL) { - gss_delete_sec_context(&tmpmin, -@@ -1344,7 +1338,7 @@ acc_ctx_hints(OM_uint32 *minor_status, - if (ret != GSS_S_COMPLETE) - goto cleanup; - -- sc = create_spnego_ctx(); -+ sc = create_spnego_ctx(0); - if (sc == NULL) { - ret = GSS_S_FAILURE; - goto cleanup; -@@ -1426,7 +1420,7 @@ acc_ctx_new(OM_uint32 *minor_status, - gss_release_buffer(&tmpmin, &sc->DER_mechTypes); - assert(mech_wanted != GSS_C_NO_OID); - } else -- sc = create_spnego_ctx(); -+ sc = create_spnego_ctx(0); - if (sc == NULL) { - ret = GSS_S_FAILURE; - *return_token = NO_TOKEN_SEND; -@@ -1809,13 +1803,12 @@ cleanup: - ret = GSS_S_FAILURE; - } - if (ret == GSS_S_COMPLETE) { -- *context_handle = (gss_ctx_id_t)sc->ctx_handle; -+ sc->opened = 1; - if (sc->internal_name != GSS_C_NO_NAME && - src_name != NULL) { - *src_name = sc->internal_name; - sc->internal_name = GSS_C_NO_NAME; - } -- release_spnego_ctx(&sc); - } else if (ret != GSS_S_CONTINUE_NEEDED) { - if (sc != NULL) { - gss_delete_sec_context(&tmpmin, &sc->ctx_handle, -@@ -2128,8 +2121,13 @@ spnego_gss_unwrap( - gss_qop_t *qop_state) - { - OM_uint32 ret; -+ spnego_gss_ctx_id_t sc = (spnego_gss_ctx_id_t)context_handle; -+ -+ if (sc->ctx_handle == GSS_C_NO_CONTEXT) -+ return (GSS_S_NO_CONTEXT); -+ - ret = gss_unwrap(minor_status, -- context_handle, -+ sc->ctx_handle, - input_message_buffer, - output_message_buffer, - conf_state, -@@ -2149,8 +2147,13 @@ spnego_gss_wrap( - gss_buffer_t output_message_buffer) - { - OM_uint32 ret; -+ spnego_gss_ctx_id_t sc = (spnego_gss_ctx_id_t)context_handle; -+ -+ if (sc->ctx_handle == GSS_C_NO_CONTEXT) -+ return (GSS_S_NO_CONTEXT); -+ - ret = gss_wrap(minor_status, -- context_handle, -+ sc->ctx_handle, - conf_req_flag, - qop_req, - input_message_buffer, -@@ -2167,8 +2170,14 @@ spnego_gss_process_context_token( - const gss_buffer_t token_buffer) - { - OM_uint32 ret; -+ spnego_gss_ctx_id_t sc = (spnego_gss_ctx_id_t)context_handle; -+ -+ /* SPNEGO doesn't have its own context tokens. */ -+ if (!sc->opened) -+ return (GSS_S_DEFECTIVE_TOKEN); -+ - ret = gss_process_context_token(minor_status, -- context_handle, -+ sc->ctx_handle, - token_buffer); - - return (ret); -@@ -2192,19 +2201,9 @@ spnego_gss_delete_sec_context( - if (*ctx == NULL) - return (GSS_S_COMPLETE); - -- /* -- * If this is still an SPNEGO mech, release it locally. -- */ -- if ((*ctx)->magic_num == SPNEGO_MAGIC_ID) { -- (void) gss_delete_sec_context(minor_status, -- &(*ctx)->ctx_handle, -- output_token); -- (void) release_spnego_ctx(ctx); -- } else { -- ret = gss_delete_sec_context(minor_status, -- context_handle, -- output_token); -- } -+ (void) gss_delete_sec_context(minor_status, &(*ctx)->ctx_handle, -+ output_token); -+ (void) release_spnego_ctx(ctx); - - return (ret); - } -@@ -2216,8 +2215,13 @@ spnego_gss_context_time( - OM_uint32 *time_rec) - { - OM_uint32 ret; -+ spnego_gss_ctx_id_t sc = (spnego_gss_ctx_id_t)context_handle; -+ -+ if (sc->ctx_handle == GSS_C_NO_CONTEXT) -+ return (GSS_S_NO_CONTEXT); -+ - ret = gss_context_time(minor_status, -- context_handle, -+ sc->ctx_handle, - time_rec); - return (ret); - } -@@ -2229,9 +2233,20 @@ spnego_gss_export_sec_context( - gss_buffer_t interprocess_token) - { - OM_uint32 ret; -+ spnego_gss_ctx_id_t sc = *(spnego_gss_ctx_id_t *)context_handle; -+ -+ /* We don't currently support exporting partially established -+ * contexts. */ -+ if (!sc->opened) -+ return GSS_S_UNAVAILABLE; -+ - ret = gss_export_sec_context(minor_status, -- context_handle, -+ &sc->ctx_handle, - interprocess_token); -+ if (sc->ctx_handle == GSS_C_NO_CONTEXT) { -+ release_spnego_ctx(&sc); -+ *context_handle = GSS_C_NO_CONTEXT; -+ } - return (ret); - } - -@@ -2241,11 +2256,12 @@ spnego_gss_import_sec_context( - const gss_buffer_t interprocess_token, - gss_ctx_id_t *context_handle) - { -- OM_uint32 ret; -- ret = gss_import_sec_context(minor_status, -- interprocess_token, -- context_handle); -- return (ret); -+ /* -+ * Until we implement partial context exports, there are no SPNEGO -+ * exported context tokens, only tokens for underlying mechs. So just -+ * return an error for now. -+ */ -+ return GSS_S_UNAVAILABLE; - } - #endif /* LEAN_CLIENT */ - -@@ -2262,16 +2278,48 @@ spnego_gss_inquire_context( - int *opened) - { - OM_uint32 ret = GSS_S_COMPLETE; -+ spnego_gss_ctx_id_t sc = (spnego_gss_ctx_id_t)context_handle; -+ -+ if (src_name != NULL) -+ *src_name = GSS_C_NO_NAME; -+ if (targ_name != NULL) -+ *targ_name = GSS_C_NO_NAME; -+ if (lifetime_rec != NULL) -+ *lifetime_rec = 0; -+ if (mech_type != NULL) -+ *mech_type = (gss_OID)gss_mech_spnego; -+ if (ctx_flags != NULL) -+ *ctx_flags = 0; -+ if (locally_initiated != NULL) -+ *locally_initiated = sc->initiate; -+ if (opened != NULL) -+ *opened = sc->opened; -+ -+ if (sc->ctx_handle != GSS_C_NO_CONTEXT) { -+ ret = gss_inquire_context(minor_status, sc->ctx_handle, -+ src_name, targ_name, lifetime_rec, -+ mech_type, ctx_flags, NULL, NULL); -+ } - -- ret = gss_inquire_context(minor_status, -- context_handle, -- src_name, -- targ_name, -- lifetime_rec, -- mech_type, -- ctx_flags, -- locally_initiated, -- opened); -+ if (!sc->opened) { -+ /* -+ * We are still doing SPNEGO negotiation, so report SPNEGO as -+ * the OID. After negotiation is complete we will report the -+ * underlying mechanism OID. -+ */ -+ if (mech_type != NULL) -+ *mech_type = (gss_OID)gss_mech_spnego; -+ -+ /* -+ * Remove flags we don't support with partially-established -+ * contexts. (Change this to keep GSS_C_TRANS_FLAG if we add -+ * support for exporting partial SPNEGO contexts.) -+ */ -+ if (ctx_flags != NULL) { -+ *ctx_flags &= ~GSS_C_PROT_READY_FLAG; -+ *ctx_flags &= ~GSS_C_TRANS_FLAG; -+ } -+ } - - return (ret); - } -@@ -2286,8 +2334,13 @@ spnego_gss_wrap_size_limit( - OM_uint32 *max_input_size) - { - OM_uint32 ret; -+ spnego_gss_ctx_id_t sc = (spnego_gss_ctx_id_t)context_handle; -+ -+ if (sc->ctx_handle == GSS_C_NO_CONTEXT) -+ return (GSS_S_NO_CONTEXT); -+ - ret = gss_wrap_size_limit(minor_status, -- context_handle, -+ sc->ctx_handle, - conf_req_flag, - qop_req, - req_output_size, -@@ -2304,8 +2357,13 @@ spnego_gss_get_mic( - gss_buffer_t message_token) - { - OM_uint32 ret; -+ spnego_gss_ctx_id_t sc = (spnego_gss_ctx_id_t)context_handle; -+ -+ if (sc->ctx_handle == GSS_C_NO_CONTEXT) -+ return (GSS_S_NO_CONTEXT); -+ - ret = gss_get_mic(minor_status, -- context_handle, -+ sc->ctx_handle, - qop_req, - message_buffer, - message_token); -@@ -2321,8 +2379,13 @@ spnego_gss_verify_mic( - gss_qop_t *qop_state) - { - OM_uint32 ret; -+ spnego_gss_ctx_id_t sc = (spnego_gss_ctx_id_t)context_handle; -+ -+ if (sc->ctx_handle == GSS_C_NO_CONTEXT) -+ return (GSS_S_NO_CONTEXT); -+ - ret = gss_verify_mic(minor_status, -- context_handle, -+ sc->ctx_handle, - msg_buffer, - token_buffer, - qop_state); -@@ -2337,8 +2400,14 @@ spnego_gss_inquire_sec_context_by_oid( - gss_buffer_set_t *data_set) - { - OM_uint32 ret; -+ spnego_gss_ctx_id_t sc = (spnego_gss_ctx_id_t)context_handle; -+ -+ /* There are no SPNEGO-specific OIDs for this function. */ -+ if (sc->ctx_handle == GSS_C_NO_CONTEXT) -+ return (GSS_S_UNAVAILABLE); -+ - ret = gss_inquire_sec_context_by_oid(minor_status, -- context_handle, -+ sc->ctx_handle, - desired_object, - data_set); - return (ret); -@@ -2407,8 +2476,15 @@ spnego_gss_set_sec_context_option( - const gss_buffer_t value) - { - OM_uint32 ret; -+ spnego_gss_ctx_id_t sc = (spnego_gss_ctx_id_t)*context_handle; -+ -+ /* There are no SPNEGO-specific OIDs for this function, and we cannot -+ * construct an empty SPNEGO context with it. */ -+ if (sc == NULL || sc->ctx_handle == GSS_C_NO_CONTEXT) -+ return (GSS_S_UNAVAILABLE); -+ - ret = gss_set_sec_context_option(minor_status, -- context_handle, -+ &sc->ctx_handle, - desired_object, - value); - return (ret); -@@ -2425,8 +2501,13 @@ spnego_gss_wrap_aead(OM_uint32 *minor_status, - gss_buffer_t output_message_buffer) - { - OM_uint32 ret; -+ spnego_gss_ctx_id_t sc = (spnego_gss_ctx_id_t)context_handle; -+ -+ if (sc->ctx_handle == GSS_C_NO_CONTEXT) -+ return (GSS_S_NO_CONTEXT); -+ - ret = gss_wrap_aead(minor_status, -- context_handle, -+ sc->ctx_handle, - conf_req_flag, - qop_req, - input_assoc_buffer, -@@ -2447,8 +2528,13 @@ spnego_gss_unwrap_aead(OM_uint32 *minor_status, - gss_qop_t *qop_state) - { - OM_uint32 ret; -+ spnego_gss_ctx_id_t sc = (spnego_gss_ctx_id_t)context_handle; -+ -+ if (sc->ctx_handle == GSS_C_NO_CONTEXT) -+ return (GSS_S_NO_CONTEXT); -+ - ret = gss_unwrap_aead(minor_status, -- context_handle, -+ sc->ctx_handle, - input_message_buffer, - input_assoc_buffer, - output_payload_buffer, -@@ -2467,8 +2553,13 @@ spnego_gss_wrap_iov(OM_uint32 *minor_status, - int iov_count) - { - OM_uint32 ret; -+ spnego_gss_ctx_id_t sc = (spnego_gss_ctx_id_t)context_handle; -+ -+ if (sc->ctx_handle == GSS_C_NO_CONTEXT) -+ return (GSS_S_NO_CONTEXT); -+ - ret = gss_wrap_iov(minor_status, -- context_handle, -+ sc->ctx_handle, - conf_req_flag, - qop_req, - conf_state, -@@ -2486,8 +2577,13 @@ spnego_gss_unwrap_iov(OM_uint32 *minor_status, - int iov_count) - { - OM_uint32 ret; -+ spnego_gss_ctx_id_t sc = (spnego_gss_ctx_id_t)context_handle; -+ -+ if (sc->ctx_handle == GSS_C_NO_CONTEXT) -+ return (GSS_S_NO_CONTEXT); -+ - ret = gss_unwrap_iov(minor_status, -- context_handle, -+ sc->ctx_handle, - conf_state, - qop_state, - iov, -@@ -2505,8 +2601,13 @@ spnego_gss_wrap_iov_length(OM_uint32 *minor_status, - int iov_count) - { - OM_uint32 ret; -+ spnego_gss_ctx_id_t sc = (spnego_gss_ctx_id_t)context_handle; -+ -+ if (sc->ctx_handle == GSS_C_NO_CONTEXT) -+ return (GSS_S_NO_CONTEXT); -+ - ret = gss_wrap_iov_length(minor_status, -- context_handle, -+ sc->ctx_handle, - conf_req_flag, - qop_req, - conf_state, -@@ -2523,8 +2624,13 @@ spnego_gss_complete_auth_token( - gss_buffer_t input_message_buffer) - { - OM_uint32 ret; -+ spnego_gss_ctx_id_t sc = (spnego_gss_ctx_id_t)context_handle; -+ -+ if (sc->ctx_handle == GSS_C_NO_CONTEXT) -+ return (GSS_S_UNAVAILABLE); -+ - ret = gss_complete_auth_token(minor_status, -- context_handle, -+ sc->ctx_handle, - input_message_buffer); - return (ret); - } -@@ -2776,8 +2882,13 @@ spnego_gss_pseudo_random(OM_uint32 *minor_status, - gss_buffer_t prf_out) - { - OM_uint32 ret; -+ spnego_gss_ctx_id_t sc = (spnego_gss_ctx_id_t)context; -+ -+ if (sc->ctx_handle == GSS_C_NO_CONTEXT) -+ return (GSS_S_NO_CONTEXT); -+ - ret = gss_pseudo_random(minor_status, -- context, -+ sc->ctx_handle, - prf_key, - prf_in, - desired_output_len, -@@ -2918,7 +3029,12 @@ spnego_gss_get_mic_iov(OM_uint32 *minor_status, gss_ctx_id_t context_handle, - gss_qop_t qop_req, gss_iov_buffer_desc *iov, - int iov_count) - { -- return gss_get_mic_iov(minor_status, context_handle, qop_req, iov, -+ spnego_gss_ctx_id_t sc = (spnego_gss_ctx_id_t)context_handle; -+ -+ if (sc->ctx_handle == GSS_C_NO_CONTEXT) -+ return (GSS_S_NO_CONTEXT); -+ -+ return gss_get_mic_iov(minor_status, sc->ctx_handle, qop_req, iov, - iov_count); - } - -@@ -2927,7 +3043,12 @@ spnego_gss_verify_mic_iov(OM_uint32 *minor_status, gss_ctx_id_t context_handle, - gss_qop_t *qop_state, gss_iov_buffer_desc *iov, - int iov_count) - { -- return gss_verify_mic_iov(minor_status, context_handle, qop_state, iov, -+ spnego_gss_ctx_id_t sc = (spnego_gss_ctx_id_t)context_handle; -+ -+ if (sc->ctx_handle == GSS_C_NO_CONTEXT) -+ return (GSS_S_NO_CONTEXT); -+ -+ return gss_verify_mic_iov(minor_status, sc->ctx_handle, qop_state, iov, - iov_count); - } - -@@ -2936,7 +3057,12 @@ spnego_gss_get_mic_iov_length(OM_uint32 *minor_status, - gss_ctx_id_t context_handle, gss_qop_t qop_req, - gss_iov_buffer_desc *iov, int iov_count) - { -- return gss_get_mic_iov_length(minor_status, context_handle, qop_req, iov, -+ spnego_gss_ctx_id_t sc = (spnego_gss_ctx_id_t)context_handle; -+ -+ if (sc->ctx_handle == GSS_C_NO_CONTEXT) -+ return (GSS_S_NO_CONTEXT); -+ -+ return gss_get_mic_iov_length(minor_status, sc->ctx_handle, qop_req, iov, - iov_count); - } - diff --git a/gnu/packages/patches/mit-krb5-CVE-2015-2695-pt2.patch b/gnu/packages/patches/mit-krb5-CVE-2015-2695-pt2.patch deleted file mode 100644 index aa9fcfa0dd..0000000000 --- a/gnu/packages/patches/mit-krb5-CVE-2015-2695-pt2.patch +++ /dev/null @@ -1,65 +0,0 @@ -Copied from Debian. - -From 18c512ebdcc5cacc777e9dbcc6817f83c301ad93 Mon Sep 17 00:00:00 2001 -From: Greg Hudson <ghudson@mit.edu> -Date: Wed, 4 Nov 2015 21:29:10 -0500 -Subject: Fix SPNEGO context import - -The patches for CVE-2015-2695 did not implement a SPNEGO -gss_import_sec_context() function, under the erroneous belief than an -exported SPNEGO context would be tagged with the underlying context -mechanism. Implement it now to allow SPNEGO contexts to be -successfully exported and imported after establishment. - -ticket: 8273 -(cherry picked from commit fbb565f913c52eba9bea82f1694aba7a8c90e93d) - -Patch-Category: upstream ---- - src/lib/gssapi/spnego/spnego_mech.c | 33 +++++++++++++++++++++++++++------ - 1 file changed, 27 insertions(+), 6 deletions(-) - -diff --git a/src/lib/gssapi/spnego/spnego_mech.c b/src/lib/gssapi/spnego/spnego_mech.c -index a1072b0..02284a1 100644 ---- a/src/lib/gssapi/spnego/spnego_mech.c -+++ b/src/lib/gssapi/spnego/spnego_mech.c -@@ -2256,12 +2256,33 @@ spnego_gss_import_sec_context( - const gss_buffer_t interprocess_token, - gss_ctx_id_t *context_handle) - { -- /* -- * Until we implement partial context exports, there are no SPNEGO -- * exported context tokens, only tokens for underlying mechs. So just -- * return an error for now. -- */ -- return GSS_S_UNAVAILABLE; -+ OM_uint32 ret, tmpmin; -+ gss_ctx_id_t mctx; -+ spnego_gss_ctx_id_t sc; -+ int initiate, opened; -+ -+ ret = gss_import_sec_context(minor_status, interprocess_token, &mctx); -+ if (ret != GSS_S_COMPLETE) -+ return ret; -+ -+ ret = gss_inquire_context(&tmpmin, mctx, NULL, NULL, NULL, NULL, NULL, -+ &initiate, &opened); -+ if (ret != GSS_S_COMPLETE || !opened) { -+ /* We don't currently support importing partially established -+ * contexts. */ -+ (void) gss_delete_sec_context(&tmpmin, &mctx, GSS_C_NO_BUFFER); -+ return GSS_S_FAILURE; -+ } -+ -+ sc = create_spnego_ctx(initiate); -+ if (sc == NULL) { -+ (void) gss_delete_sec_context(&tmpmin, &mctx, GSS_C_NO_BUFFER); -+ return GSS_S_FAILURE; -+ } -+ sc->ctx_handle = mctx; -+ sc->opened = 1; -+ *context_handle = (gss_ctx_id_t)sc; -+ return GSS_S_COMPLETE; - } - #endif /* LEAN_CLIENT */ - diff --git a/gnu/packages/patches/mit-krb5-CVE-2015-2696.patch b/gnu/packages/patches/mit-krb5-CVE-2015-2696.patch deleted file mode 100644 index 7b4b1d71ab..0000000000 --- a/gnu/packages/patches/mit-krb5-CVE-2015-2696.patch +++ /dev/null @@ -1,736 +0,0 @@ -Copied from Debian. - -From ebea85358bc72ec20c53130d83acb93f95853b76 Mon Sep 17 00:00:00 2001 -From: Nicolas Williams <nico@twosigma.com> -Date: Mon, 14 Sep 2015 12:28:36 -0400 -Subject: Fix IAKERB context aliasing bugs [CVE-2015-2696] - -The IAKERB mechanism currently replaces its context handle with the -krb5 mechanism handle upon establishment, under the assumption that -most GSS functions are only called after context establishment. This -assumption is incorrect, and can lead to aliasing violations for some -programs. Maintain the IAKERB context structure after context -establishment and add new IAKERB entry points to refer to it with that -type. Add initiate and established flags to the IAKERB context -structure for use in gss_inquire_context() prior to context -establishment. - -CVE-2015-2696: - -In MIT krb5 1.9 and later, applications which call -gss_inquire_context() on a partially-established IAKERB context can -cause the GSS-API library to read from a pointer using the wrong type, -generally causing a process crash. Java server applications using the -native JGSS provider are vulnerable to this bug. A carefully crafted -IAKERB packet might allow the gss_inquire_context() call to succeed -with attacker-determined results, but applications should not make -access control decisions based on gss_inquire_context() results prior -to context establishment. - - CVSSv2 Vector: AV:N/AC:M/Au:N/C:N/I:N/A:C/E:POC/RL:OF/RC:C - -[ghudson@mit.edu: several bugfixes, style changes, and edge-case -behavior changes; commit message and CVE description] - -ticket: 8244 -target_version: 1.14 -tags: pullup - -(cherry picked from commit e04f0283516e80d2f93366e0d479d13c9b5c8c2a) -Patch-Category: upstream ---- - src/lib/gssapi/krb5/gssapiP_krb5.h | 114 ++++++++++++ - src/lib/gssapi/krb5/gssapi_krb5.c | 105 +++++++++-- - src/lib/gssapi/krb5/iakerb.c | 351 +++++++++++++++++++++++++++++++++---- - 3 files changed, 529 insertions(+), 41 deletions(-) - -diff --git a/src/lib/gssapi/krb5/gssapiP_krb5.h b/src/lib/gssapi/krb5/gssapiP_krb5.h -index a0e8625..05dc321 100644 ---- a/src/lib/gssapi/krb5/gssapiP_krb5.h -+++ b/src/lib/gssapi/krb5/gssapiP_krb5.h -@@ -620,6 +620,21 @@ OM_uint32 KRB5_CALLCONV krb5_gss_accept_sec_context_ext - ); - #endif /* LEAN_CLIENT */ - -+OM_uint32 KRB5_CALLCONV krb5_gss_inquire_sec_context_by_oid -+(OM_uint32*, /* minor_status */ -+ const gss_ctx_id_t, -+ /* context_handle */ -+ const gss_OID, /* desired_object */ -+ gss_buffer_set_t* /* data_set */ -+); -+ -+OM_uint32 KRB5_CALLCONV krb5_gss_set_sec_context_option -+(OM_uint32*, /* minor_status */ -+ gss_ctx_id_t*, /* context_handle */ -+ const gss_OID, /* desired_object */ -+ const gss_buffer_t/* value */ -+); -+ - OM_uint32 KRB5_CALLCONV krb5_gss_process_context_token - (OM_uint32*, /* minor_status */ - gss_ctx_id_t, /* context_handle */ -@@ -1301,6 +1316,105 @@ OM_uint32 KRB5_CALLCONV - krb5_gss_import_cred(OM_uint32 *minor_status, gss_buffer_t token, - gss_cred_id_t *cred_handle); - -+OM_uint32 KRB5_CALLCONV -+iakerb_gss_process_context_token(OM_uint32 *minor_status, -+ const gss_ctx_id_t context_handle, -+ const gss_buffer_t token_buffer); -+ -+OM_uint32 KRB5_CALLCONV -+iakerb_gss_context_time(OM_uint32 *minor_status, gss_ctx_id_t context_handle, -+ OM_uint32 *time_rec); -+ -+OM_uint32 KRB5_CALLCONV -+iakerb_gss_inquire_context(OM_uint32 *minor_status, -+ gss_ctx_id_t context_handle, gss_name_t *src_name, -+ gss_name_t *targ_name, OM_uint32 *lifetime_rec, -+ gss_OID *mech_type, OM_uint32 *ctx_flags, -+ int *locally_initiated, int *opened); -+ -+OM_uint32 KRB5_CALLCONV -+iakerb_gss_get_mic(OM_uint32 *minor_status, gss_ctx_id_t context_handle, -+ gss_qop_t qop_req, gss_buffer_t message_buffer, -+ gss_buffer_t message_token); -+ -+OM_uint32 KRB5_CALLCONV -+iakerb_gss_get_mic_iov(OM_uint32 *minor_status, gss_ctx_id_t context_handle, -+ gss_qop_t qop_req, gss_iov_buffer_desc *iov, -+ int iov_count); -+ -+OM_uint32 KRB5_CALLCONV -+iakerb_gss_get_mic_iov_length(OM_uint32 *minor_status, -+ gss_ctx_id_t context_handle, gss_qop_t qop_req, -+ gss_iov_buffer_desc *iov, int iov_count); -+ -+OM_uint32 KRB5_CALLCONV -+iakerb_gss_verify_mic(OM_uint32 *minor_status, gss_ctx_id_t context_handle, -+ gss_buffer_t msg_buffer, gss_buffer_t token_buffer, -+ gss_qop_t *qop_state); -+ -+OM_uint32 KRB5_CALLCONV -+iakerb_gss_verify_mic_iov(OM_uint32 *minor_status, gss_ctx_id_t context_handle, -+ gss_qop_t *qop_state, gss_iov_buffer_desc *iov, -+ int iov_count); -+ -+OM_uint32 KRB5_CALLCONV -+iakerb_gss_wrap(OM_uint32 *minor_status, gss_ctx_id_t context_handle, -+ int conf_req_flag, gss_qop_t qop_req, -+ gss_buffer_t input_message_buffer, int *conf_state, -+ gss_buffer_t output_message_buffer); -+ -+OM_uint32 KRB5_CALLCONV -+iakerb_gss_wrap_iov(OM_uint32 *minor_status, gss_ctx_id_t context_handle, -+ int conf_req_flag, gss_qop_t qop_req, int *conf_state, -+ gss_iov_buffer_desc *iov, int iov_count); -+ -+OM_uint32 KRB5_CALLCONV -+iakerb_gss_wrap_iov_length(OM_uint32 *minor_status, -+ gss_ctx_id_t context_handle, int conf_req_flag, -+ gss_qop_t qop_req, int *conf_state, -+ gss_iov_buffer_desc *iov, int iov_count); -+ -+OM_uint32 KRB5_CALLCONV -+iakerb_gss_unwrap(OM_uint32 *minor_status, gss_ctx_id_t context_handle, -+ gss_buffer_t input_message_buffer, -+ gss_buffer_t output_message_buffer, int *conf_state, -+ gss_qop_t *qop_state); -+ -+OM_uint32 KRB5_CALLCONV -+iakerb_gss_unwrap_iov(OM_uint32 *minor_status, gss_ctx_id_t context_handle, -+ int *conf_state, gss_qop_t *qop_state, -+ gss_iov_buffer_desc *iov, int iov_count); -+ -+OM_uint32 KRB5_CALLCONV -+iakerb_gss_wrap_size_limit(OM_uint32 *minor_status, -+ gss_ctx_id_t context_handle, int conf_req_flag, -+ gss_qop_t qop_req, OM_uint32 req_output_size, -+ OM_uint32 *max_input_size); -+ -+#ifndef LEAN_CLIENT -+OM_uint32 KRB5_CALLCONV -+iakerb_gss_export_sec_context(OM_uint32 *minor_status, -+ gss_ctx_id_t *context_handle, -+ gss_buffer_t interprocess_token); -+#endif /* LEAN_CLIENT */ -+ -+OM_uint32 KRB5_CALLCONV -+iakerb_gss_inquire_sec_context_by_oid(OM_uint32 *minor_status, -+ const gss_ctx_id_t context_handle, -+ const gss_OID desired_object, -+ gss_buffer_set_t *data_set); -+ -+OM_uint32 KRB5_CALLCONV -+iakerb_gss_set_sec_context_option(OM_uint32 *minor_status, -+ gss_ctx_id_t *context_handle, -+ const gss_OID desired_object, -+ const gss_buffer_t value); -+ -+OM_uint32 KRB5_CALLCONV -+iakerb_gss_pseudo_random(OM_uint32 *minor_status, gss_ctx_id_t context_handle, -+ int prf_key, const gss_buffer_t prf_in, -+ ssize_t desired_output_len, gss_buffer_t prf_out); -+ - /* Magic string to identify exported krb5 GSS credentials. Increment this if - * the format changes. */ - #define CRED_EXPORT_MAGIC "K5C1" -diff --git a/src/lib/gssapi/krb5/gssapi_krb5.c b/src/lib/gssapi/krb5/gssapi_krb5.c -index 77b7fff..9a23656 100644 ---- a/src/lib/gssapi/krb5/gssapi_krb5.c -+++ b/src/lib/gssapi/krb5/gssapi_krb5.c -@@ -345,7 +345,7 @@ static struct { - } - }; - --static OM_uint32 KRB5_CALLCONV -+OM_uint32 KRB5_CALLCONV - krb5_gss_inquire_sec_context_by_oid (OM_uint32 *minor_status, - const gss_ctx_id_t context_handle, - const gss_OID desired_object, -@@ -459,7 +459,7 @@ static struct { - }; - #endif - --static OM_uint32 KRB5_CALLCONV -+OM_uint32 KRB5_CALLCONV - krb5_gss_set_sec_context_option (OM_uint32 *minor_status, - gss_ctx_id_t *context_handle, - const gss_OID desired_object, -@@ -904,20 +904,103 @@ static struct gss_config krb5_mechanism = { - krb5_gss_get_mic_iov_length, - }; - -+/* Functions which use security contexts or acquire creds are IAKERB-specific; -+ * other functions can borrow from the krb5 mech. */ -+static struct gss_config iakerb_mechanism = { -+ { GSS_MECH_KRB5_OID_LENGTH, GSS_MECH_KRB5_OID }, -+ NULL, -+ iakerb_gss_acquire_cred, -+ krb5_gss_release_cred, -+ iakerb_gss_init_sec_context, -+#ifdef LEAN_CLIENT -+ NULL, -+#else -+ iakerb_gss_accept_sec_context, -+#endif -+ iakerb_gss_process_context_token, -+ iakerb_gss_delete_sec_context, -+ iakerb_gss_context_time, -+ iakerb_gss_get_mic, -+ iakerb_gss_verify_mic, -+#if defined(IOV_SHIM_EXERCISE_WRAP) || defined(IOV_SHIM_EXERCISE) -+ NULL, -+#else -+ iakerb_gss_wrap, -+#endif -+#if defined(IOV_SHIM_EXERCISE_UNWRAP) || defined(IOV_SHIM_EXERCISE) -+ NULL, -+#else -+ iakerb_gss_unwrap, -+#endif -+ krb5_gss_display_status, -+ krb5_gss_indicate_mechs, -+ krb5_gss_compare_name, -+ krb5_gss_display_name, -+ krb5_gss_import_name, -+ krb5_gss_release_name, -+ krb5_gss_inquire_cred, -+ NULL, /* add_cred */ -+#ifdef LEAN_CLIENT -+ NULL, -+ NULL, -+#else -+ iakerb_gss_export_sec_context, -+ NULL, -+#endif -+ krb5_gss_inquire_cred_by_mech, -+ krb5_gss_inquire_names_for_mech, -+ iakerb_gss_inquire_context, -+ krb5_gss_internal_release_oid, -+ iakerb_gss_wrap_size_limit, -+ krb5_gss_localname, -+ krb5_gss_authorize_localname, -+ krb5_gss_export_name, -+ krb5_gss_duplicate_name, -+ krb5_gss_store_cred, -+ iakerb_gss_inquire_sec_context_by_oid, -+ krb5_gss_inquire_cred_by_oid, -+ iakerb_gss_set_sec_context_option, -+ krb5_gssspi_set_cred_option, -+ krb5_gssspi_mech_invoke, -+ NULL, /* wrap_aead */ -+ NULL, /* unwrap_aead */ -+ iakerb_gss_wrap_iov, -+ iakerb_gss_unwrap_iov, -+ iakerb_gss_wrap_iov_length, -+ NULL, /* complete_auth_token */ -+ NULL, /* acquire_cred_impersonate_name */ -+ NULL, /* add_cred_impersonate_name */ -+ NULL, /* display_name_ext */ -+ krb5_gss_inquire_name, -+ krb5_gss_get_name_attribute, -+ krb5_gss_set_name_attribute, -+ krb5_gss_delete_name_attribute, -+ krb5_gss_export_name_composite, -+ krb5_gss_map_name_to_any, -+ krb5_gss_release_any_name_mapping, -+ iakerb_gss_pseudo_random, -+ NULL, /* set_neg_mechs */ -+ krb5_gss_inquire_saslname_for_mech, -+ krb5_gss_inquire_mech_for_saslname, -+ krb5_gss_inquire_attrs_for_mech, -+ krb5_gss_acquire_cred_from, -+ krb5_gss_store_cred_into, -+ iakerb_gss_acquire_cred_with_password, -+ krb5_gss_export_cred, -+ krb5_gss_import_cred, -+ NULL, /* import_sec_context_by_mech */ -+ NULL, /* import_name_by_mech */ -+ NULL, /* import_cred_by_mech */ -+ iakerb_gss_get_mic_iov, -+ iakerb_gss_verify_mic_iov, -+ iakerb_gss_get_mic_iov_length, -+}; -+ - #ifdef _GSS_STATIC_LINK - #include "mglueP.h" - static int gss_iakerbmechglue_init(void) - { - struct gss_mech_config mech_iakerb; -- struct gss_config iakerb_mechanism = krb5_mechanism; -- -- /* IAKERB mechanism mirrors krb5, but with different context SPIs */ -- iakerb_mechanism.gss_accept_sec_context = iakerb_gss_accept_sec_context; -- iakerb_mechanism.gss_init_sec_context = iakerb_gss_init_sec_context; -- iakerb_mechanism.gss_delete_sec_context = iakerb_gss_delete_sec_context; -- iakerb_mechanism.gss_acquire_cred = iakerb_gss_acquire_cred; -- iakerb_mechanism.gssspi_acquire_cred_with_password -- = iakerb_gss_acquire_cred_with_password; - - memset(&mech_iakerb, 0, sizeof(mech_iakerb)); - mech_iakerb.mech = &iakerb_mechanism; -diff --git a/src/lib/gssapi/krb5/iakerb.c b/src/lib/gssapi/krb5/iakerb.c -index f30de32..4662bd9 100644 ---- a/src/lib/gssapi/krb5/iakerb.c -+++ b/src/lib/gssapi/krb5/iakerb.c -@@ -47,6 +47,8 @@ struct _iakerb_ctx_id_rec { - gss_ctx_id_t gssc; - krb5_data conv; /* conversation for checksumming */ - unsigned int count; /* number of round trips */ -+ int initiate; -+ int established; - krb5_get_init_creds_opt *gic_opts; - }; - -@@ -695,7 +697,7 @@ cleanup: - * Allocate and initialise an IAKERB context - */ - static krb5_error_code --iakerb_alloc_context(iakerb_ctx_id_t *pctx) -+iakerb_alloc_context(iakerb_ctx_id_t *pctx, int initiate) - { - iakerb_ctx_id_t ctx; - krb5_error_code code; -@@ -709,6 +711,8 @@ iakerb_alloc_context(iakerb_ctx_id_t *pctx) - ctx->magic = KG_IAKERB_CONTEXT; - ctx->state = IAKERB_AS_REQ; - ctx->count = 0; -+ ctx->initiate = initiate; -+ ctx->established = 0; - - code = krb5_gss_init_context(&ctx->k5c); - if (code != 0) -@@ -732,7 +736,7 @@ iakerb_gss_delete_sec_context(OM_uint32 *minor_status, - gss_ctx_id_t *context_handle, - gss_buffer_t output_token) - { -- OM_uint32 major_status = GSS_S_COMPLETE; -+ iakerb_ctx_id_t iakerb_ctx = (iakerb_ctx_id_t)*context_handle; - - if (output_token != GSS_C_NO_BUFFER) { - output_token->length = 0; -@@ -740,23 +744,10 @@ iakerb_gss_delete_sec_context(OM_uint32 *minor_status, - } - - *minor_status = 0; -+ *context_handle = GSS_C_NO_CONTEXT; -+ iakerb_release_context(iakerb_ctx); - -- if (*context_handle != GSS_C_NO_CONTEXT) { -- iakerb_ctx_id_t iakerb_ctx = (iakerb_ctx_id_t)*context_handle; -- -- if (iakerb_ctx->magic == KG_IAKERB_CONTEXT) { -- iakerb_release_context(iakerb_ctx); -- *context_handle = GSS_C_NO_CONTEXT; -- } else { -- assert(iakerb_ctx->magic == KG_CONTEXT); -- -- major_status = krb5_gss_delete_sec_context(minor_status, -- context_handle, -- output_token); -- } -- } -- -- return major_status; -+ return GSS_S_COMPLETE; - } - - static krb5_boolean -@@ -802,7 +793,7 @@ iakerb_gss_accept_sec_context(OM_uint32 *minor_status, - int initialContextToken = (*context_handle == GSS_C_NO_CONTEXT); - - if (initialContextToken) { -- code = iakerb_alloc_context(&ctx); -+ code = iakerb_alloc_context(&ctx, 0); - if (code != 0) - goto cleanup; - -@@ -854,11 +845,8 @@ iakerb_gss_accept_sec_context(OM_uint32 *minor_status, - time_rec, - delegated_cred_handle, - &exts); -- if (major_status == GSS_S_COMPLETE) { -- *context_handle = ctx->gssc; -- ctx->gssc = NULL; -- iakerb_release_context(ctx); -- } -+ if (major_status == GSS_S_COMPLETE) -+ ctx->established = 1; - if (mech_type != NULL) - *mech_type = (gss_OID)gss_mech_krb5; - } -@@ -897,7 +885,7 @@ iakerb_gss_init_sec_context(OM_uint32 *minor_status, - int initialContextToken = (*context_handle == GSS_C_NO_CONTEXT); - - if (initialContextToken) { -- code = iakerb_alloc_context(&ctx); -+ code = iakerb_alloc_context(&ctx, 1); - if (code != 0) { - *minor_status = code; - goto cleanup; -@@ -983,11 +971,8 @@ iakerb_gss_init_sec_context(OM_uint32 *minor_status, - ret_flags, - time_rec, - &exts); -- if (major_status == GSS_S_COMPLETE) { -- *context_handle = ctx->gssc; -- ctx->gssc = GSS_C_NO_CONTEXT; -- iakerb_release_context(ctx); -- } -+ if (major_status == GSS_S_COMPLETE) -+ ctx->established = 1; - if (actual_mech_type != NULL) - *actual_mech_type = (gss_OID)gss_mech_krb5; - } else { -@@ -1010,3 +995,309 @@ cleanup: - - return major_status; - } -+ -+OM_uint32 KRB5_CALLCONV -+iakerb_gss_unwrap(OM_uint32 *minor_status, gss_ctx_id_t context_handle, -+ gss_buffer_t input_message_buffer, -+ gss_buffer_t output_message_buffer, int *conf_state, -+ gss_qop_t *qop_state) -+{ -+ iakerb_ctx_id_t ctx = (iakerb_ctx_id_t)context_handle; -+ -+ if (ctx->gssc == GSS_C_NO_CONTEXT) -+ return GSS_S_NO_CONTEXT; -+ -+ return krb5_gss_unwrap(minor_status, ctx->gssc, input_message_buffer, -+ output_message_buffer, conf_state, qop_state); -+} -+ -+OM_uint32 KRB5_CALLCONV -+iakerb_gss_wrap(OM_uint32 *minor_status, gss_ctx_id_t context_handle, -+ int conf_req_flag, gss_qop_t qop_req, -+ gss_buffer_t input_message_buffer, int *conf_state, -+ gss_buffer_t output_message_buffer) -+{ -+ iakerb_ctx_id_t ctx = (iakerb_ctx_id_t)context_handle; -+ -+ if (ctx->gssc == GSS_C_NO_CONTEXT) -+ return GSS_S_NO_CONTEXT; -+ -+ return krb5_gss_wrap(minor_status, ctx->gssc, conf_req_flag, qop_req, -+ input_message_buffer, conf_state, -+ output_message_buffer); -+} -+ -+OM_uint32 KRB5_CALLCONV -+iakerb_gss_process_context_token(OM_uint32 *minor_status, -+ const gss_ctx_id_t context_handle, -+ const gss_buffer_t token_buffer) -+{ -+ iakerb_ctx_id_t ctx = (iakerb_ctx_id_t)context_handle; -+ -+ if (ctx->gssc == GSS_C_NO_CONTEXT) -+ return GSS_S_DEFECTIVE_TOKEN; -+ -+ return krb5_gss_process_context_token(minor_status, ctx->gssc, -+ token_buffer); -+} -+ -+OM_uint32 KRB5_CALLCONV -+iakerb_gss_context_time(OM_uint32 *minor_status, gss_ctx_id_t context_handle, -+ OM_uint32 *time_rec) -+{ -+ iakerb_ctx_id_t ctx = (iakerb_ctx_id_t)context_handle; -+ -+ if (ctx->gssc == GSS_C_NO_CONTEXT) -+ return GSS_S_NO_CONTEXT; -+ -+ return krb5_gss_context_time(minor_status, ctx->gssc, time_rec); -+} -+ -+#ifndef LEAN_CLIENT -+ -+OM_uint32 KRB5_CALLCONV -+iakerb_gss_export_sec_context(OM_uint32 *minor_status, -+ gss_ctx_id_t *context_handle, -+ gss_buffer_t interprocess_token) -+{ -+ OM_uint32 maj; -+ iakerb_ctx_id_t ctx = (iakerb_ctx_id_t)context_handle; -+ -+ /* We don't currently support exporting partially established contexts. */ -+ if (!ctx->established) -+ return GSS_S_UNAVAILABLE; -+ -+ maj = krb5_gss_export_sec_context(minor_status, &ctx->gssc, -+ interprocess_token); -+ if (ctx->gssc == GSS_C_NO_CONTEXT) { -+ iakerb_release_context(ctx); -+ *context_handle = GSS_C_NO_CONTEXT; -+ } -+ return maj; -+} -+ -+/* -+ * Until we implement partial context exports, there are no SPNEGO exported -+ * context tokens, only tokens for the underlying krb5 context. So we do not -+ * need to implement an iakerb_gss_import_sec_context() yet; it would be -+ * unreachable except via a manually constructed token. -+ */ -+ -+#endif /* LEAN_CLIENT */ -+ -+OM_uint32 KRB5_CALLCONV -+iakerb_gss_inquire_context(OM_uint32 *minor_status, -+ gss_ctx_id_t context_handle, gss_name_t *src_name, -+ gss_name_t *targ_name, OM_uint32 *lifetime_rec, -+ gss_OID *mech_type, OM_uint32 *ctx_flags, -+ int *initiate, int *opened) -+{ -+ OM_uint32 ret; -+ iakerb_ctx_id_t ctx = (iakerb_ctx_id_t)context_handle; -+ -+ if (src_name != NULL) -+ *src_name = GSS_C_NO_NAME; -+ if (targ_name != NULL) -+ *targ_name = GSS_C_NO_NAME; -+ if (lifetime_rec != NULL) -+ *lifetime_rec = 0; -+ if (mech_type != NULL) -+ *mech_type = (gss_OID)gss_mech_iakerb; -+ if (ctx_flags != NULL) -+ *ctx_flags = 0; -+ if (initiate != NULL) -+ *initiate = ctx->initiate; -+ if (opened != NULL) -+ *opened = ctx->established; -+ -+ if (ctx->gssc == GSS_C_NO_CONTEXT) -+ return GSS_S_COMPLETE; -+ -+ ret = krb5_gss_inquire_context(minor_status, ctx->gssc, src_name, -+ targ_name, lifetime_rec, mech_type, -+ ctx_flags, initiate, opened); -+ -+ if (!ctx->established) { -+ /* Report IAKERB as the mech OID until the context is established. */ -+ if (mech_type != NULL) -+ *mech_type = (gss_OID)gss_mech_iakerb; -+ -+ /* We don't support exporting partially-established contexts. */ -+ if (ctx_flags != NULL) -+ *ctx_flags &= ~GSS_C_TRANS_FLAG; -+ } -+ -+ return ret; -+} -+ -+OM_uint32 KRB5_CALLCONV -+iakerb_gss_wrap_size_limit(OM_uint32 *minor_status, -+ gss_ctx_id_t context_handle, int conf_req_flag, -+ gss_qop_t qop_req, OM_uint32 req_output_size, -+ OM_uint32 *max_input_size) -+{ -+ iakerb_ctx_id_t ctx = (iakerb_ctx_id_t)context_handle; -+ -+ if (ctx->gssc == GSS_C_NO_CONTEXT) -+ return GSS_S_NO_CONTEXT; -+ -+ return krb5_gss_wrap_size_limit(minor_status, ctx->gssc, conf_req_flag, -+ qop_req, req_output_size, max_input_size); -+} -+ -+OM_uint32 KRB5_CALLCONV -+iakerb_gss_get_mic(OM_uint32 *minor_status, gss_ctx_id_t context_handle, -+ gss_qop_t qop_req, gss_buffer_t message_buffer, -+ gss_buffer_t message_token) -+{ -+ iakerb_ctx_id_t ctx = (iakerb_ctx_id_t)context_handle; -+ -+ if (ctx->gssc == GSS_C_NO_CONTEXT) -+ return GSS_S_NO_CONTEXT; -+ -+ return krb5_gss_get_mic(minor_status, ctx->gssc, qop_req, message_buffer, -+ message_token); -+} -+ -+OM_uint32 KRB5_CALLCONV -+iakerb_gss_verify_mic(OM_uint32 *minor_status, gss_ctx_id_t context_handle, -+ gss_buffer_t msg_buffer, gss_buffer_t token_buffer, -+ gss_qop_t *qop_state) -+{ -+ iakerb_ctx_id_t ctx = (iakerb_ctx_id_t)context_handle; -+ -+ if (ctx->gssc == GSS_C_NO_CONTEXT) -+ return GSS_S_NO_CONTEXT; -+ -+ return krb5_gss_verify_mic(minor_status, ctx->gssc, msg_buffer, -+ token_buffer, qop_state); -+} -+ -+OM_uint32 KRB5_CALLCONV -+iakerb_gss_inquire_sec_context_by_oid(OM_uint32 *minor_status, -+ const gss_ctx_id_t context_handle, -+ const gss_OID desired_object, -+ gss_buffer_set_t *data_set) -+{ -+ iakerb_ctx_id_t ctx = (iakerb_ctx_id_t)context_handle; -+ -+ if (ctx->gssc == GSS_C_NO_CONTEXT) -+ return GSS_S_UNAVAILABLE; -+ -+ return krb5_gss_inquire_sec_context_by_oid(minor_status, ctx->gssc, -+ desired_object, data_set); -+} -+ -+OM_uint32 KRB5_CALLCONV -+iakerb_gss_set_sec_context_option(OM_uint32 *minor_status, -+ gss_ctx_id_t *context_handle, -+ const gss_OID desired_object, -+ const gss_buffer_t value) -+{ -+ iakerb_ctx_id_t ctx = (iakerb_ctx_id_t)*context_handle; -+ -+ if (ctx == NULL || ctx->gssc == GSS_C_NO_CONTEXT) -+ return GSS_S_UNAVAILABLE; -+ -+ return krb5_gss_set_sec_context_option(minor_status, &ctx->gssc, -+ desired_object, value); -+} -+ -+OM_uint32 KRB5_CALLCONV -+iakerb_gss_wrap_iov(OM_uint32 *minor_status, gss_ctx_id_t context_handle, -+ int conf_req_flag, gss_qop_t qop_req, int *conf_state, -+ gss_iov_buffer_desc *iov, int iov_count) -+{ -+ iakerb_ctx_id_t ctx = (iakerb_ctx_id_t)context_handle; -+ -+ if (ctx->gssc == GSS_C_NO_CONTEXT) -+ return GSS_S_NO_CONTEXT; -+ -+ return krb5_gss_wrap_iov(minor_status, ctx->gssc, conf_req_flag, qop_req, -+ conf_state, iov, iov_count); -+} -+ -+OM_uint32 KRB5_CALLCONV -+iakerb_gss_unwrap_iov(OM_uint32 *minor_status, gss_ctx_id_t context_handle, -+ int *conf_state, gss_qop_t *qop_state, -+ gss_iov_buffer_desc *iov, int iov_count) -+{ -+ iakerb_ctx_id_t ctx = (iakerb_ctx_id_t)context_handle; -+ -+ if (ctx->gssc == GSS_C_NO_CONTEXT) -+ return GSS_S_NO_CONTEXT; -+ -+ return krb5_gss_unwrap_iov(minor_status, ctx->gssc, conf_state, qop_state, -+ iov, iov_count); -+} -+ -+OM_uint32 KRB5_CALLCONV -+iakerb_gss_wrap_iov_length(OM_uint32 *minor_status, -+ gss_ctx_id_t context_handle, int conf_req_flag, -+ gss_qop_t qop_req, int *conf_state, -+ gss_iov_buffer_desc *iov, int iov_count) -+{ -+ iakerb_ctx_id_t ctx = (iakerb_ctx_id_t)context_handle; -+ -+ if (ctx->gssc == GSS_C_NO_CONTEXT) -+ return GSS_S_NO_CONTEXT; -+ -+ return krb5_gss_wrap_iov_length(minor_status, ctx->gssc, conf_req_flag, -+ qop_req, conf_state, iov, iov_count); -+} -+ -+OM_uint32 KRB5_CALLCONV -+iakerb_gss_pseudo_random(OM_uint32 *minor_status, gss_ctx_id_t context_handle, -+ int prf_key, const gss_buffer_t prf_in, -+ ssize_t desired_output_len, gss_buffer_t prf_out) -+{ -+ iakerb_ctx_id_t ctx = (iakerb_ctx_id_t)context_handle; -+ -+ if (ctx->gssc == GSS_C_NO_CONTEXT) -+ return GSS_S_NO_CONTEXT; -+ -+ return krb5_gss_pseudo_random(minor_status, ctx->gssc, prf_key, prf_in, -+ desired_output_len, prf_out); -+} -+ -+OM_uint32 KRB5_CALLCONV -+iakerb_gss_get_mic_iov(OM_uint32 *minor_status, gss_ctx_id_t context_handle, -+ gss_qop_t qop_req, gss_iov_buffer_desc *iov, -+ int iov_count) -+{ -+ iakerb_ctx_id_t ctx = (iakerb_ctx_id_t)context_handle; -+ -+ if (ctx->gssc == GSS_C_NO_CONTEXT) -+ return GSS_S_NO_CONTEXT; -+ -+ return krb5_gss_get_mic_iov(minor_status, ctx->gssc, qop_req, iov, -+ iov_count); -+} -+ -+OM_uint32 KRB5_CALLCONV -+iakerb_gss_verify_mic_iov(OM_uint32 *minor_status, gss_ctx_id_t context_handle, -+ gss_qop_t *qop_state, gss_iov_buffer_desc *iov, -+ int iov_count) -+{ -+ iakerb_ctx_id_t ctx = (iakerb_ctx_id_t)context_handle; -+ -+ if (ctx->gssc == GSS_C_NO_CONTEXT) -+ return GSS_S_NO_CONTEXT; -+ -+ return krb5_gss_verify_mic_iov(minor_status, ctx->gssc, qop_state, iov, -+ iov_count); -+} -+ -+OM_uint32 KRB5_CALLCONV -+iakerb_gss_get_mic_iov_length(OM_uint32 *minor_status, -+ gss_ctx_id_t context_handle, gss_qop_t qop_req, -+ gss_iov_buffer_desc *iov, int iov_count) -+{ -+ iakerb_ctx_id_t ctx = (iakerb_ctx_id_t)context_handle; -+ -+ if (ctx->gssc == GSS_C_NO_CONTEXT) -+ return GSS_S_NO_CONTEXT; -+ -+ return krb5_gss_get_mic_iov_length(minor_status, ctx->gssc, qop_req, iov, -+ iov_count); -+} diff --git a/gnu/packages/patches/mit-krb5-CVE-2015-2697.patch b/gnu/packages/patches/mit-krb5-CVE-2015-2697.patch deleted file mode 100644 index f65ce39623..0000000000 --- a/gnu/packages/patches/mit-krb5-CVE-2015-2697.patch +++ /dev/null @@ -1,55 +0,0 @@ -Copied from Debian. - -From fcafb522a0509bfd6f4f6b57e4a1e93c0092eeb0 Mon Sep 17 00:00:00 2001 -From: Greg Hudson <ghudson@mit.edu> -Date: Fri, 25 Sep 2015 12:51:47 -0400 -Subject: Fix build_principal memory bug [CVE-2015-2697] - -In build_principal_va(), use k5memdup0() instead of strdup() to make a -copy of the realm, to ensure that we allocate the correct number of -bytes and do not read past the end of the input string. This bug -affects krb5_build_principal(), krb5_build_principal_va(), and -krb5_build_principal_alloc_va(). krb5_build_principal_ext() is not -affected. - -CVE-2015-2697: - -In MIT krb5 1.7 and later, an authenticated attacker may be able to -cause a KDC to crash using a TGS request with a large realm field -beginning with a null byte. If the KDC attempts to find a referral to -answer the request, it constructs a principal name for lookup using -krb5_build_principal() with the requested realm. Due to a bug in this -function, the null byte causes only one byte be allocated for the -realm field of the constructed principal, far less than its length. -Subsequent operations on the lookup principal may cause a read beyond -the end of the mapped memory region, causing the KDC process to crash. - -CVSSv2: AV:N/AC:L/Au:S/C:N/I:N/A:C/E:POC/RL:OF/RC:C - -ticket: 8252 (new) -target_version: 1.14 -tags: pullup - -(cherry picked from commit f0c094a1b745d91ef2f9a4eae2149aac026a5789) -Patch-Category: upstream ---- - src/lib/krb5/krb/bld_princ.c | 6 ++---- - 1 file changed, 2 insertions(+), 4 deletions(-) - -diff --git a/src/lib/krb5/krb/bld_princ.c b/src/lib/krb5/krb/bld_princ.c -index ab6fed8..8604268 100644 ---- a/src/lib/krb5/krb/bld_princ.c -+++ b/src/lib/krb5/krb/bld_princ.c -@@ -40,10 +40,8 @@ build_principal_va(krb5_context context, krb5_principal princ, - data = malloc(size * sizeof(krb5_data)); - if (!data) { retval = ENOMEM; } - -- if (!retval) { -- r = strdup(realm); -- if (!r) { retval = ENOMEM; } -- } -+ if (!retval) -+ r = k5memdup0(realm, rlen, &retval); - - while (!retval && (component = va_arg(ap, char *))) { - if (count == size) { diff --git a/gnu/packages/patches/mit-krb5-CVE-2015-2698-pt1.patch b/gnu/packages/patches/mit-krb5-CVE-2015-2698-pt1.patch deleted file mode 100644 index 67545e4c16..0000000000 --- a/gnu/packages/patches/mit-krb5-CVE-2015-2698-pt1.patch +++ /dev/null @@ -1,43 +0,0 @@ -Copied from Debian. - -From 1a8bdc6d81dcd7dd8a4d42e8de6d2cacf1dd4408 Mon Sep 17 00:00:00 2001 -From: Greg Hudson <ghudson@mit.edu> -Date: Tue, 27 Oct 2015 00:44:24 -0400 -Subject: Fix two IAKERB comments - -The comment explaining why there is no iakerb_gss_import_sec_context() -erroneously referenced SPNEGO instead of IAKERB (noticed by Ben -Kaduk). The comment above iakerb_gss_delete_sec_context() is out of -date after the last commit. - -(cherry picked from commit 92d6dd045dfc06cc03d20b327a6ee7a71e6bc24d) - -Patch-Category: upstream ---- - src/lib/gssapi/krb5/iakerb.c | 6 +----- - 1 file changed, 1 insertion(+), 5 deletions(-) - -diff --git a/src/lib/gssapi/krb5/iakerb.c b/src/lib/gssapi/krb5/iakerb.c -index 4662bd9..e25862d 100644 ---- a/src/lib/gssapi/krb5/iakerb.c -+++ b/src/lib/gssapi/krb5/iakerb.c -@@ -727,10 +727,6 @@ cleanup: - return code; - } - --/* -- * Delete an IAKERB context. This can also accept Kerberos context -- * handles. The heuristic is similar to SPNEGO's delete_sec_context. -- */ - OM_uint32 KRB5_CALLCONV - iakerb_gss_delete_sec_context(OM_uint32 *minor_status, - gss_ctx_id_t *context_handle, -@@ -1077,7 +1073,7 @@ iakerb_gss_export_sec_context(OM_uint32 *minor_status, - } - - /* -- * Until we implement partial context exports, there are no SPNEGO exported -+ * Until we implement partial context exports, there are no IAKERB exported - * context tokens, only tokens for the underlying krb5 context. So we do not - * need to implement an iakerb_gss_import_sec_context() yet; it would be - * unreachable except via a manually constructed token. diff --git a/gnu/packages/patches/mit-krb5-CVE-2015-2698-pt2.patch b/gnu/packages/patches/mit-krb5-CVE-2015-2698-pt2.patch deleted file mode 100644 index 8725cd4eed..0000000000 --- a/gnu/packages/patches/mit-krb5-CVE-2015-2698-pt2.patch +++ /dev/null @@ -1,132 +0,0 @@ -Copied from Debian. - -From 4b330d5be1f8048be4d079ac3cb38d60c0e99e69 Mon Sep 17 00:00:00 2001 -From: Greg Hudson <ghudson@mit.edu> -Date: Wed, 4 Nov 2015 21:28:28 -0500 -Subject: Fix IAKERB context export/import [CVE-2015-2698] - -The patches for CVE-2015-2696 contained a regression in the newly -added IAKERB iakerb_gss_export_sec_context() function, which could -cause it to corrupt memory. Fix the regression by properly -dereferencing the context_handle pointer before casting it. - -Also, the patches did not implement an IAKERB gss_import_sec_context() -function, under the erroneous belief than an exported IAKERB context -would be tagged as a krb5 context. Implement it now to allow IAKERB -contexts to be successfully exported and imported after establishment. - -CVE-2015-2698: - -In any MIT krb5 release with the patches for CVE-2015-2696 applied, an -application which calls gss_export_sec_context() may experience memory -corruption if the context was established using the IAKERB mechanism. -Historically, some vulnerabilities of this nature can be translated -into remote code execution, though the necessary exploits must be -tailored to the individual application and are usually quite -complicated. - - CVSSv2 Vector: AV:N/AC:H/Au:S/C:C/I:C/A:C/E:POC/RL:OF/RC:C - -ticket: 8273 (new) -target_version: 1.14 -tags: pullup - -(cherry picked from commit d8b31c874c7d1039be7649362ef11c89f4e14c27) - -Patch-Category: upstream ---- - src/lib/gssapi/krb5/gssapiP_krb5.h | 5 +++++ - src/lib/gssapi/krb5/gssapi_krb5.c | 2 +- - src/lib/gssapi/krb5/iakerb.c | 42 +++++++++++++++++++++++++++++++------- - 3 files changed, 41 insertions(+), 8 deletions(-) - -diff --git a/src/lib/gssapi/krb5/gssapiP_krb5.h b/src/lib/gssapi/krb5/gssapiP_krb5.h -index 05dc321..ac53662 100644 ---- a/src/lib/gssapi/krb5/gssapiP_krb5.h -+++ b/src/lib/gssapi/krb5/gssapiP_krb5.h -@@ -1396,6 +1396,11 @@ OM_uint32 KRB5_CALLCONV - iakerb_gss_export_sec_context(OM_uint32 *minor_status, - gss_ctx_id_t *context_handle, - gss_buffer_t interprocess_token); -+ -+OM_uint32 KRB5_CALLCONV -+iakerb_gss_import_sec_context(OM_uint32 *minor_status, -+ const gss_buffer_t interprocess_token, -+ gss_ctx_id_t *context_handle); - #endif /* LEAN_CLIENT */ - - OM_uint32 KRB5_CALLCONV -diff --git a/src/lib/gssapi/krb5/gssapi_krb5.c b/src/lib/gssapi/krb5/gssapi_krb5.c -index 9a23656..d7ba279 100644 ---- a/src/lib/gssapi/krb5/gssapi_krb5.c -+++ b/src/lib/gssapi/krb5/gssapi_krb5.c -@@ -945,7 +945,7 @@ static struct gss_config iakerb_mechanism = { - NULL, - #else - iakerb_gss_export_sec_context, -- NULL, -+ iakerb_gss_import_sec_context, - #endif - krb5_gss_inquire_cred_by_mech, - krb5_gss_inquire_names_for_mech, -diff --git a/src/lib/gssapi/krb5/iakerb.c b/src/lib/gssapi/krb5/iakerb.c -index e25862d..32a341e 100644 ---- a/src/lib/gssapi/krb5/iakerb.c -+++ b/src/lib/gssapi/krb5/iakerb.c -@@ -1057,7 +1057,7 @@ iakerb_gss_export_sec_context(OM_uint32 *minor_status, - gss_buffer_t interprocess_token) - { - OM_uint32 maj; -- iakerb_ctx_id_t ctx = (iakerb_ctx_id_t)context_handle; -+ iakerb_ctx_id_t ctx = (iakerb_ctx_id_t)*context_handle; - - /* We don't currently support exporting partially established contexts. */ - if (!ctx->established) -@@ -1072,13 +1072,41 @@ iakerb_gss_export_sec_context(OM_uint32 *minor_status, - return maj; - } - --/* -- * Until we implement partial context exports, there are no IAKERB exported -- * context tokens, only tokens for the underlying krb5 context. So we do not -- * need to implement an iakerb_gss_import_sec_context() yet; it would be -- * unreachable except via a manually constructed token. -- */ -+OM_uint32 KRB5_CALLCONV -+iakerb_gss_import_sec_context(OM_uint32 *minor_status, -+ gss_buffer_t interprocess_token, -+ gss_ctx_id_t *context_handle) -+{ -+ OM_uint32 maj, tmpmin; -+ krb5_error_code code; -+ gss_ctx_id_t gssc; -+ krb5_gss_ctx_id_t kctx; -+ iakerb_ctx_id_t ctx; -+ -+ maj = krb5_gss_import_sec_context(minor_status, interprocess_token, &gssc); -+ if (maj != GSS_S_COMPLETE) -+ return maj; -+ kctx = (krb5_gss_ctx_id_t)gssc; -+ -+ if (!kctx->established) { -+ /* We don't currently support importing partially established -+ * contexts. */ -+ krb5_gss_delete_sec_context(&tmpmin, &gssc, GSS_C_NO_BUFFER); -+ return GSS_S_FAILURE; -+ } - -+ code = iakerb_alloc_context(&ctx, kctx->initiate); -+ if (code != 0) { -+ krb5_gss_delete_sec_context(&tmpmin, &gssc, GSS_C_NO_BUFFER); -+ *minor_status = code; -+ return GSS_S_FAILURE; -+ } -+ -+ ctx->gssc = gssc; -+ ctx->established = 1; -+ *context_handle = (gss_ctx_id_t)ctx; -+ return GSS_S_COMPLETE; -+} - #endif /* LEAN_CLIENT */ - - OM_uint32 KRB5_CALLCONV diff --git a/gnu/packages/patches/mit-krb5-CVE-2015-8629.patch b/gnu/packages/patches/mit-krb5-CVE-2015-8629.patch new file mode 100644 index 0000000000..a296d8cb1b --- /dev/null +++ b/gnu/packages/patches/mit-krb5-CVE-2015-8629.patch @@ -0,0 +1,51 @@ +Copied from Fedora. +http://pkgs.fedoraproject.org/cgit/rpms/krb5.git/tree/krb5-CVE-2015-8629.patch?h=f22 + +From df17a1224a3406f57477bcd372c61e04c0e5a5bb Mon Sep 17 00:00:00 2001 +From: Greg Hudson <ghudson@mit.edu> +Date: Fri, 8 Jan 2016 12:45:25 -0500 +Subject: [PATCH 1/3] Verify decoded kadmin C strings [CVE-2015-8629] + +In xdr_nullstring(), check that the decoded string is terminated with +a zero byte and does not contain any internal zero bytes. + +CVE-2015-8629: + +In all versions of MIT krb5, an authenticated attacker can cause +kadmind to read beyond the end of allocated memory by sending a string +without a terminating zero byte. Information leakage may be possible +for an attacker with permission to modify the database. + + CVSSv2 Vector: AV:N/AC:H/Au:S/C:P/I:N/A:N/E:POC/RL:OF/RC:C + +ticket: 8341 (new) +target_version: 1.14-next +target_version: 1.13-next +tags: pullup +--- + src/lib/kadm5/kadm_rpc_xdr.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/src/lib/kadm5/kadm_rpc_xdr.c b/src/lib/kadm5/kadm_rpc_xdr.c +index 2bef858..ba67084 100644 +--- a/src/lib/kadm5/kadm_rpc_xdr.c ++++ b/src/lib/kadm5/kadm_rpc_xdr.c +@@ -64,7 +64,14 @@ bool_t xdr_nullstring(XDR *xdrs, char **objp) + return FALSE; + } + } +- return (xdr_opaque(xdrs, *objp, size)); ++ if (!xdr_opaque(xdrs, *objp, size)) ++ return FALSE; ++ /* Check that the unmarshalled bytes are a C string. */ ++ if ((*objp)[size - 1] != '\0') ++ return FALSE; ++ if (memchr(*objp, '\0', size - 1) != NULL) ++ return FALSE; ++ return TRUE; + + case XDR_ENCODE: + if (size != 0) +-- +2.7.0.rc3 + diff --git a/gnu/packages/patches/mit-krb5-CVE-2015-8630.patch b/gnu/packages/patches/mit-krb5-CVE-2015-8630.patch new file mode 100644 index 0000000000..c21d84b1e7 --- /dev/null +++ b/gnu/packages/patches/mit-krb5-CVE-2015-8630.patch @@ -0,0 +1,81 @@ +Copied from Fedora. +http://pkgs.fedoraproject.org/cgit/rpms/krb5.git/tree/krb5-CVE-2015-8630.patch?h=f22 + +From b863de7fbf080b15e347a736fdda0a82d42f4f6b Mon Sep 17 00:00:00 2001 +From: Greg Hudson <ghudson@mit.edu> +Date: Fri, 8 Jan 2016 12:52:28 -0500 +Subject: [PATCH 2/3] Check for null kadm5 policy name [CVE-2015-8630] + +In kadm5_create_principal_3() and kadm5_modify_principal(), check for +entry->policy being null when KADM5_POLICY is included in the mask. + +CVE-2015-8630: + +In MIT krb5 1.12 and later, an authenticated attacker with permission +to modify a principal entry can cause kadmind to dereference a null +pointer by supplying a null policy value but including KADM5_POLICY in +the mask. + + CVSSv2 Vector: AV:N/AC:H/Au:S/C:N/I:N/A:C/E:POC/RL:OF/RC:C + +ticket: 8342 (new) +target_version: 1.14-next +target_version: 1.13-next +tags: pullup +--- + src/lib/kadm5/srv/svr_principal.c | 12 ++++++++---- + 1 file changed, 8 insertions(+), 4 deletions(-) + +diff --git a/src/lib/kadm5/srv/svr_principal.c b/src/lib/kadm5/srv/svr_principal.c +index 5b95fa3..1d4365c 100644 +--- a/src/lib/kadm5/srv/svr_principal.c ++++ b/src/lib/kadm5/srv/svr_principal.c +@@ -395,6 +395,8 @@ kadm5_create_principal_3(void *server_handle, + /* + * Argument sanity checking, and opening up the DB + */ ++ if (entry == NULL) ++ return EINVAL; + if(!(mask & KADM5_PRINCIPAL) || (mask & KADM5_MOD_NAME) || + (mask & KADM5_MOD_TIME) || (mask & KADM5_LAST_PWD_CHANGE) || + (mask & KADM5_MKVNO) || (mask & KADM5_AUX_ATTRIBUTES) || +@@ -403,12 +405,12 @@ kadm5_create_principal_3(void *server_handle, + return KADM5_BAD_MASK; + if ((mask & KADM5_KEY_DATA) && entry->n_key_data != 0) + return KADM5_BAD_MASK; ++ if((mask & KADM5_POLICY) && entry->policy == NULL) ++ return KADM5_BAD_MASK; + if((mask & KADM5_POLICY) && (mask & KADM5_POLICY_CLR)) + return KADM5_BAD_MASK; + if((mask & ~ALL_PRINC_MASK)) + return KADM5_BAD_MASK; +- if (entry == NULL) +- return EINVAL; + + /* + * Check to see if the principal exists +@@ -643,6 +645,8 @@ kadm5_modify_principal(void *server_handle, + + krb5_clear_error_message(handle->context); + ++ if(entry == NULL) ++ return EINVAL; + if((mask & KADM5_PRINCIPAL) || (mask & KADM5_LAST_PWD_CHANGE) || + (mask & KADM5_MOD_TIME) || (mask & KADM5_MOD_NAME) || + (mask & KADM5_MKVNO) || (mask & KADM5_AUX_ATTRIBUTES) || +@@ -651,10 +655,10 @@ kadm5_modify_principal(void *server_handle, + return KADM5_BAD_MASK; + if((mask & ~ALL_PRINC_MASK)) + return KADM5_BAD_MASK; ++ if((mask & KADM5_POLICY) && entry->policy == NULL) ++ return KADM5_BAD_MASK; + if((mask & KADM5_POLICY) && (mask & KADM5_POLICY_CLR)) + return KADM5_BAD_MASK; +- if(entry == (kadm5_principal_ent_t) NULL) +- return EINVAL; + if (mask & KADM5_TL_DATA) { + tl_data_orig = entry->tl_data; + while (tl_data_orig) { +-- +2.7.0.rc3 + diff --git a/gnu/packages/patches/mit-krb5-CVE-2015-8631.patch b/gnu/packages/patches/mit-krb5-CVE-2015-8631.patch new file mode 100644 index 0000000000..dd1eb2945c --- /dev/null +++ b/gnu/packages/patches/mit-krb5-CVE-2015-8631.patch @@ -0,0 +1,576 @@ +Copied from Fedora. +http://pkgs.fedoraproject.org/cgit/rpms/krb5.git/tree/krb5-CVE-2015-8631.patch?h=f22 + +From 83ed75feba32e46f736fcce0d96a0445f29b96c2 Mon Sep 17 00:00:00 2001 +From: Greg Hudson <ghudson@mit.edu> +Date: Fri, 8 Jan 2016 13:16:54 -0500 +Subject: [PATCH 3/3] Fix leaks in kadmin server stubs [CVE-2015-8631] + +In each kadmind server stub, initialize the client_name and +server_name variables, and release them in the cleanup handler. Many +of the stubs will otherwise leak the client and server name if +krb5_unparse_name() fails. Also make sure to free the prime_arg +variables in rename_principal_2_svc(), or we can leak the first one if +unparsing the second one fails. Discovered by Simo Sorce. + +CVE-2015-8631: + +In all versions of MIT krb5, an authenticated attacker can cause +kadmind to leak memory by supplying a null principal name in a request +which uses one. Repeating these requests will eventually cause +kadmind to exhaust all available memory. + + CVSSv2 Vector: AV:N/AC:L/Au:S/C:N/I:N/A:C/E:POC/RL:OF/RC:C + +ticket: 8343 (new) +target_version: 1.14-next +target_version: 1.13-next +tags: pullup +--- + src/kadmin/server/server_stubs.c | 151 ++++++++++++++++++++------------------- + 1 file changed, 77 insertions(+), 74 deletions(-) + +diff --git a/src/kadmin/server/server_stubs.c b/src/kadmin/server/server_stubs.c +index 1879dc6..6ac797e 100644 +--- a/src/kadmin/server/server_stubs.c ++++ b/src/kadmin/server/server_stubs.c +@@ -334,7 +334,8 @@ create_principal_2_svc(cprinc_arg *arg, struct svc_req *rqstp) + { + static generic_ret ret; + char *prime_arg; +- gss_buffer_desc client_name, service_name; ++ gss_buffer_desc client_name = GSS_C_EMPTY_BUFFER; ++ gss_buffer_desc service_name = GSS_C_EMPTY_BUFFER; + OM_uint32 minor_stat; + kadm5_server_handle_t handle; + restriction_t *rp; +@@ -382,10 +383,10 @@ create_principal_2_svc(cprinc_arg *arg, struct svc_req *rqstp) + krb5_free_error_message(handle->context, errmsg); + } + free(prime_arg); +- gss_release_buffer(&minor_stat, &client_name); +- gss_release_buffer(&minor_stat, &service_name); + + exit_func: ++ gss_release_buffer(&minor_stat, &client_name); ++ gss_release_buffer(&minor_stat, &service_name); + free_server_handle(handle); + return &ret; + } +@@ -395,7 +396,8 @@ create_principal3_2_svc(cprinc3_arg *arg, struct svc_req *rqstp) + { + static generic_ret ret; + char *prime_arg; +- gss_buffer_desc client_name, service_name; ++ gss_buffer_desc client_name = GSS_C_EMPTY_BUFFER; ++ gss_buffer_desc service_name = GSS_C_EMPTY_BUFFER; + OM_uint32 minor_stat; + kadm5_server_handle_t handle; + restriction_t *rp; +@@ -444,10 +446,10 @@ create_principal3_2_svc(cprinc3_arg *arg, struct svc_req *rqstp) + krb5_free_error_message(handle->context, errmsg); + } + free(prime_arg); +- gss_release_buffer(&minor_stat, &client_name); +- gss_release_buffer(&minor_stat, &service_name); + + exit_func: ++ gss_release_buffer(&minor_stat, &client_name); ++ gss_release_buffer(&minor_stat, &service_name); + free_server_handle(handle); + return &ret; + } +@@ -457,8 +459,8 @@ delete_principal_2_svc(dprinc_arg *arg, struct svc_req *rqstp) + { + static generic_ret ret; + char *prime_arg; +- gss_buffer_desc client_name, +- service_name; ++ gss_buffer_desc client_name = GSS_C_EMPTY_BUFFER; ++ gss_buffer_desc service_name = GSS_C_EMPTY_BUFFER; + OM_uint32 minor_stat; + kadm5_server_handle_t handle; + const char *errmsg = NULL; +@@ -501,10 +503,10 @@ delete_principal_2_svc(dprinc_arg *arg, struct svc_req *rqstp) + + } + free(prime_arg); +- gss_release_buffer(&minor_stat, &client_name); +- gss_release_buffer(&minor_stat, &service_name); + + exit_func: ++ gss_release_buffer(&minor_stat, &client_name); ++ gss_release_buffer(&minor_stat, &service_name); + free_server_handle(handle); + return &ret; + } +@@ -514,8 +516,8 @@ modify_principal_2_svc(mprinc_arg *arg, struct svc_req *rqstp) + { + static generic_ret ret; + char *prime_arg; +- gss_buffer_desc client_name, +- service_name; ++ gss_buffer_desc client_name = GSS_C_EMPTY_BUFFER; ++ gss_buffer_desc service_name = GSS_C_EMPTY_BUFFER; + OM_uint32 minor_stat; + kadm5_server_handle_t handle; + restriction_t *rp; +@@ -559,9 +561,9 @@ modify_principal_2_svc(mprinc_arg *arg, struct svc_req *rqstp) + krb5_free_error_message(handle->context, errmsg); + } + free(prime_arg); ++exit_func: + gss_release_buffer(&minor_stat, &client_name); + gss_release_buffer(&minor_stat, &service_name); +-exit_func: + free_server_handle(handle); + return &ret; + } +@@ -570,10 +572,9 @@ generic_ret * + rename_principal_2_svc(rprinc_arg *arg, struct svc_req *rqstp) + { + static generic_ret ret; +- char *prime_arg1, +- *prime_arg2; +- gss_buffer_desc client_name, +- service_name; ++ char *prime_arg1 = NULL, *prime_arg2 = NULL; ++ gss_buffer_desc client_name = GSS_C_EMPTY_BUFFER; ++ gss_buffer_desc service_name = GSS_C_EMPTY_BUFFER; + OM_uint32 minor_stat; + kadm5_server_handle_t handle; + restriction_t *rp; +@@ -655,11 +656,11 @@ rename_principal_2_svc(rprinc_arg *arg, struct svc_req *rqstp) + krb5_free_error_message(handle->context, errmsg); + + } ++exit_func: + free(prime_arg1); + free(prime_arg2); + gss_release_buffer(&minor_stat, &client_name); + gss_release_buffer(&minor_stat, &service_name); +-exit_func: + free_server_handle(handle); + return &ret; + } +@@ -669,8 +670,8 @@ get_principal_2_svc(gprinc_arg *arg, struct svc_req *rqstp) + { + static gprinc_ret ret; + char *prime_arg, *funcname; +- gss_buffer_desc client_name, +- service_name; ++ gss_buffer_desc client_name = GSS_C_EMPTY_BUFFER; ++ gss_buffer_desc service_name = GSS_C_EMPTY_BUFFER; + OM_uint32 minor_stat; + kadm5_server_handle_t handle; + const char *errmsg = NULL; +@@ -719,9 +720,9 @@ get_principal_2_svc(gprinc_arg *arg, struct svc_req *rqstp) + krb5_free_error_message(handle->context, errmsg); + } + free(prime_arg); ++exit_func: + gss_release_buffer(&minor_stat, &client_name); + gss_release_buffer(&minor_stat, &service_name); +-exit_func: + free_server_handle(handle); + return &ret; + } +@@ -731,8 +732,8 @@ get_princs_2_svc(gprincs_arg *arg, struct svc_req *rqstp) + { + static gprincs_ret ret; + char *prime_arg; +- gss_buffer_desc client_name, +- service_name; ++ gss_buffer_desc client_name = GSS_C_EMPTY_BUFFER; ++ gss_buffer_desc service_name = GSS_C_EMPTY_BUFFER; + OM_uint32 minor_stat; + kadm5_server_handle_t handle; + const char *errmsg = NULL; +@@ -777,9 +778,9 @@ get_princs_2_svc(gprincs_arg *arg, struct svc_req *rqstp) + krb5_free_error_message(handle->context, errmsg); + + } ++exit_func: + gss_release_buffer(&minor_stat, &client_name); + gss_release_buffer(&minor_stat, &service_name); +-exit_func: + free_server_handle(handle); + return &ret; + } +@@ -789,8 +790,8 @@ chpass_principal_2_svc(chpass_arg *arg, struct svc_req *rqstp) + { + static generic_ret ret; + char *prime_arg; +- gss_buffer_desc client_name, +- service_name; ++ gss_buffer_desc client_name = GSS_C_EMPTY_BUFFER; ++ gss_buffer_desc service_name = GSS_C_EMPTY_BUFFER; + OM_uint32 minor_stat; + kadm5_server_handle_t handle; + const char *errmsg = NULL; +@@ -840,9 +841,9 @@ chpass_principal_2_svc(chpass_arg *arg, struct svc_req *rqstp) + } + + free(prime_arg); ++exit_func: + gss_release_buffer(&minor_stat, &client_name); + gss_release_buffer(&minor_stat, &service_name); +-exit_func: + free_server_handle(handle); + return &ret; + } +@@ -852,8 +853,8 @@ chpass_principal3_2_svc(chpass3_arg *arg, struct svc_req *rqstp) + { + static generic_ret ret; + char *prime_arg; +- gss_buffer_desc client_name, +- service_name; ++ gss_buffer_desc client_name = GSS_C_EMPTY_BUFFER; ++ gss_buffer_desc service_name = GSS_C_EMPTY_BUFFER; + OM_uint32 minor_stat; + kadm5_server_handle_t handle; + const char *errmsg = NULL; +@@ -909,9 +910,9 @@ chpass_principal3_2_svc(chpass3_arg *arg, struct svc_req *rqstp) + } + + free(prime_arg); ++exit_func: + gss_release_buffer(&minor_stat, &client_name); + gss_release_buffer(&minor_stat, &service_name); +-exit_func: + free_server_handle(handle); + return &ret; + } +@@ -921,8 +922,8 @@ setv4key_principal_2_svc(setv4key_arg *arg, struct svc_req *rqstp) + { + static generic_ret ret; + char *prime_arg; +- gss_buffer_desc client_name, +- service_name; ++ gss_buffer_desc client_name = GSS_C_EMPTY_BUFFER; ++ gss_buffer_desc service_name = GSS_C_EMPTY_BUFFER; + OM_uint32 minor_stat; + kadm5_server_handle_t handle; + const char *errmsg = NULL; +@@ -969,9 +970,9 @@ setv4key_principal_2_svc(setv4key_arg *arg, struct svc_req *rqstp) + } + + free(prime_arg); ++exit_func: + gss_release_buffer(&minor_stat, &client_name); + gss_release_buffer(&minor_stat, &service_name); +-exit_func: + free_server_handle(handle); + return &ret; + } +@@ -981,8 +982,8 @@ setkey_principal_2_svc(setkey_arg *arg, struct svc_req *rqstp) + { + static generic_ret ret; + char *prime_arg; +- gss_buffer_desc client_name, +- service_name; ++ gss_buffer_desc client_name = GSS_C_EMPTY_BUFFER; ++ gss_buffer_desc service_name = GSS_C_EMPTY_BUFFER; + OM_uint32 minor_stat; + kadm5_server_handle_t handle; + const char *errmsg = NULL; +@@ -1029,9 +1030,9 @@ setkey_principal_2_svc(setkey_arg *arg, struct svc_req *rqstp) + } + + free(prime_arg); ++exit_func: + gss_release_buffer(&minor_stat, &client_name); + gss_release_buffer(&minor_stat, &service_name); +-exit_func: + free_server_handle(handle); + return &ret; + } +@@ -1041,8 +1042,8 @@ setkey_principal3_2_svc(setkey3_arg *arg, struct svc_req *rqstp) + { + static generic_ret ret; + char *prime_arg; +- gss_buffer_desc client_name, +- service_name; ++ gss_buffer_desc client_name = GSS_C_EMPTY_BUFFER; ++ gss_buffer_desc service_name = GSS_C_EMPTY_BUFFER; + OM_uint32 minor_stat; + kadm5_server_handle_t handle; + const char *errmsg = NULL; +@@ -1092,9 +1093,9 @@ setkey_principal3_2_svc(setkey3_arg *arg, struct svc_req *rqstp) + } + + free(prime_arg); ++exit_func: + gss_release_buffer(&minor_stat, &client_name); + gss_release_buffer(&minor_stat, &service_name); +-exit_func: + free_server_handle(handle); + return &ret; + } +@@ -1106,8 +1107,8 @@ chrand_principal_2_svc(chrand_arg *arg, struct svc_req *rqstp) + krb5_keyblock *k; + int nkeys; + char *prime_arg, *funcname; +- gss_buffer_desc client_name, +- service_name; ++ gss_buffer_desc client_name = GSS_C_EMPTY_BUFFER; ++ gss_buffer_desc service_name = GSS_C_EMPTY_BUFFER; + OM_uint32 minor_stat; + kadm5_server_handle_t handle; + const char *errmsg = NULL; +@@ -1164,9 +1165,9 @@ chrand_principal_2_svc(chrand_arg *arg, struct svc_req *rqstp) + krb5_free_error_message(handle->context, errmsg); + } + free(prime_arg); ++exit_func: + gss_release_buffer(&minor_stat, &client_name); + gss_release_buffer(&minor_stat, &service_name); +-exit_func: + free_server_handle(handle); + return &ret; + } +@@ -1178,8 +1179,8 @@ chrand_principal3_2_svc(chrand3_arg *arg, struct svc_req *rqstp) + krb5_keyblock *k; + int nkeys; + char *prime_arg, *funcname; +- gss_buffer_desc client_name, +- service_name; ++ gss_buffer_desc client_name = GSS_C_EMPTY_BUFFER; ++ gss_buffer_desc service_name = GSS_C_EMPTY_BUFFER; + OM_uint32 minor_stat; + kadm5_server_handle_t handle; + const char *errmsg = NULL; +@@ -1241,9 +1242,9 @@ chrand_principal3_2_svc(chrand3_arg *arg, struct svc_req *rqstp) + krb5_free_error_message(handle->context, errmsg); + } + free(prime_arg); ++exit_func: + gss_release_buffer(&minor_stat, &client_name); + gss_release_buffer(&minor_stat, &service_name); +-exit_func: + free_server_handle(handle); + return &ret; + } +@@ -1253,8 +1254,8 @@ create_policy_2_svc(cpol_arg *arg, struct svc_req *rqstp) + { + static generic_ret ret; + char *prime_arg; +- gss_buffer_desc client_name, +- service_name; ++ gss_buffer_desc client_name = GSS_C_EMPTY_BUFFER; ++ gss_buffer_desc service_name = GSS_C_EMPTY_BUFFER; + OM_uint32 minor_stat; + kadm5_server_handle_t handle; + const char *errmsg = NULL; +@@ -1295,9 +1296,9 @@ create_policy_2_svc(cpol_arg *arg, struct svc_req *rqstp) + if (errmsg != NULL) + krb5_free_error_message(handle->context, errmsg); + } ++exit_func: + gss_release_buffer(&minor_stat, &client_name); + gss_release_buffer(&minor_stat, &service_name); +-exit_func: + free_server_handle(handle); + return &ret; + } +@@ -1307,8 +1308,8 @@ delete_policy_2_svc(dpol_arg *arg, struct svc_req *rqstp) + { + static generic_ret ret; + char *prime_arg; +- gss_buffer_desc client_name, +- service_name; ++ gss_buffer_desc client_name = GSS_C_EMPTY_BUFFER; ++ gss_buffer_desc service_name = GSS_C_EMPTY_BUFFER; + OM_uint32 minor_stat; + kadm5_server_handle_t handle; + const char *errmsg = NULL; +@@ -1347,9 +1348,9 @@ delete_policy_2_svc(dpol_arg *arg, struct svc_req *rqstp) + if (errmsg != NULL) + krb5_free_error_message(handle->context, errmsg); + } ++exit_func: + gss_release_buffer(&minor_stat, &client_name); + gss_release_buffer(&minor_stat, &service_name); +-exit_func: + free_server_handle(handle); + return &ret; + } +@@ -1359,8 +1360,8 @@ modify_policy_2_svc(mpol_arg *arg, struct svc_req *rqstp) + { + static generic_ret ret; + char *prime_arg; +- gss_buffer_desc client_name, +- service_name; ++ gss_buffer_desc client_name = GSS_C_EMPTY_BUFFER; ++ gss_buffer_desc service_name = GSS_C_EMPTY_BUFFER; + OM_uint32 minor_stat; + kadm5_server_handle_t handle; + const char *errmsg = NULL; +@@ -1400,9 +1401,9 @@ modify_policy_2_svc(mpol_arg *arg, struct svc_req *rqstp) + if (errmsg != NULL) + krb5_free_error_message(handle->context, errmsg); + } ++exit_func: + gss_release_buffer(&minor_stat, &client_name); + gss_release_buffer(&minor_stat, &service_name); +-exit_func: + free_server_handle(handle); + return &ret; + } +@@ -1413,8 +1414,8 @@ get_policy_2_svc(gpol_arg *arg, struct svc_req *rqstp) + static gpol_ret ret; + kadm5_ret_t ret2; + char *prime_arg, *funcname; +- gss_buffer_desc client_name, +- service_name; ++ gss_buffer_desc client_name = GSS_C_EMPTY_BUFFER; ++ gss_buffer_desc service_name = GSS_C_EMPTY_BUFFER; + OM_uint32 minor_stat; + kadm5_principal_ent_rec caller_ent; + kadm5_server_handle_t handle; +@@ -1475,9 +1476,9 @@ get_policy_2_svc(gpol_arg *arg, struct svc_req *rqstp) + log_unauth(funcname, prime_arg, + &client_name, &service_name, rqstp); + } ++exit_func: + gss_release_buffer(&minor_stat, &client_name); + gss_release_buffer(&minor_stat, &service_name); +-exit_func: + free_server_handle(handle); + return &ret; + +@@ -1488,8 +1489,8 @@ get_pols_2_svc(gpols_arg *arg, struct svc_req *rqstp) + { + static gpols_ret ret; + char *prime_arg; +- gss_buffer_desc client_name, +- service_name; ++ gss_buffer_desc client_name = GSS_C_EMPTY_BUFFER; ++ gss_buffer_desc service_name = GSS_C_EMPTY_BUFFER; + OM_uint32 minor_stat; + kadm5_server_handle_t handle; + const char *errmsg = NULL; +@@ -1531,9 +1532,9 @@ get_pols_2_svc(gpols_arg *arg, struct svc_req *rqstp) + if (errmsg != NULL) + krb5_free_error_message(handle->context, errmsg); + } ++exit_func: + gss_release_buffer(&minor_stat, &client_name); + gss_release_buffer(&minor_stat, &service_name); +-exit_func: + free_server_handle(handle); + return &ret; + } +@@ -1541,7 +1542,8 @@ exit_func: + getprivs_ret * get_privs_2_svc(krb5_ui_4 *arg, struct svc_req *rqstp) + { + static getprivs_ret ret; +- gss_buffer_desc client_name, service_name; ++ gss_buffer_desc client_name = GSS_C_EMPTY_BUFFER; ++ gss_buffer_desc service_name = GSS_C_EMPTY_BUFFER; + OM_uint32 minor_stat; + kadm5_server_handle_t handle; + const char *errmsg = NULL; +@@ -1571,9 +1573,9 @@ getprivs_ret * get_privs_2_svc(krb5_ui_4 *arg, struct svc_req *rqstp) + if (errmsg != NULL) + krb5_free_error_message(handle->context, errmsg); + ++exit_func: + gss_release_buffer(&minor_stat, &client_name); + gss_release_buffer(&minor_stat, &service_name); +-exit_func: + free_server_handle(handle); + return &ret; + } +@@ -1583,7 +1585,8 @@ purgekeys_2_svc(purgekeys_arg *arg, struct svc_req *rqstp) + { + static generic_ret ret; + char *prime_arg, *funcname; +- gss_buffer_desc client_name, service_name; ++ gss_buffer_desc client_name = GSS_C_EMPTY_BUFFER; ++ gss_buffer_desc service_name = GSS_C_EMPTY_BUFFER; + OM_uint32 minor_stat; + kadm5_server_handle_t handle; + +@@ -1629,9 +1632,9 @@ purgekeys_2_svc(purgekeys_arg *arg, struct svc_req *rqstp) + krb5_free_error_message(handle->context, errmsg); + } + free(prime_arg); ++exit_func: + gss_release_buffer(&minor_stat, &client_name); + gss_release_buffer(&minor_stat, &service_name); +-exit_func: + free_server_handle(handle); + return &ret; + } +@@ -1641,8 +1644,8 @@ get_strings_2_svc(gstrings_arg *arg, struct svc_req *rqstp) + { + static gstrings_ret ret; + char *prime_arg; +- gss_buffer_desc client_name, +- service_name; ++ gss_buffer_desc client_name = GSS_C_EMPTY_BUFFER; ++ gss_buffer_desc service_name = GSS_C_EMPTY_BUFFER; + OM_uint32 minor_stat; + kadm5_server_handle_t handle; + const char *errmsg = NULL; +@@ -1688,9 +1691,9 @@ get_strings_2_svc(gstrings_arg *arg, struct svc_req *rqstp) + krb5_free_error_message(handle->context, errmsg); + } + free(prime_arg); ++exit_func: + gss_release_buffer(&minor_stat, &client_name); + gss_release_buffer(&minor_stat, &service_name); +-exit_func: + free_server_handle(handle); + return &ret; + } +@@ -1700,8 +1703,8 @@ set_string_2_svc(sstring_arg *arg, struct svc_req *rqstp) + { + static generic_ret ret; + char *prime_arg; +- gss_buffer_desc client_name, +- service_name; ++ gss_buffer_desc client_name = GSS_C_EMPTY_BUFFER; ++ gss_buffer_desc service_name = GSS_C_EMPTY_BUFFER; + OM_uint32 minor_stat; + kadm5_server_handle_t handle; + const char *errmsg = NULL; +@@ -1744,9 +1747,9 @@ set_string_2_svc(sstring_arg *arg, struct svc_req *rqstp) + krb5_free_error_message(handle->context, errmsg); + } + free(prime_arg); ++exit_func: + gss_release_buffer(&minor_stat, &client_name); + gss_release_buffer(&minor_stat, &service_name); +-exit_func: + free_server_handle(handle); + return &ret; + } +@@ -1754,8 +1757,8 @@ exit_func: + generic_ret *init_2_svc(krb5_ui_4 *arg, struct svc_req *rqstp) + { + static generic_ret ret; +- gss_buffer_desc client_name, +- service_name; ++ gss_buffer_desc client_name = GSS_C_EMPTY_BUFFER; ++ gss_buffer_desc service_name = GSS_C_EMPTY_BUFFER; + kadm5_server_handle_t handle; + OM_uint32 minor_stat; + const char *errmsg = NULL; +@@ -1797,10 +1800,10 @@ generic_ret *init_2_svc(krb5_ui_4 *arg, struct svc_req *rqstp) + rqstp->rq_cred.oa_flavor); + if (errmsg != NULL) + krb5_free_error_message(NULL, errmsg); +- gss_release_buffer(&minor_stat, &client_name); +- gss_release_buffer(&minor_stat, &service_name); + + exit_func: ++ gss_release_buffer(&minor_stat, &client_name); ++ gss_release_buffer(&minor_stat, &service_name); + return(&ret); + } + +-- +2.7.0.rc3 + diff --git a/gnu/packages/patches/mit-krb5-init-context-null-spnego.patch b/gnu/packages/patches/mit-krb5-init-context-null-spnego.patch new file mode 100644 index 0000000000..195db38d08 --- /dev/null +++ b/gnu/packages/patches/mit-krb5-init-context-null-spnego.patch @@ -0,0 +1,49 @@ +Copied from Fedora. +http://pkgs.fedoraproject.org/cgit/rpms/krb5.git/tree/krb5-init_context_null_spnego.patch?h=f22 + +From 3beb564cea3d219efcf71682b6576cad548c2d23 Mon Sep 17 00:00:00 2001 +From: Simo Sorce <simo@redhat.com> +Date: Tue, 5 Jan 2016 12:11:59 -0500 +Subject: [PATCH] Check internal context on init context errors + +If the mechanism deletes the internal context handle on error, the +mechglue must do the same with the union context, to avoid crashes if +the application calls other functions with this invalid union context. + +[ghudson@mit.edu: edit commit message and code comment] + +ticket: 8337 (new) +target_version: 1.14-next +target_version: 1.13-next +tags: pullup +--- + src/lib/gssapi/mechglue/g_init_sec_context.c | 11 +++++++---- + 1 file changed, 7 insertions(+), 4 deletions(-) + +diff --git a/src/lib/gssapi/mechglue/g_init_sec_context.c b/src/lib/gssapi/mechglue/g_init_sec_context.c +index aaae767..9f154b8 100644 +--- a/src/lib/gssapi/mechglue/g_init_sec_context.c ++++ b/src/lib/gssapi/mechglue/g_init_sec_context.c +@@ -224,12 +224,15 @@ OM_uint32 * time_rec; + + if (status != GSS_S_COMPLETE && status != GSS_S_CONTINUE_NEEDED) { + /* +- * the spec says (the preferred) method is to delete all +- * context info on the first call to init, and on all +- * subsequent calls make the caller responsible for +- * calling gss_delete_sec_context ++ * The spec says the preferred method is to delete all context info on ++ * the first call to init, and on all subsequent calls make the caller ++ * responsible for calling gss_delete_sec_context. However, if the ++ * mechanism decided to delete the internal context, we should also ++ * delete the union context. + */ + map_error(minor_status, mech); ++ if (union_ctx_id->internal_ctx_id == GSS_C_NO_CONTEXT) ++ *context_handle = GSS_C_NO_CONTEXT; + if (*context_handle == GSS_C_NO_CONTEXT) { + free(union_ctx_id->mech_type->elements); + free(union_ctx_id->mech_type); +-- +2.6.4 + |