Blame SOURCES/Fix-segfault-in-finish_dispatch.patch

665228
From eb58cafce36423ece63a4c1b503a965b38527171 Mon Sep 17 00:00:00 2001
665228
From: Robbie Harwood <rharwood@redhat.com>
665228
Date: Wed, 18 Apr 2018 14:13:28 -0400
665228
Subject: [PATCH] Fix segfault in finish_dispatch()
665228
665228
dispatch() doesn't necessarily initialize state->active_realm which
665228
led to an explicit NULL dereference in finish_dispatch().
665228
665228
Additionally, fix make_too_big_error() so that it won't subsequently
665228
dereference state->active_realm.
665228
665228
tags: pullup
665228
target_version: 1.16-next
665228
target_version: 1.15-next
665228
665228
(cherry picked from commit c822bacc1b33970a2a20d9eae80f43307e783516)
665228
---
665228
 src/kdc/dispatch.c | 79 ++++++++++++++++++++++++----------------------
665228
 1 file changed, 42 insertions(+), 37 deletions(-)
665228
665228
diff --git a/src/kdc/dispatch.c b/src/kdc/dispatch.c
665228
index 4ecc23481..1f4b70874 100644
665228
--- a/src/kdc/dispatch.c
665228
+++ b/src/kdc/dispatch.c
665228
@@ -35,9 +35,6 @@
665228
 
665228
 static krb5_int32 last_usec = 0, last_os_random = 0;
665228
 
665228
-static krb5_error_code make_too_big_error(kdc_realm_t *kdc_active_realm,
665228
-                                          krb5_data **out);
665228
-
665228
 struct dispatch_state {
665228
     loop_respond_fn respond;
665228
     void *arg;
665228
@@ -47,6 +44,41 @@ struct dispatch_state {
665228
     krb5_context kdc_err_context;
665228
 };
665228
 
665228
+
665228
+static krb5_error_code
665228
+make_too_big_error(krb5_context context, krb5_principal tgsprinc,
665228
+                   krb5_data **out)
665228
+{
665228
+    krb5_error errpkt;
665228
+    krb5_error_code retval;
665228
+    krb5_data *scratch;
665228
+
665228
+    *out = NULL;
665228
+    memset(&errpkt, 0, sizeof(errpkt));
665228
+
665228
+    retval = krb5_us_timeofday(context, &errpkt.stime, &errpkt.susec);
665228
+    if (retval)
665228
+        return retval;
665228
+    errpkt.error = KRB_ERR_RESPONSE_TOO_BIG;
665228
+    errpkt.server = tgsprinc;
665228
+    errpkt.client = NULL;
665228
+    errpkt.text.length = 0;
665228
+    errpkt.text.data = 0;
665228
+    errpkt.e_data.length = 0;
665228
+    errpkt.e_data.data = 0;
665228
+    scratch = malloc(sizeof(*scratch));
665228
+    if (scratch == NULL)
665228
+        return ENOMEM;
665228
+    retval = krb5_mk_error(context, &errpkt, scratch);
665228
+    if (retval) {
665228
+        free(scratch);
665228
+        return retval;
665228
+    }
665228
+
665228
+    *out = scratch;
665228
+    return 0;
665228
+}
665228
+
665228
 static void
665228
 finish_dispatch(struct dispatch_state *state, krb5_error_code code,
665228
                 krb5_data *response)
665228
@@ -54,12 +86,17 @@ finish_dispatch(struct dispatch_state *state, krb5_error_code code,
665228
     loop_respond_fn oldrespond = state->respond;
665228
     void *oldarg = state->arg;
665228
     kdc_realm_t *kdc_active_realm = state->active_realm;
665228
+    krb5_principal tgsprinc = NULL;
665228
+
665228
+    if (kdc_active_realm != NULL)
665228
+        tgsprinc = kdc_active_realm->realm_tgsprinc;
665228
 
665228
     if (state->is_tcp == 0 && response &&
665228
         response->length > (unsigned int)max_dgram_reply_size) {
665228
-        krb5_free_data(kdc_context, response);
665228
+        krb5_free_data(state->kdc_err_context, response);
665228
         response = NULL;
665228
-        code = make_too_big_error(kdc_active_realm, &response);
665228
+        code = make_too_big_error(state->kdc_err_context, tgsprinc,
665228
+                                  &response);
665228
         if (code)
665228
             krb5_klog_syslog(LOG_ERR, "error constructing "
665228
                              "KRB_ERR_RESPONSE_TOO_BIG error: %s",
665228
@@ -201,38 +238,6 @@ dispatch(void *cb, struct sockaddr *local_saddr,
665228
     finish_dispatch_cache(state, retval, response);
665228
 }
665228
 
665228
-static krb5_error_code
665228
-make_too_big_error(kdc_realm_t *kdc_active_realm, krb5_data **out)
665228
-{
665228
-    krb5_error errpkt;
665228
-    krb5_error_code retval;
665228
-    krb5_data *scratch;
665228
-
665228
-    *out = NULL;
665228
-    memset(&errpkt, 0, sizeof(errpkt));
665228
-
665228
-    retval = krb5_us_timeofday(kdc_context, &errpkt.stime, &errpkt.susec);
665228
-    if (retval)
665228
-        return retval;
665228
-    errpkt.error = KRB_ERR_RESPONSE_TOO_BIG;
665228
-    errpkt.server = tgs_server;
665228
-    errpkt.client = NULL;
665228
-    errpkt.text.length = 0;
665228
-    errpkt.text.data = 0;
665228
-    errpkt.e_data.length = 0;
665228
-    errpkt.e_data.data = 0;
665228
-    scratch = malloc(sizeof(*scratch));
665228
-    if (scratch == NULL)
665228
-        return ENOMEM;
665228
-    retval = krb5_mk_error(kdc_context, &errpkt, scratch);
665228
-    if (retval) {
665228
-        free(scratch);
665228
-        return retval;
665228
-    }
665228
-
665228
-    *out = scratch;
665228
-    return 0;
665228
-}
665228
 
665228
 krb5_context get_context(void *handle)
665228
 {