krb5 commit [krb5-1.20]: Fix integer overflows in PAC parsing

ghudson at mit.edu ghudson at mit.edu
Tue Nov 15 11:32:09 EST 2022


https://github.com/krb5/krb5/commit/b99de751dd35360c0fccac74a40f4a60dbf1ceea
commit b99de751dd35360c0fccac74a40f4a60dbf1ceea
Author: Greg Hudson <ghudson at mit.edu>
Date:   Mon Oct 17 20:25:11 2022 -0400

    Fix integer overflows in PAC parsing
    
    In krb5_parse_pac(), check for buffer counts large enough to threaten
    integer overflow in the header length and memory length calculations.
    Avoid potential integer overflows when checking the length of each
    buffer.  Credit to OSS-Fuzz for discovering one of the issues.
    
    CVE-2022-42898:
    
    In MIT krb5 releases 1.8 and later, an authenticated attacker may be
    able to cause a KDC or kadmind process to crash by reading beyond the
    bounds of allocated memory, creating a denial of service.  A
    privileged attacker may similarly be able to cause a Kerberos or GSS
    application service to crash.  On 32-bit platforms, an attacker can
    also cause insufficient memory to be allocated for the result,
    potentially leading to remote code execution in a KDC, kadmind, or GSS
    or Kerberos application server process.  An attacker with the
    privileges of a cross-realm KDC may be able to extract secrets from a
    KDC process's memory by having them copied into the PAC of a new
    ticket.
    
    (cherry picked from commit ea92d2f0fcceb54a70910fa32e9a0d7a5afc3583)
    
    ticket: 9074
    version_fixed: 1.20.1

 src/lib/krb5/krb/pac.c   |  9 +++++++--
 src/lib/krb5/krb/t_pac.c | 18 ++++++++++++++++++
 2 files changed, 25 insertions(+), 2 deletions(-)

diff --git a/src/lib/krb5/krb/pac.c b/src/lib/krb5/krb/pac.c
index 2f1df8d42..f6c4373de 100644
--- a/src/lib/krb5/krb/pac.c
+++ b/src/lib/krb5/krb/pac.c
@@ -28,6 +28,8 @@
 #include "int-proto.h"
 #include "authdata.h"
 
+#define MAX_BUFFERS 4096
+
 /* draft-brezak-win2k-krb-authz-00 */
 
 /*
@@ -317,6 +319,9 @@ krb5_pac_parse(krb5_context context,
     if (version != 0)
         return EINVAL;
 
+    if (cbuffers < 1 || cbuffers > MAX_BUFFERS)
+        return ERANGE;
+
     header_len = PACTYPE_LENGTH + (cbuffers * PAC_INFO_BUFFER_LENGTH);
     if (len < header_len)
         return ERANGE;
@@ -349,8 +354,8 @@ krb5_pac_parse(krb5_context context,
             krb5_pac_free(context, pac);
             return EINVAL;
         }
-        if (buffer->Offset < header_len ||
-            buffer->Offset + buffer->cbBufferSize > len) {
+        if (buffer->Offset < header_len || buffer->Offset > len ||
+            buffer->cbBufferSize > len - buffer->Offset) {
             krb5_pac_free(context, pac);
             return ERANGE;
         }
diff --git a/src/lib/krb5/krb/t_pac.c b/src/lib/krb5/krb/t_pac.c
index 0b1b1f056..173bde7ba 100644
--- a/src/lib/krb5/krb/t_pac.c
+++ b/src/lib/krb5/krb/t_pac.c
@@ -431,6 +431,16 @@ static const unsigned char s4u_pac_ent_xrealm[] = {
     0x8a, 0x81, 0x9c, 0x9c, 0x00, 0x00, 0x00, 0x00
 };
 
+static const unsigned char fuzz1[] = {
+    0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,
+    0x06, 0xff, 0xff, 0xff, 0x00, 0x00, 0xf5
+};
+
+static const unsigned char fuzz2[] = {
+    0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00,
+    0x20, 0x20
+};
+
 static const char *s4u_principal = "w2k8u at ACME.COM";
 static const char *s4u_enterprise = "w2k8u at abc@ACME.COM";
 
@@ -828,6 +838,14 @@ main(int argc, char **argv)
         krb5_free_principal(context, sep);
     }
 
+    /* Check problematic PACs found by fuzzing. */
+    ret = krb5_pac_parse(context, fuzz1, sizeof(fuzz1), &pac);
+    if (!ret)
+        err(context, ret, "krb5_pac_parse should have failed");
+    ret = krb5_pac_parse(context, fuzz2, sizeof(fuzz2), &pac);
+    if (!ret)
+        err(context, ret, "krb5_pac_parse should have failed");
+
     /*
      * Test empty free
      */


More information about the cvs-krb5 mailing list