Pull in fix for CVE-2014-4341/CVE-2014-4342
- pull in fix for denial of service by injection of malformed GSSAPI tokens (CVE-2014-4341, CVE-2014-4342, #1116181)
This commit is contained in:
		
							parent
							
								
									40e2189ede
								
							
						
					
					
						commit
						e2bc024559
					
				
							
								
								
									
										547
									
								
								krb5-1.12-CVE-2014-4341_4342-tests.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										547
									
								
								krb5-1.12-CVE-2014-4341_4342-tests.patch
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,547 @@
 | 
			
		||||
Changes to .gitignore removed, chunks for tests/gssapi/Makefile.in adjusted to
 | 
			
		||||
account for t_prf not being around yet, calls to gssint_g__seqstate_init()
 | 
			
		||||
changed to calls to gssint_g_order_init(), changed attempt to export
 | 
			
		||||
gssint_g_seqstate_init() to export gssint_g_order_init().
 | 
			
		||||
 | 
			
		||||
commit 7a9990d73537dcdd95bf9b280ebfd560adf8342d
 | 
			
		||||
Author: Greg Hudson <ghudson@mit.edu>
 | 
			
		||||
Date:   Thu Jun 19 13:13:33 2014 -0400
 | 
			
		||||
 | 
			
		||||
    Add tests for invalid GSSAPI per-message tokens
 | 
			
		||||
    
 | 
			
		||||
    ticket: 7949
 | 
			
		||||
 | 
			
		||||
--- a/src/lib/gssapi/libgssapi_krb5.exports
 | 
			
		||||
+++ b/src/lib/gssapi/libgssapi_krb5.exports
 | 
			
		||||
@@ -157,3 +157,4 @@ gss_inquire_name
 | 
			
		||||
 gss_acquire_cred_from
 | 
			
		||||
 gss_add_cred_from
 | 
			
		||||
 gss_store_cred_into
 | 
			
		||||
+gssint_g_order_init
 | 
			
		||||
diff --git a/src/tests/gssapi/Makefile.in b/src/tests/gssapi/Makefile.in
 | 
			
		||||
index ac6a435..5effd90 100644
 | 
			
		||||
--- a/src/tests/gssapi/Makefile.in
 | 
			
		||||
+++ b/src/tests/gssapi/Makefile.in
 | 
			
		||||
@@ -1,6 +1,7 @@
 | 
			
		||||
 mydir=tests$(S)gssapi
 | 
			
		||||
 BUILDTOP=$(REL)..$(S)..
 | 
			
		||||
 DEFINES = -DUSE_AUTOCONF_H
 | 
			
		||||
+LOCALINCLUDES = -I../../lib/gssapi/mechglue -I../../lib/gssapi/generic -I../../lib/gssapi/krb5
 | 
			
		||||
 
 | 
			
		||||
 SRCS=	$(srcdir)/ccinit.c $(srcdir)/ccrefresh.c $(srcdir)/common.c \
 | 
			
		||||
 	$(srcdir)/t_accname.c $(srcdir)/t_ccselect.c $(srcdir)/t_credstore.c \
 | 
			
		||||
@@ -12,27 +13,28 @@ SRCS=	$(srcdir)/ccinit.c $(srcdir)/ccrefresh.c $(srcdir)/common.c \
 | 
			
		||||
 	$(srcdir)/t_accname.c $(srcdir)/t_ccselect.c $(srcdir)/t_credstore.c \
 | 
			
		||||
 	$(srcdir)/t_enctypes.c $(srcdir)/t_err.c $(srcdir)/t_export_cred.c \
 | 
			
		||||
 	$(srcdir)/t_export_name.c $(srcdir)/t_gssexts.c \
 | 
			
		||||
-	$(srcdir)/t_imp_cred.c $(srcdir)/t_imp_name.c $(srcdir)/t_inq_cred.c \
 | 
			
		||||
-	$(srcdir)/t_inq_mechs_name.c $(srcdir)/t_iov.c \
 | 
			
		||||
+	$(srcdir)/t_imp_cred.c $(srcdir)/t_imp_name.c $(srcdir)/t_invalid.c \
 | 
			
		||||
+	$(srcdir)/t_inq_cred.c $(srcdir)/t_inq_mechs_name.c $(srcdir)/t_iov.c \
 | 
			
		||||
 	$(srcdir)/t_namingexts.c $(srcdir)/t_oid.c $(srcdir)/t_s4u.c \
 | 
			
		||||
 	$(srcdir)/t_s4u2proxy_krb5.c $(srcdir)/t_saslname.c \
 | 
			
		||||
 	$(srcdir)/t_spnego.c
 | 
			
		||||
 
 | 
			
		||||
 OBJS=	ccinit.o ccrefresh.o common.o t_accname.o t_ccselect.o t_credstore.o \
 | 
			
		||||
 	t_enctypes.o t_err.o t_export_cred.o t_export_name.o t_gssexts.o \
 | 
			
		||||
-	t_imp_cred.o t_imp_name.o t_inq_cred.o t_inq_mechs_name.o t_iov.o \
 | 
			
		||||
-	t_namingexts.o t_oid.o t_s4u.o t_s4u2proxy_krb5.o t_saslname.o \
 | 
			
		||||
+	t_imp_cred.o t_imp_name.o t_invalid.o t_inq_cred.o t_inq_mechs_name.o \
 | 
			
		||||
+	t_iov.o t_namingexts.o t_oid.o t_s4u.o t_s4u2proxy_krb5.o t_saslname.o \
 | 
			
		||||
 	t_spnego.o
 | 
			
		||||
 
 | 
			
		||||
 COMMON_DEPS= common.o $(GSS_DEPLIBS) $(KRB5_BASE_DEPLIBS)
 | 
			
		||||
 COMMON_LIBS= common.o $(GSS_LIBS) $(KRB5_BASE_LIBS)
 | 
			
		||||
 
 | 
			
		||||
 all:: ccinit ccrefresh t_accname t_ccselect t_credstore t_enctypes t_err \
 | 
			
		||||
-	t_export_cred t_export_name t_gssexts t_imp_cred t_imp_name \
 | 
			
		||||
+	t_export_cred t_export_name t_gssexts t_imp_cred t_imp_name t_invalid \
 | 
			
		||||
 	t_inq_cred t_inq_mechs_name t_iov t_namingexts t_oid t_s4u \
 | 
			
		||||
 	t_s4u2proxy_krb5 t_saslname t_spnego
 | 
			
		||||
 
 | 
			
		||||
 check-unix:: t_oid
 | 
			
		||||
+	$(RUN_SETUP) $(VALGRIND) ./t_invalid
 | 
			
		||||
 	$(RUN_SETUP) $(VALGRIND) ./t_oid
 | 
			
		||||
 
 | 
			
		||||
 check-pytests:: ccinit ccrefresh t_accname t_ccselect t_credstore t_enctypes \
 | 
			
		||||
@@ -70,6 +72,8 @@ t_imp_cred: t_imp_cred.o $(COMMON_DEPS)
 | 
			
		||||
 	$(CC_LINK) -o $@ t_imp_cred.o $(COMMON_LIBS)
 | 
			
		||||
 t_imp_name: t_imp_name.o $(COMMON_DEPS)
 | 
			
		||||
 	$(CC_LINK) -o $@ t_imp_name.o $(COMMON_LIBS)
 | 
			
		||||
+t_invalid: t_invalid.o $(COMMON_DEPS)
 | 
			
		||||
+	$(CC_LINK) -o $@ t_invalid.o $(COMMON_LIBS)
 | 
			
		||||
 t_inq_cred: t_inq_cred.o $(COMMON_DEPS)
 | 
			
		||||
 	$(CC_LINK) -o $@ t_inq_cred.o $(COMMON_LIBS)
 | 
			
		||||
 t_inq_mechs_name: t_inq_mechs_name.o $(COMMON_DEPS)
 | 
			
		||||
@@ -94,5 +98,5 @@ t_spnego: t_spnego.o $(COMMON_DEPS)
 | 
			
		||||
 clean::
 | 
			
		||||
 	$(RM) ccinit ccrefresh t_accname t_ccselect t_credstore t_enctypes
 | 
			
		||||
 	$(RM) t_err t_export_cred t_export_name t_gssexts t_imp_cred t_imp_name
 | 
			
		||||
-	$(RM) t_inq_cred t_inq_mechs_name t_iov t_namingexts t_oid t_s4u
 | 
			
		||||
-	$(RM) t_s4u2proxy_krb5 t_saslname t_spnego
 | 
			
		||||
+	$(RM) t_invalid t_inq_cred t_inq_mechs_name t_iov t_namingexts t_oid
 | 
			
		||||
+	$(RM) t_s4u t_s4u2proxy_krb5 t_saslname t_spnego
 | 
			
		||||
diff --git a/src/tests/gssapi/deps b/src/tests/gssapi/deps
 | 
			
		||||
index c76d4ca..0a82d5d 100644
 | 
			
		||||
--- a/src/tests/gssapi/deps
 | 
			
		||||
+++ b/src/tests/gssapi/deps
 | 
			
		||||
@@ -75,6 +75,24 @@ $(OUTPRE)t_imp_name.$(OBJEXT): $(BUILDTOP)/include/gssapi/gssapi.h \
 | 
			
		||||
   $(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/gssapi/gssapi_krb5.h \
 | 
			
		||||
   $(BUILDTOP)/include/krb5/krb5.h $(COM_ERR_DEPS) $(top_srcdir)/include/krb5.h \
 | 
			
		||||
   common.h t_imp_name.c
 | 
			
		||||
+$(OUTPRE)t_invalid.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
 | 
			
		||||
+  $(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/gssapi/gssapi_alloc.h \
 | 
			
		||||
+  $(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/gssapi/gssapi_krb5.h \
 | 
			
		||||
+  $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \
 | 
			
		||||
+  $(BUILDTOP)/include/profile.h $(BUILDTOP)/lib/gssapi/generic/gssapi_err_generic.h \
 | 
			
		||||
+  $(BUILDTOP)/lib/gssapi/krb5/gssapi_err_krb5.h $(COM_ERR_DEPS) \
 | 
			
		||||
+  $(srcdir)/../../lib/gssapi/generic/gssapiP_generic.h \
 | 
			
		||||
+  $(srcdir)/../../lib/gssapi/generic/gssapi_ext.h $(srcdir)/../../lib/gssapi/generic/gssapi_generic.h \
 | 
			
		||||
+  $(srcdir)/../../lib/gssapi/krb5/gssapiP_krb5.h $(srcdir)/../../lib/gssapi/krb5/gssapi_krb5.h \
 | 
			
		||||
+  $(srcdir)/../../lib/gssapi/mechglue/mechglue.h $(srcdir)/../../lib/gssapi/mechglue/mglueP.h \
 | 
			
		||||
+  $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \
 | 
			
		||||
+  $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \
 | 
			
		||||
+  $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \
 | 
			
		||||
+  $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \
 | 
			
		||||
+  $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \
 | 
			
		||||
+  $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \
 | 
			
		||||
+  $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \
 | 
			
		||||
+  common.h t_invalid.c
 | 
			
		||||
 $(OUTPRE)t_inq_cred.$(OBJEXT): $(BUILDTOP)/include/gssapi/gssapi.h \
 | 
			
		||||
   $(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/gssapi/gssapi_krb5.h \
 | 
			
		||||
   $(BUILDTOP)/include/krb5/krb5.h $(COM_ERR_DEPS) $(top_srcdir)/include/krb5.h \
 | 
			
		||||
diff --git a/src/tests/gssapi/t_invalid.c b/src/tests/gssapi/t_invalid.c
 | 
			
		||||
new file mode 100644
 | 
			
		||||
index 0000000..5c8ddac
 | 
			
		||||
--- /dev/null
 | 
			
		||||
+++ b/src/tests/gssapi/t_invalid.c
 | 
			
		||||
@@ -0,0 +1,429 @@
 | 
			
		||||
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
 | 
			
		||||
+/* tests/gssapi/t_invalid.c - Invalid message token regression tests */
 | 
			
		||||
+/*
 | 
			
		||||
+ * Copyright (C) 2014 by the Massachusetts Institute of Technology.
 | 
			
		||||
+ * All rights reserved.
 | 
			
		||||
+ *
 | 
			
		||||
+ * Redistribution and use in source and binary forms, with or without
 | 
			
		||||
+ * modification, are permitted provided that the following conditions
 | 
			
		||||
+ * are met:
 | 
			
		||||
+ *
 | 
			
		||||
+ * * Redistributions of source code must retain the above copyright
 | 
			
		||||
+ *   notice, this list of conditions and the following disclaimer.
 | 
			
		||||
+ *
 | 
			
		||||
+ * * Redistributions in binary form must reproduce the above copyright
 | 
			
		||||
+ *   notice, this list of conditions and the following disclaimer in
 | 
			
		||||
+ *   the documentation and/or other materials provided with the
 | 
			
		||||
+ *   distribution.
 | 
			
		||||
+ *
 | 
			
		||||
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | 
			
		||||
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | 
			
		||||
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 | 
			
		||||
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 | 
			
		||||
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 | 
			
		||||
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 | 
			
		||||
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 | 
			
		||||
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 | 
			
		||||
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 | 
			
		||||
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 | 
			
		||||
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 | 
			
		||||
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
+ */
 | 
			
		||||
+
 | 
			
		||||
+/*
 | 
			
		||||
+ * This file contains regression tests for some GSSAPI krb5 invalid per-message
 | 
			
		||||
+ * token vulnerabilities.
 | 
			
		||||
+ *
 | 
			
		||||
+ * 1. A pre-CFX wrap or MIC token processed with a CFX-only context causes a
 | 
			
		||||
+ *    null pointer dereference.  (The token must use SEAL_ALG_NONE or it will
 | 
			
		||||
+ *    be rejected.)
 | 
			
		||||
+ *
 | 
			
		||||
+ * 2. A pre-CFX wrap or MIC token with fewer than 24 bytes after the ASN.1
 | 
			
		||||
+ *    header causes an input buffer overrun, usually leading to either a segv
 | 
			
		||||
+ *    or a GSS_S_DEFECTIVE_TOKEN error due to garbage algorithm, filler, or
 | 
			
		||||
+ *    sequence number values.
 | 
			
		||||
+ *
 | 
			
		||||
+ * 3. A pre-CFX wrap token with fewer than 16 + cksumlen bytes after the ASN.1
 | 
			
		||||
+ *    header causes an integer underflow when computing the ciphertext length,
 | 
			
		||||
+ *    leading to an allocation error on 32-bit platforms or a segv on 64-bit
 | 
			
		||||
+ *    platforms.  A pre-CFX MIC token of this size causes an input buffer
 | 
			
		||||
+ *    overrun when comparing the checksum, perhaps leading to a segv.
 | 
			
		||||
+ *
 | 
			
		||||
+ * 4. A pre-CFX wrap token with fewer than conflen + padlen bytes in the
 | 
			
		||||
+ *    ciphertext (where padlen is the last byte of the decrypted ciphertext)
 | 
			
		||||
+ *    causes an integer underflow when computing the original message length,
 | 
			
		||||
+ *    leading to an allocation error.
 | 
			
		||||
+ *
 | 
			
		||||
+ * Vulnerabilities #1 and #2 also apply to IOV unwrap, although tokens with
 | 
			
		||||
+ * fewer than 16 bytes after the ASN.1 header will be rejected.  Vulnerability
 | 
			
		||||
+ * #2 can only be robustly detected using a memory-checking environment such as
 | 
			
		||||
+ * valgrind.
 | 
			
		||||
+ */
 | 
			
		||||
+
 | 
			
		||||
+#include "k5-int.h"
 | 
			
		||||
+#include "common.h"
 | 
			
		||||
+#include "mglueP.h"
 | 
			
		||||
+#include "gssapiP_krb5.h"
 | 
			
		||||
+
 | 
			
		||||
+/*
 | 
			
		||||
+ * The following samples contain context parameters and otherwise valid seal
 | 
			
		||||
+ * tokens where the plain text is padded with byte value 100 instead of the
 | 
			
		||||
+ * proper value 1.
 | 
			
		||||
+ */
 | 
			
		||||
+struct test {
 | 
			
		||||
+    krb5_enctype enctype;
 | 
			
		||||
+    krb5_enctype encseq_enctype;
 | 
			
		||||
+    int sealalg;
 | 
			
		||||
+    int signalg;
 | 
			
		||||
+    size_t cksum_size;
 | 
			
		||||
+    size_t keylen;
 | 
			
		||||
+    const char *keydata;
 | 
			
		||||
+    size_t toklen;
 | 
			
		||||
+    const char *token;
 | 
			
		||||
+} tests[] = {
 | 
			
		||||
+    {
 | 
			
		||||
+        ENCTYPE_DES_CBC_CRC, ENCTYPE_DES_CBC_RAW,
 | 
			
		||||
+        SEAL_ALG_DES, SGN_ALG_DES_MAC_MD5, 8,
 | 
			
		||||
+        8,
 | 
			
		||||
+        "\x26\xEC\xBA\xB6\xFE\xBA\x91\xCE",
 | 
			
		||||
+        53,
 | 
			
		||||
+        "\x60\x33\x06\x09\x2A\x86\x48\x86\xF7\x12\x01\x02\x02\x02\x01\x00"
 | 
			
		||||
+        "\x00\x00\x00\xFF\xFF\xF0\x0B\x90\x7B\xC4\xFC\xEB\xF4\x84\x9C\x5A"
 | 
			
		||||
+        "\xA8\x56\x41\x3E\xE1\x62\xEE\x38\xD1\x34\x9A\xE3\xFB\xC9\xFD\x0A"
 | 
			
		||||
+        "\xDC\x83\xE1\x4A\xE4"
 | 
			
		||||
+    },
 | 
			
		||||
+    {
 | 
			
		||||
+        ENCTYPE_DES3_CBC_SHA1, ENCTYPE_DES3_CBC_RAW,
 | 
			
		||||
+        SEAL_ALG_DES3KD, SGN_ALG_HMAC_SHA1_DES3_KD, 20,
 | 
			
		||||
+        24,
 | 
			
		||||
+        "\x4F\xEA\x19\x19\x5E\x0E\x10\xDF\x3D\x29\xB5\x13\x8F\x01\xC7\xA7"
 | 
			
		||||
+        "\x92\x3D\x38\xF7\x26\x73\x0D\x6D",
 | 
			
		||||
+        65,
 | 
			
		||||
+        "\x60\x3F\x06\x09\x2A\x86\x48\x86\xF7\x12\x01\x02\x02\x02\x01\x04"
 | 
			
		||||
+        "\x00\x02\x00\xFF\xFF\xEB\xF3\x9A\x89\x24\x57\xB8\x63\x95\x25\xE8"
 | 
			
		||||
+        "\x6E\x8E\x79\xE6\x2E\xCA\xD3\xFF\x57\x9F\x8C\xAB\xEF\xDD\x28\x10"
 | 
			
		||||
+        "\x2F\x93\x21\x2E\xF2\x52\xB6\x6F\xA8\xBB\x8A\x6D\xAA\x6F\xB7\xF4\xD4"
 | 
			
		||||
+    },
 | 
			
		||||
+    {
 | 
			
		||||
+        ENCTYPE_ARCFOUR_HMAC, ENCTYPE_ARCFOUR_HMAC,
 | 
			
		||||
+        SEAL_ALG_MICROSOFT_RC4, SGN_ALG_HMAC_MD5, 8,
 | 
			
		||||
+        16,
 | 
			
		||||
+        "\x66\x64\x41\x64\x55\x78\x21\xD0\xD0\xFD\x05\x6A\xFF\x6F\xE8\x09",
 | 
			
		||||
+        53,
 | 
			
		||||
+        "\x60\x33\x06\x09\x2A\x86\x48\x86\xF7\x12\x01\x02\x02\x02\x01\x11"
 | 
			
		||||
+        "\x00\x10\x00\xFF\xFF\x35\xD4\x79\xF3\x8C\x47\x8F\x6E\x23\x6F\x3E"
 | 
			
		||||
+        "\xCC\x5E\x57\x5C\x6A\x89\xF0\xA2\x03\x4F\x0B\x51\x11\xEE\x89\x7E"
 | 
			
		||||
+        "\xD6\xF6\xB5\xD6\x51"
 | 
			
		||||
+    }
 | 
			
		||||
+};
 | 
			
		||||
+
 | 
			
		||||
+/* Fake up enough of a CFX GSS context for gss_unwrap, using an AES key. */
 | 
			
		||||
+static gss_ctx_id_t
 | 
			
		||||
+make_fake_cfx_context()
 | 
			
		||||
+{
 | 
			
		||||
+    gss_union_ctx_id_t uctx;
 | 
			
		||||
+    krb5_gss_ctx_id_t kgctx;
 | 
			
		||||
+    krb5_keyblock kb;
 | 
			
		||||
+
 | 
			
		||||
+    kgctx = calloc(1, sizeof(*kgctx));
 | 
			
		||||
+    if (kgctx == NULL)
 | 
			
		||||
+        abort();
 | 
			
		||||
+    kgctx->established = 1;
 | 
			
		||||
+    kgctx->proto = 1;
 | 
			
		||||
+    if (g_order_init(&kgctx->seqstate, 0, 0, 0, 0) != 0)
 | 
			
		||||
+        abort();
 | 
			
		||||
+    kgctx->mech_used = &mech_krb5;
 | 
			
		||||
+    kgctx->sealalg = -1;
 | 
			
		||||
+    kgctx->signalg = -1;
 | 
			
		||||
+
 | 
			
		||||
+    kb.enctype = ENCTYPE_AES128_CTS_HMAC_SHA1_96;
 | 
			
		||||
+    kb.length = 16;
 | 
			
		||||
+    kb.contents = (unsigned char *)"1234567887654321";
 | 
			
		||||
+    if (krb5_k_create_key(NULL, &kb, &kgctx->subkey) != 0)
 | 
			
		||||
+        abort();
 | 
			
		||||
+
 | 
			
		||||
+    uctx = calloc(1, sizeof(*uctx));
 | 
			
		||||
+    if (uctx == NULL)
 | 
			
		||||
+        abort();
 | 
			
		||||
+    uctx->mech_type = &mech_krb5;
 | 
			
		||||
+    uctx->internal_ctx_id = (gss_ctx_id_t)kgctx;
 | 
			
		||||
+    return (gss_ctx_id_t)uctx;
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+/* Fake up enough of a GSS context for gss_unwrap, using keys from test. */
 | 
			
		||||
+static gss_ctx_id_t
 | 
			
		||||
+make_fake_context(const struct test *test)
 | 
			
		||||
+{
 | 
			
		||||
+    gss_union_ctx_id_t uctx;
 | 
			
		||||
+    krb5_gss_ctx_id_t kgctx;
 | 
			
		||||
+    krb5_keyblock kb;
 | 
			
		||||
+    unsigned char encbuf[8];
 | 
			
		||||
+    size_t i;
 | 
			
		||||
+
 | 
			
		||||
+    kgctx = calloc(1, sizeof(*kgctx));
 | 
			
		||||
+    if (kgctx == NULL)
 | 
			
		||||
+        abort();
 | 
			
		||||
+    kgctx->established = 1;
 | 
			
		||||
+    if (g_order_init(&kgctx->seqstate, 0, 0, 0, 0) != 0)
 | 
			
		||||
+        abort();
 | 
			
		||||
+    kgctx->mech_used = &mech_krb5;
 | 
			
		||||
+    kgctx->sealalg = test->sealalg;
 | 
			
		||||
+    kgctx->signalg = test->signalg;
 | 
			
		||||
+    kgctx->cksum_size = test->cksum_size;
 | 
			
		||||
+
 | 
			
		||||
+    kb.enctype = test->enctype;
 | 
			
		||||
+    kb.length = test->keylen;
 | 
			
		||||
+    kb.contents = (unsigned char *)test->keydata;
 | 
			
		||||
+    if (krb5_k_create_key(NULL, &kb, &kgctx->subkey) != 0)
 | 
			
		||||
+        abort();
 | 
			
		||||
+
 | 
			
		||||
+    kb.enctype = test->encseq_enctype;
 | 
			
		||||
+    if (krb5_k_create_key(NULL, &kb, &kgctx->seq) != 0)
 | 
			
		||||
+        abort();
 | 
			
		||||
+
 | 
			
		||||
+    if (kb.enctype == ENCTYPE_DES_CBC_RAW) {
 | 
			
		||||
+        for (i = 0; i < 8; i++)
 | 
			
		||||
+            encbuf[i] = kb.contents[i] ^ 0xF0;
 | 
			
		||||
+        kb.contents = encbuf;
 | 
			
		||||
+    }
 | 
			
		||||
+    if (krb5_k_create_key(NULL, &kb, &kgctx->enc) != 0)
 | 
			
		||||
+        abort();
 | 
			
		||||
+
 | 
			
		||||
+    uctx = calloc(1, sizeof(*uctx));
 | 
			
		||||
+    if (uctx == NULL)
 | 
			
		||||
+        abort();
 | 
			
		||||
+    uctx->mech_type = &mech_krb5;
 | 
			
		||||
+    uctx->internal_ctx_id = (gss_ctx_id_t)kgctx;
 | 
			
		||||
+    return (gss_ctx_id_t)uctx;
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+/* Free a context created by make_fake_context. */
 | 
			
		||||
+static void
 | 
			
		||||
+free_fake_context(gss_ctx_id_t ctx)
 | 
			
		||||
+{
 | 
			
		||||
+    gss_union_ctx_id_t uctx = (gss_union_ctx_id_t)ctx;
 | 
			
		||||
+    krb5_gss_ctx_id_t kgctx = (krb5_gss_ctx_id_t)uctx->internal_ctx_id;
 | 
			
		||||
+
 | 
			
		||||
+    free(kgctx->seqstate);
 | 
			
		||||
+    krb5_k_free_key(NULL, kgctx->subkey);
 | 
			
		||||
+    krb5_k_free_key(NULL, kgctx->seq);
 | 
			
		||||
+    krb5_k_free_key(NULL, kgctx->enc);
 | 
			
		||||
+    free(kgctx);
 | 
			
		||||
+    free(uctx);
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+/* Prefix a token (starting at the two-byte ID) with an ASN.1 header and return
 | 
			
		||||
+ * it in an allocated block to facilitate checking by valgrind or similar. */
 | 
			
		||||
+static void
 | 
			
		||||
+make_token(unsigned char *token, size_t len, gss_buffer_t out)
 | 
			
		||||
+{
 | 
			
		||||
+    char *wrapped;
 | 
			
		||||
+
 | 
			
		||||
+    assert(mech_krb5.length == 9);
 | 
			
		||||
+    assert(len + 11 < 128);
 | 
			
		||||
+    wrapped = malloc(len + 13);
 | 
			
		||||
+    if (wrapped == NULL)
 | 
			
		||||
+        abort();
 | 
			
		||||
+    wrapped[0] = 0x60;
 | 
			
		||||
+    wrapped[1] = len + 11;
 | 
			
		||||
+    wrapped[2] = 0x06;
 | 
			
		||||
+    wrapped[3] = 9;
 | 
			
		||||
+    memcpy(wrapped + 4, mech_krb5.elements, 9);
 | 
			
		||||
+    memcpy(wrapped + 13, token, len);
 | 
			
		||||
+    out->length = len + 13;
 | 
			
		||||
+    out->value = wrapped;
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+/* Unwrap a superficially valid RFC 1964 token with a CFX-only context, with
 | 
			
		||||
+ * regular and IOV unwrap. */
 | 
			
		||||
+static void
 | 
			
		||||
+test_bogus_1964_token(gss_ctx_id_t ctx)
 | 
			
		||||
+{
 | 
			
		||||
+    OM_uint32 minor, major;
 | 
			
		||||
+    unsigned char tokbuf[128];
 | 
			
		||||
+    gss_buffer_desc in, out;
 | 
			
		||||
+    gss_iov_buffer_desc iov;
 | 
			
		||||
+
 | 
			
		||||
+    store_16_be(KG_TOK_SIGN_MSG, tokbuf);
 | 
			
		||||
+    store_16_le(SGN_ALG_DES_MAC_MD5, tokbuf + 2);
 | 
			
		||||
+    store_16_le(SEAL_ALG_NONE, tokbuf + 4);
 | 
			
		||||
+    store_16_le(0xFFFF, tokbuf + 6);
 | 
			
		||||
+    memset(tokbuf + 8, 0, 16);
 | 
			
		||||
+    make_token(tokbuf, 24, &in);
 | 
			
		||||
+
 | 
			
		||||
+    major = gss_unwrap(&minor, ctx, &in, &out, NULL, NULL);
 | 
			
		||||
+    if (major != GSS_S_DEFECTIVE_TOKEN)
 | 
			
		||||
+        abort();
 | 
			
		||||
+    (void)gss_release_buffer(&minor, &out);
 | 
			
		||||
+
 | 
			
		||||
+    iov.type = GSS_IOV_BUFFER_TYPE_HEADER;
 | 
			
		||||
+    iov.buffer = in;
 | 
			
		||||
+    major = gss_unwrap_iov(&minor, ctx, NULL, NULL, &iov, 1);
 | 
			
		||||
+    if (major != GSS_S_DEFECTIVE_TOKEN)
 | 
			
		||||
+        abort();
 | 
			
		||||
+
 | 
			
		||||
+    free(in.value);
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+/* Process wrap and MIC tokens with incomplete headers. */
 | 
			
		||||
+static void
 | 
			
		||||
+test_short_header(gss_ctx_id_t ctx)
 | 
			
		||||
+{
 | 
			
		||||
+    OM_uint32 minor, major;
 | 
			
		||||
+    unsigned char tokbuf[128];
 | 
			
		||||
+    gss_buffer_desc in, out, empty = GSS_C_EMPTY_BUFFER;
 | 
			
		||||
+
 | 
			
		||||
+    /* Seal token, 2-24 bytes */
 | 
			
		||||
+    store_16_be(KG_TOK_SEAL_MSG, tokbuf);
 | 
			
		||||
+    make_token(tokbuf, 2, &in);
 | 
			
		||||
+    major = gss_unwrap(&minor, ctx, &in, &out, NULL, NULL);
 | 
			
		||||
+    if (major != GSS_S_DEFECTIVE_TOKEN)
 | 
			
		||||
+        abort();
 | 
			
		||||
+    free(in.value);
 | 
			
		||||
+    (void)gss_release_buffer(&minor, &out);
 | 
			
		||||
+
 | 
			
		||||
+    /* Sign token, 2-24 bytes */
 | 
			
		||||
+    store_16_be(KG_TOK_SIGN_MSG, tokbuf);
 | 
			
		||||
+    make_token(tokbuf, 2, &in);
 | 
			
		||||
+    major = gss_unwrap(&minor, ctx, &in, &out, NULL, NULL);
 | 
			
		||||
+    if (major != GSS_S_DEFECTIVE_TOKEN)
 | 
			
		||||
+        abort();
 | 
			
		||||
+    free(in.value);
 | 
			
		||||
+    (void)gss_release_buffer(&minor, &out);
 | 
			
		||||
+
 | 
			
		||||
+    /* MIC token, 2-24 bytes */
 | 
			
		||||
+    store_16_be(KG_TOK_MIC_MSG, tokbuf);
 | 
			
		||||
+    make_token(tokbuf, 2, &in);
 | 
			
		||||
+    major = gss_verify_mic(&minor, ctx, &empty, &in, NULL);
 | 
			
		||||
+    if (major != GSS_S_DEFECTIVE_TOKEN)
 | 
			
		||||
+        abort();
 | 
			
		||||
+    free(in.value);
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+/* Process wrap and MIC tokens with incomplete headers. */
 | 
			
		||||
+static void
 | 
			
		||||
+test_short_header_iov(gss_ctx_id_t ctx, const struct test *test)
 | 
			
		||||
+{
 | 
			
		||||
+    OM_uint32 minor, major;
 | 
			
		||||
+    unsigned char tokbuf[128];
 | 
			
		||||
+    gss_iov_buffer_desc iov;
 | 
			
		||||
+
 | 
			
		||||
+    /* IOV seal token, 16-23 bytes */
 | 
			
		||||
+    store_16_be(KG_TOK_SEAL_MSG, tokbuf);
 | 
			
		||||
+    store_16_le(test->signalg, tokbuf + 2);
 | 
			
		||||
+    store_16_le(test->sealalg, tokbuf + 4);
 | 
			
		||||
+    store_16_be(0xFFFF, tokbuf + 6);
 | 
			
		||||
+    memset(tokbuf + 8, 0, 8);
 | 
			
		||||
+    iov.type = GSS_IOV_BUFFER_TYPE_HEADER;
 | 
			
		||||
+    make_token(tokbuf, 16, &iov.buffer);
 | 
			
		||||
+    major = gss_unwrap_iov(&minor, ctx, NULL, NULL, &iov, 1);
 | 
			
		||||
+    if (major != GSS_S_DEFECTIVE_TOKEN)
 | 
			
		||||
+        abort();
 | 
			
		||||
+    free(iov.buffer.value);
 | 
			
		||||
+
 | 
			
		||||
+    /* IOV sign token, 16-23 bytes */
 | 
			
		||||
+    store_16_be(KG_TOK_SIGN_MSG, tokbuf);
 | 
			
		||||
+    store_16_le(test->signalg, tokbuf + 2);
 | 
			
		||||
+    store_16_le(SEAL_ALG_NONE, tokbuf + 4);
 | 
			
		||||
+    store_16_le(0xFFFF, tokbuf + 6);
 | 
			
		||||
+    memset(tokbuf + 8, 0, 8);
 | 
			
		||||
+    iov.type = GSS_IOV_BUFFER_TYPE_HEADER;
 | 
			
		||||
+    make_token(tokbuf, 16, &iov.buffer);
 | 
			
		||||
+    major = gss_unwrap_iov(&minor, ctx, NULL, NULL, &iov, 1);
 | 
			
		||||
+    if (major != GSS_S_DEFECTIVE_TOKEN)
 | 
			
		||||
+        abort();
 | 
			
		||||
+    free(iov.buffer.value);
 | 
			
		||||
+
 | 
			
		||||
+    /* IOV MIC token, 16-23 bytes */
 | 
			
		||||
+    store_16_be(KG_TOK_MIC_MSG, tokbuf);
 | 
			
		||||
+    store_16_be(test->signalg, tokbuf + 2);
 | 
			
		||||
+    store_16_le(SEAL_ALG_NONE, tokbuf + 4);
 | 
			
		||||
+    store_16_le(0xFFFF, tokbuf + 6);
 | 
			
		||||
+    memset(tokbuf + 8, 0, 8);
 | 
			
		||||
+    iov.type = GSS_IOV_BUFFER_TYPE_MIC_TOKEN;
 | 
			
		||||
+    make_token(tokbuf, 16, &iov.buffer);
 | 
			
		||||
+    major = gss_verify_mic_iov(&minor, ctx, NULL, &iov, 1);
 | 
			
		||||
+    if (major != GSS_S_DEFECTIVE_TOKEN)
 | 
			
		||||
+        abort();
 | 
			
		||||
+    free(iov.buffer.value);
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+/* Process wrap and MIC tokens with incomplete checksums. */
 | 
			
		||||
+static void
 | 
			
		||||
+test_short_checksum(gss_ctx_id_t ctx, const struct test *test)
 | 
			
		||||
+{
 | 
			
		||||
+    OM_uint32 minor, major;
 | 
			
		||||
+    unsigned char tokbuf[128];
 | 
			
		||||
+    gss_buffer_desc in, out, empty = GSS_C_EMPTY_BUFFER;
 | 
			
		||||
+
 | 
			
		||||
+    /* Can only do this with the DES3 checksum, as we can't easily get past
 | 
			
		||||
+     * retrieving the sequence number when the checksum is only eight bytes. */
 | 
			
		||||
+    if (test->cksum_size <= 8)
 | 
			
		||||
+        return;
 | 
			
		||||
+    /* Seal token, fewer than 16 + cksum_size bytes.  Use the token from the
 | 
			
		||||
+     * test data to get a valid sequence number. */
 | 
			
		||||
+    make_token((unsigned char *)test->token + 13, 24, &in);
 | 
			
		||||
+    major = gss_unwrap(&minor, ctx, &in, &out, NULL, NULL);
 | 
			
		||||
+    if (major != GSS_S_DEFECTIVE_TOKEN)
 | 
			
		||||
+        abort();
 | 
			
		||||
+    free(in.value);
 | 
			
		||||
+    (void)gss_release_buffer(&minor, &out);
 | 
			
		||||
+
 | 
			
		||||
+    /* Sign token, fewer than 16 + cksum_size bytes. */
 | 
			
		||||
+    memcpy(tokbuf, test->token + 13, 24);
 | 
			
		||||
+    store_16_be(KG_TOK_SIGN_MSG, tokbuf);
 | 
			
		||||
+    store_16_le(SEAL_ALG_NONE, tokbuf + 4);
 | 
			
		||||
+    make_token(tokbuf, 24, &in);
 | 
			
		||||
+    major = gss_unwrap(&minor, ctx, &in, &out, NULL, NULL);
 | 
			
		||||
+    if (major != GSS_S_DEFECTIVE_TOKEN)
 | 
			
		||||
+        abort();
 | 
			
		||||
+    free(in.value);
 | 
			
		||||
+    (void)gss_release_buffer(&minor, &out);
 | 
			
		||||
+
 | 
			
		||||
+    /* MIC token, fewer than 16 + cksum_size bytes. */
 | 
			
		||||
+    memcpy(tokbuf, test->token + 13, 24);
 | 
			
		||||
+    store_16_be(KG_TOK_MIC_MSG, tokbuf);
 | 
			
		||||
+    store_16_le(SEAL_ALG_NONE, tokbuf + 4);
 | 
			
		||||
+    make_token(tokbuf, 24, &in);
 | 
			
		||||
+    major = gss_verify_mic(&minor, ctx, &empty, &in, NULL);
 | 
			
		||||
+    if (major != GSS_S_DEFECTIVE_TOKEN)
 | 
			
		||||
+        abort();
 | 
			
		||||
+    free(in.value);
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+/* Unwrap a token with a bogus padding byte in the decrypted ciphertext. */
 | 
			
		||||
+static void
 | 
			
		||||
+test_bad_pad(gss_ctx_id_t ctx, const struct test *test)
 | 
			
		||||
+{
 | 
			
		||||
+    OM_uint32 minor, major;
 | 
			
		||||
+    gss_buffer_desc in, out;
 | 
			
		||||
+
 | 
			
		||||
+    in.length = test->toklen;
 | 
			
		||||
+    in.value = (char *)test->token;
 | 
			
		||||
+    major = gss_unwrap(&minor, ctx, &in, &out, NULL, NULL);
 | 
			
		||||
+    if (major != GSS_S_BAD_SIG)
 | 
			
		||||
+        abort();
 | 
			
		||||
+    (void)gss_release_buffer(&minor, &out);
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+int
 | 
			
		||||
+main(int argc, char **argv)
 | 
			
		||||
+{
 | 
			
		||||
+    gss_ctx_id_t ctx;
 | 
			
		||||
+    size_t i;
 | 
			
		||||
+
 | 
			
		||||
+    ctx = make_fake_cfx_context();
 | 
			
		||||
+    test_bogus_1964_token(ctx);
 | 
			
		||||
+    free_fake_context(ctx);
 | 
			
		||||
+
 | 
			
		||||
+    for (i = 0; i < sizeof(tests) / sizeof(*tests); i++) {
 | 
			
		||||
+        ctx = make_fake_context(&tests[i]);
 | 
			
		||||
+        test_short_header(ctx);
 | 
			
		||||
+        test_short_header_iov(ctx, &tests[i]);
 | 
			
		||||
+        test_short_checksum(ctx, &tests[i]);
 | 
			
		||||
+        test_bad_pad(ctx, &tests[i]);
 | 
			
		||||
+        free_fake_context(ctx);
 | 
			
		||||
+    }
 | 
			
		||||
+
 | 
			
		||||
+    return 0;
 | 
			
		||||
+}
 | 
			
		||||
							
								
								
									
										163
									
								
								krb5-1.12-CVE-2014-4341_4342.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										163
									
								
								krb5-1.12-CVE-2014-4341_4342.patch
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,163 @@
 | 
			
		||||
commit e6ae703ae597d798e310368d52b8f38ee11c6a73
 | 
			
		||||
Author: Greg Hudson <ghudson@mit.edu>
 | 
			
		||||
Date:   Thu Jun 19 13:49:16 2014 -0400
 | 
			
		||||
 | 
			
		||||
    Handle invalid RFC 1964 tokens [CVE-2014-4341...]
 | 
			
		||||
    
 | 
			
		||||
    Detect the following cases which would otherwise cause invalid memory
 | 
			
		||||
    accesses and/or integer underflow:
 | 
			
		||||
    
 | 
			
		||||
    * An RFC 1964 token being processed by an RFC 4121-only context
 | 
			
		||||
      [CVE-2014-4342]
 | 
			
		||||
    
 | 
			
		||||
    * A header with fewer than 22 bytes after the token ID or an
 | 
			
		||||
      incomplete checksum [CVE-2014-4341 CVE-2014-4342]
 | 
			
		||||
    
 | 
			
		||||
    * A ciphertext shorter than the confounder [CVE-2014-4341]
 | 
			
		||||
    
 | 
			
		||||
    * A declared padding length longer than the plaintext [CVE-2014-4341]
 | 
			
		||||
    
 | 
			
		||||
    If we detect a bad pad byte, continue on to compute the checksum to
 | 
			
		||||
    avoid creating a padding oracle, but treat the checksum as invalid
 | 
			
		||||
    even if it compares equal.
 | 
			
		||||
    
 | 
			
		||||
    CVE-2014-4341:
 | 
			
		||||
    
 | 
			
		||||
    In MIT krb5, an unauthenticated remote attacker with the ability to
 | 
			
		||||
    inject packets into a legitimately established GSSAPI application
 | 
			
		||||
    session can cause a program crash due to invalid memory references
 | 
			
		||||
    when attempting to read beyond the end of a buffer.
 | 
			
		||||
    
 | 
			
		||||
        CVSSv2 Vector: AV:N/AC:M/Au:N/C:N/I:N/A:P/E:POC/RL:OF/RC:C
 | 
			
		||||
    
 | 
			
		||||
    CVE-2014-4342:
 | 
			
		||||
    
 | 
			
		||||
    In MIT krb5 releases krb5-1.7 and later, an unauthenticated remote
 | 
			
		||||
    attacker with the ability to inject packets into a legitimately
 | 
			
		||||
    established GSSAPI application session can cause a program crash due
 | 
			
		||||
    to invalid memory references when reading beyond the end of a buffer
 | 
			
		||||
    or by causing a null pointer dereference.
 | 
			
		||||
    
 | 
			
		||||
        CVSSv2 Vector: AV:N/AC:M/Au:N/C:N/I:N/A:P/E:POC/RL:OF/RC:C
 | 
			
		||||
    
 | 
			
		||||
    [tlyu@mit.edu: CVE summaries, CVSS]
 | 
			
		||||
    
 | 
			
		||||
    (cherry picked from commit fb99962cbd063ac04c9a9d2cc7c75eab73f3533d)
 | 
			
		||||
    
 | 
			
		||||
    ticket: 7949
 | 
			
		||||
    version_fixed: 1.12.2
 | 
			
		||||
    status: resolved
 | 
			
		||||
 | 
			
		||||
diff --git a/src/lib/gssapi/krb5/k5unseal.c b/src/lib/gssapi/krb5/k5unseal.c
 | 
			
		||||
index ca21d43..b65c83c 100644
 | 
			
		||||
--- a/src/lib/gssapi/krb5/k5unseal.c
 | 
			
		||||
+++ b/src/lib/gssapi/krb5/k5unseal.c
 | 
			
		||||
@@ -74,6 +74,7 @@ kg_unseal_v1(context, minor_status, ctx, ptr, bodysize, message_buffer,
 | 
			
		||||
     int conflen = 0;
 | 
			
		||||
     int signalg;
 | 
			
		||||
     int sealalg;
 | 
			
		||||
+    int bad_pad = 0;
 | 
			
		||||
     gss_buffer_desc token;
 | 
			
		||||
     krb5_checksum cksum;
 | 
			
		||||
     krb5_checksum md5cksum;
 | 
			
		||||
@@ -86,6 +87,7 @@ kg_unseal_v1(context, minor_status, ctx, ptr, bodysize, message_buffer,
 | 
			
		||||
     krb5_ui_4 seqnum;
 | 
			
		||||
     OM_uint32 retval;
 | 
			
		||||
     size_t sumlen;
 | 
			
		||||
+    size_t padlen;
 | 
			
		||||
     krb5_keyusage sign_usage = KG_USAGE_SIGN;
 | 
			
		||||
 
 | 
			
		||||
     if (toktype == KG_TOK_SEAL_MSG) {
 | 
			
		||||
@@ -93,18 +95,23 @@ kg_unseal_v1(context, minor_status, ctx, ptr, bodysize, message_buffer,
 | 
			
		||||
         message_buffer->value = NULL;
 | 
			
		||||
     }
 | 
			
		||||
 
 | 
			
		||||
-    /* get the sign and seal algorithms */
 | 
			
		||||
-
 | 
			
		||||
-    signalg = ptr[0] + (ptr[1]<<8);
 | 
			
		||||
-    sealalg = ptr[2] + (ptr[3]<<8);
 | 
			
		||||
-
 | 
			
		||||
     /* Sanity checks */
 | 
			
		||||
 
 | 
			
		||||
-    if ((ptr[4] != 0xff) || (ptr[5] != 0xff)) {
 | 
			
		||||
+    if (ctx->seq == NULL) {
 | 
			
		||||
+        /* ctx was established using a newer enctype, and cannot process RFC
 | 
			
		||||
+         * 1964 tokens. */
 | 
			
		||||
+        *minor_status = 0;
 | 
			
		||||
+        return GSS_S_DEFECTIVE_TOKEN;
 | 
			
		||||
+    }
 | 
			
		||||
+
 | 
			
		||||
+    if ((bodysize < 22) || (ptr[4] != 0xff) || (ptr[5] != 0xff)) {
 | 
			
		||||
         *minor_status = 0;
 | 
			
		||||
         return GSS_S_DEFECTIVE_TOKEN;
 | 
			
		||||
     }
 | 
			
		||||
 
 | 
			
		||||
+    signalg = ptr[0] + (ptr[1]<<8);
 | 
			
		||||
+    sealalg = ptr[2] + (ptr[3]<<8);
 | 
			
		||||
+
 | 
			
		||||
     if ((toktype != KG_TOK_SEAL_MSG) &&
 | 
			
		||||
         (sealalg != 0xffff)) {
 | 
			
		||||
         *minor_status = 0;
 | 
			
		||||
@@ -153,6 +160,11 @@ kg_unseal_v1(context, minor_status, ctx, ptr, bodysize, message_buffer,
 | 
			
		||||
         return GSS_S_DEFECTIVE_TOKEN;
 | 
			
		||||
     }
 | 
			
		||||
 
 | 
			
		||||
+    if ((size_t)bodysize < 14 + cksum_len) {
 | 
			
		||||
+        *minor_status = 0;
 | 
			
		||||
+        return GSS_S_DEFECTIVE_TOKEN;
 | 
			
		||||
+    }
 | 
			
		||||
+
 | 
			
		||||
     /* get the token parameters */
 | 
			
		||||
 
 | 
			
		||||
     if ((code = kg_get_seq_num(context, ctx->seq, ptr+14, ptr+6, &direction,
 | 
			
		||||
@@ -207,7 +219,20 @@ kg_unseal_v1(context, minor_status, ctx, ptr, bodysize, message_buffer,
 | 
			
		||||
         plainlen = tmsglen;
 | 
			
		||||
 
 | 
			
		||||
         conflen = kg_confounder_size(context, ctx->enc->keyblock.enctype);
 | 
			
		||||
-        token.length = tmsglen - conflen - plain[tmsglen-1];
 | 
			
		||||
+        if (tmsglen < conflen) {
 | 
			
		||||
+            if (sealalg != 0xffff)
 | 
			
		||||
+                xfree(plain);
 | 
			
		||||
+            *minor_status = 0;
 | 
			
		||||
+            return(GSS_S_DEFECTIVE_TOKEN);
 | 
			
		||||
+        }
 | 
			
		||||
+        padlen = plain[tmsglen - 1];
 | 
			
		||||
+        if (tmsglen - conflen < padlen) {
 | 
			
		||||
+            /* Don't error out yet, to avoid padding oracle attacks.  We will
 | 
			
		||||
+             * treat this as a checksum failure later on. */
 | 
			
		||||
+            padlen = 0;
 | 
			
		||||
+            bad_pad = 1;
 | 
			
		||||
+        }
 | 
			
		||||
+        token.length = tmsglen - conflen - padlen;
 | 
			
		||||
 
 | 
			
		||||
         if (token.length) {
 | 
			
		||||
             if ((token.value = (void *) gssalloc_malloc(token.length)) == NULL) {
 | 
			
		||||
@@ -403,7 +428,7 @@ kg_unseal_v1(context, minor_status, ctx, ptr, bodysize, message_buffer,
 | 
			
		||||
 
 | 
			
		||||
     /* compare the computed checksum against the transmitted checksum */
 | 
			
		||||
 
 | 
			
		||||
-    if (code) {
 | 
			
		||||
+    if (code || bad_pad) {
 | 
			
		||||
         if (toktype == KG_TOK_SEAL_MSG)
 | 
			
		||||
             gssalloc_free(token.value);
 | 
			
		||||
         *minor_status = 0;
 | 
			
		||||
diff --git a/src/lib/gssapi/krb5/k5unsealiov.c b/src/lib/gssapi/krb5/k5unsealiov.c
 | 
			
		||||
index e34bda4..8d6a2da 100644
 | 
			
		||||
--- a/src/lib/gssapi/krb5/k5unsealiov.c
 | 
			
		||||
+++ b/src/lib/gssapi/krb5/k5unsealiov.c
 | 
			
		||||
@@ -69,7 +69,14 @@ kg_unseal_v1_iov(krb5_context context,
 | 
			
		||||
         return GSS_S_DEFECTIVE_TOKEN;
 | 
			
		||||
     }
 | 
			
		||||
 
 | 
			
		||||
-    if (header->buffer.length < token_wrapper_len + 14) {
 | 
			
		||||
+    if (ctx->seq == NULL) {
 | 
			
		||||
+        /* ctx was established using a newer enctype, and cannot process RFC
 | 
			
		||||
+         * 1964 tokens. */
 | 
			
		||||
+        *minor_status = 0;
 | 
			
		||||
+        return GSS_S_DEFECTIVE_TOKEN;
 | 
			
		||||
+    }
 | 
			
		||||
+
 | 
			
		||||
+    if (header->buffer.length < token_wrapper_len + 22) {
 | 
			
		||||
         *minor_status = 0;
 | 
			
		||||
         return GSS_S_DEFECTIVE_TOKEN;
 | 
			
		||||
     }
 | 
			
		||||
							
								
								
									
										10
									
								
								krb5.spec
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								krb5.spec
									
									
									
									
									
								
							@ -41,7 +41,7 @@
 | 
			
		||||
Summary: The Kerberos network authentication system
 | 
			
		||||
Name: krb5
 | 
			
		||||
Version: 1.12.1
 | 
			
		||||
Release: 9%{?dist}
 | 
			
		||||
Release: 10%{?dist}
 | 
			
		||||
# Maybe we should explode from the now-available-to-everybody tarball instead?
 | 
			
		||||
# http://web.mit.edu/kerberos/dist/krb5/1.12/krb5-1.12.1-signed.tar
 | 
			
		||||
Source0: krb5-%{version}.tar.gz
 | 
			
		||||
@ -104,6 +104,8 @@ Patch142: krb5-master-move-otp-sockets.patch
 | 
			
		||||
Patch143: krb5-master-spnego-preserve-oid.patch
 | 
			
		||||
Patch144: krb5-1.12-tcl86.patch
 | 
			
		||||
Patch145: krb5-master-mechd.patch
 | 
			
		||||
Patch146: krb5-1.12-CVE-2014-4341_4342.patch
 | 
			
		||||
Patch147: krb5-1.12-CVE-2014-4341_4342-tests.patch
 | 
			
		||||
Patch201: 0001-Don-t-try-to-stat-not-on-disk-ccache-residuals.patch
 | 
			
		||||
Patch202: 0002-Use-an-in-memory-cache-until-we-need-the-target-s.patch
 | 
			
		||||
Patch203: 0003-Learn-to-destroy-the-ccache-we-re-copying-from.patch
 | 
			
		||||
@ -356,6 +358,8 @@ ln -s NOTICE LICENSE
 | 
			
		||||
%patch143 -p1 -b .spnego-preserve-oid
 | 
			
		||||
%patch144 -p1 -b .tcl86
 | 
			
		||||
%patch145 -p1 -b .master-mechd
 | 
			
		||||
%patch146 -p1 -b .CVE-2014-4341_4342
 | 
			
		||||
%patch147 -p1 -b .CVE-2014-4341_4342
 | 
			
		||||
 | 
			
		||||
# Take the execute bit off of documentation.
 | 
			
		||||
chmod -x doc/krb5-protocol/*.txt doc/ccapi/*.html
 | 
			
		||||
@ -1030,6 +1034,10 @@ exit 0
 | 
			
		||||
%{_sbindir}/uuserver
 | 
			
		||||
 | 
			
		||||
%changelog
 | 
			
		||||
* Mon Jul  7 2014 Nalin Dahyabhai <nalin@redhat.com> - 1.12.1-10
 | 
			
		||||
- pull in fix for denial of service by injection of malformed GSSAPI tokens
 | 
			
		||||
  (CVE-2014-4341, CVE-2014-4342, #1116181)
 | 
			
		||||
 | 
			
		||||
* Tue Jun 24 2014 Nalin Dahyabhai <nalin@redhat.com> - 1.12.1-9
 | 
			
		||||
- pull in changes from upstream which add processing of the contents of
 | 
			
		||||
  /etc/gss/mech.d/*.conf when loading GSS modules (#1102839)
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user