[31673] in CVS-changelog-for-Kerberos-V5

home help back first fref pref prev next nref lref last post

krb5 commit [krb5-1.22]: Avoid repeated reallocation when decoding

daemon@ATHENA.MIT.EDU (ghudson@mit.edu)
Mon Nov 9 12:02:08 2026

From: ghudson@mit.edu
To: cvs-krb5@mit.edu
Message-Id: <20261109170157.BFA54105839@krbdev.mit.edu>
Date: Mon,  9 Nov 2026 12:01:57 -0500 (EST)
MIME-Version: 1.0
Reply-To: krbdev@mit.edu
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: 7bit
Errors-To: cvs-krb5-bounces@mit.edu

https://github.com/krb5/krb5/commit/205832663330da308d9d031a17326b68a16715fd
commit 205832663330da308d9d031a17326b68a16715fd
Author: Greg Hudson <ghudson@mit.edu>
Date:   Tue Oct 20 12:59:08 2026 -0400

    Avoid repeated reallocation when decoding ASN.1
    
    In decode_sequence_of(), make a first pass over the tags to count and
    validate the elements, allowing the array to be allocated once instead
    of reallocated for each element.
    
    CVE-2026-119079:
    
    In MIT krb5 release 1.11 and later, an unauthenticated attacker can
    cause the KDC or an application server to consume a large amount of
    CPU time decoding ASN.1 protocol elements by sending a long sequence.
    
    (cherry picked from commit 782e5ac4fb1496a79de0b87e1fc485f897e97d6d)
    
    ticket: 9266
    version_fixed: 1.22.3

 src/lib/krb5/asn.1/asn1_encode.c | 38 ++++++++++++++++++++------------------
 1 file changed, 20 insertions(+), 18 deletions(-)

diff --git a/src/lib/krb5/asn.1/asn1_encode.c b/src/lib/krb5/asn.1/asn1_encode.c
index c4140021e..c438f57d2 100644
--- a/src/lib/krb5/asn.1/asn1_encode.c
+++ b/src/lib/krb5/asn.1/asn1_encode.c
@@ -1460,40 +1460,42 @@ decode_sequence_of(const uint8_t *asn1, size_t len,
                    size_t *count_out)
 {
     krb5_error_code ret;
-    void *seq = NULL, *elem, *newseq;
-    const uint8_t *contents;
-    size_t clen, count = 0;
+    void *seq = NULL, *elem;
+    const uint8_t *p, *contents;
+    size_t l, clen, count = 0, n = 0;
     taginfo t;
 
     *seq_out = NULL;
     *count_out = 0;
-    while (len > 0) {
+
+    /* Count the elements in the sequence and check their tags. */
+    for (p = asn1, l = len, count = 0; l > 0; count++) {
+        ret = get_tag(p, l, &t, &contents, &clen, &p, &l);
+        if (ret)
+            return ret;
+        if (!check_atype_tag(elemtype, &t))
+            return ASN1_BAD_ID;
+    }
+
+    seq = k5calloc(count, elemtype->size, &ret);
+    if (seq == NULL)
+        return ret;
+
+    for (n = 0; n < count; n++) {
         ret = get_tag(asn1, len, &t, &contents, &clen, &asn1, &len);
         if (ret)
             goto error;
-        if (!check_atype_tag(elemtype, &t)) {
-            ret = ASN1_BAD_ID;
-            goto error;
-        }
-        newseq = realloc(seq, (count + 1) * elemtype->size);
-        if (newseq == NULL) {
-            ret = ENOMEM;
-            goto error;
-        }
-        seq = newseq;
-        elem = (char *)seq + count * elemtype->size;
-        memset(elem, 0, elemtype->size);
+        elem = (char *)seq + n * elemtype->size;
         ret = decode_atype(&t, contents, clen, elemtype, elem);
         if (ret)
             goto error;
-        count++;
     }
     *seq_out = seq;
     *count_out = count;
     return 0;
 
 error:
-    free_sequence_of(elemtype, seq, count);
+    free_sequence_of(elemtype, seq, n);
     free(seq);
     return ret;
 }
_______________________________________________
cvs-krb5 mailing list
cvs-krb5@mit.edu
https://mailman.mit.edu/mailman/listinfo/cvs-krb5

home help back first fref pref prev next nref lref last post