From d40593be83144713cfc43e4eb1c7bc2d925a0da0 Mon Sep 17 00:00:00 2001
From: Joseph Sutton <josephsutton@catalyst.net.nz>
Date: Wed, 25 May 2022 20:00:55 +1200
Subject: [PATCH 88/99] CVE-2022-2031 s4:kdc: Don't use strncmp to compare
 principal components

We would only compare the first 'n' characters, where 'n' is the length
of the principal component string, so 'k@REALM' would erroneously be
considered equal to 'krbtgt@REALM'.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=15047

Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz>
Reviewed-by: Andreas Schneider <asn@samba.org>

Conflict: remove selftest/knownfail_heimdal_kdc selftest/knownfail_mit_kdc
---
 source4/kdc/db-glue.c          | 27 ++++++++++++++++++++++-----
 3 files changed, 22 insertions(+), 13 deletions(-)

diff --git a/source4/kdc/db-glue.c b/source4/kdc/db-glue.c
index 073ec83c8cf..cfa2097acbd 100644
--- a/source4/kdc/db-glue.c
+++ b/source4/kdc/db-glue.c
@@ -769,15 +769,19 @@ static int principal_comp_strcmp_int(krb5_context context,
 				     bool do_strcasecmp)
 {
 	const char *p;
-	size_t len;
 
 #if defined(HAVE_KRB5_PRINCIPAL_GET_COMP_STRING)
 	p = krb5_principal_get_comp_string(context, principal, component);
 	if (p == NULL) {
 		return -1;
 	}
-	len = strlen(p);
+	if (do_strcasecmp) {
+		return strcasecmp(p, string);
+	} else {
+		return strcmp(p, string);
+	}
 #else
+	size_t len;
 	krb5_data *d;
 	if (component >= krb5_princ_size(context, principal)) {
 		return -1;
@@ -789,13 +793,26 @@ static int principal_comp_strcmp_int(krb5_context context,
 	}
 
 	p = d->data;
-	len = d->length;
-#endif
+
+	len = strlen(string);
+
+	/*
+	 * We explicitly return -1 or 1. Subtracting of the two lengths might
+	 * give the wrong result if the result overflows or loses data when
+	 * narrowed to int.
+	 */
+	if (d->length < len) {
+		return -1;
+	} else if (d->length > len) {
+		return 1;
+	}
+
 	if (do_strcasecmp) {
 		return strncasecmp(p, string, len);
 	} else {
-		return strncmp(p, string, len);
+		return memcmp(p, string, len);
 	}
+#endif
 }
 
 static int principal_comp_strcasecmp(krb5_context context,
-- 
2.25.1
