krb5 commit [krb5-1.11]: Handle invalid RFC 1964 tokens [CVE-2014-4341...]

Tom Yu tlyu at mit.edu
Fri Feb 6 18:11:51 EST 2015


https://github.com/krb5/krb5/commit/8a9a2d09c93b55ad0dbdd16ae36e952a04f27466
commit 8a9a2d09c93b55ad0dbdd16ae36e952a04f27466
Author: Greg Hudson <ghudson at 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 at mit.edu: CVE summaries, CVSS]
    
    (cherry picked from commit fb99962cbd063ac04c9a9d2cc7c75eab73f3533d)
    
    ticket: 8108 (new)
    subject: Handle invalid RFC 1964 tokens [CVE-2014-4341 CVE-2014-4342]
    version_fixed: 1.11.6
    status: resolved

 src/lib/gssapi/krb5/k5unseal.c    |   41 +++++++++++++++++++++++++++++-------
 src/lib/gssapi/krb5/k5unsealiov.c |    9 +++++++-
 2 files changed, 41 insertions(+), 9 deletions(-)

diff --git a/src/lib/gssapi/krb5/k5unseal.c b/src/lib/gssapi/krb5/k5unseal.c
index fa9a3cb..a6d456d 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 87fe34f..9f7f880 100644
--- a/src/lib/gssapi/krb5/k5unsealiov.c
+++ b/src/lib/gssapi/krb5/k5unsealiov.c
@@ -71,7 +71,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;
     }


More information about the cvs-krb5 mailing list