File 0100-Fix-build_principal-memory-bug-CVE-2015-2697.patch of Package krb5.openSUSE_13.1_Update
From f0c094a1b745d91ef2f9a4eae2149aac026a5789 Mon Sep 17 00:00:00 2001
From: Greg Hudson <ghudson@mit.edu>
Date: Fri, 25 Sep 2015 12:51:47 -0400
Subject: [PATCH] Fix build_principal memory bug [CVE-2015-2697]
In build_principal_va(), use k5memdup0() instead of strdup() to make a
copy of the realm, to ensure that we allocate the correct number of
bytes and do not read past the end of the input string. This bug
affects krb5_build_principal(), krb5_build_principal_va(), and
krb5_build_principal_alloc_va(). krb5_build_principal_ext() is not
affected.
CVE-2015-2697:
In MIT krb5 1.7 and later, an authenticated attacker may be able to
cause a KDC to crash using a TGS request with a large realm field
beginning with a null byte. If the KDC attempts to find a referral to
answer the request, it constructs a principal name for lookup using
krb5_build_principal() with the requested realm. Due to a bug in this
function, the null byte causes only one byte be allocated for the
realm field of the constructed principal, far less than its length.
Subsequent operations on the lookup principal may cause a read beyond
the end of the mapped memory region, causing the KDC process to crash.
CVSSv2: AV:N/AC:L/Au:S/C:N/I:N/A:C/E:POC/RL:OF/RC:C
ticket: 8252 (new)
target_version: 1.14
tags: pullup
Some new functions are picked from other commits by Howard Guo <hguo@suse.com> in order to adapt this patch.
diff -rupN krb5-1.11.3/src/include/k5-int.h krb5-1.11.3-patched/src/include/k5-int.h
--- krb5-1.11.3/src/include/k5-int.h 2015-10-29 14:25:59.712169789 +0100
+++ krb5-1.11.3-patched/src/include/k5-int.h 2015-10-29 14:29:17.721008181 +0100
@@ -2591,16 +2591,34 @@ authdata_eq(krb5_authdata a1, krb5_authd
/* Allocate zeroed memory; set *code to 0 on success or ENOMEM on failure. */
static inline void *
-k5alloc(size_t len, krb5_error_code *code)
+k5calloc(size_t nmemb, size_t size, krb5_error_code *code)
{
void *ptr;
/* Allocate at least one byte since zero-byte allocs may return NULL. */
- ptr = calloc((len > 0) ? len : 1, 1);
+ ptr = calloc(nmemb ? nmemb : 1, size ? size : 1);
*code = (ptr == NULL) ? ENOMEM : 0;
return ptr;
}
+/* Allocate zeroed memory; set *code to 0 on success or ENOMEM on failure. */
+static inline void *
+k5alloc(size_t size, krb5_error_code *code)
+{
+ return k5calloc(1, size, code);
+}
+
+/* Like k5memdup, but add a final null byte. */
+static inline void *
+k5memdup0(const void *in, size_t len, krb5_error_code *code)
+{
+ void *ptr = k5alloc(len + 1, code);
+
+ if (ptr != NULL && len > 0)
+ memcpy(ptr, in, len);
+ return ptr;
+}
+
krb5_error_code KRB5_CALLCONV
krb5_get_credentials_for_user(krb5_context context, krb5_flags options,
krb5_ccache ccache,
diff -rupN krb5-1.11.3/src/lib/krb5/krb/bld_princ.c krb5-1.11.3-patched/src/lib/krb5/krb/bld_princ.c
--- krb5-1.11.3/src/lib/krb5/krb/bld_princ.c 2015-10-29 14:25:59.728169856 +0100
+++ krb5-1.11.3-patched/src/lib/krb5/krb/bld_princ.c 2015-10-29 14:30:30.741323091 +0100
@@ -41,10 +41,8 @@ build_principal_va(krb5_context context,
data = malloc(size * sizeof(krb5_data));
if (!data) { retval = ENOMEM; }
- if (!retval) {
- r = strdup(realm);
- if (!r) { retval = ENOMEM; }
- }
+ if (!retval)
+ r = k5memdup0(realm, rlen, &retval);
while (!retval && (component = va_arg(ap, char *))) {
if (count == size) {