Vulnerability: The prep_reprocess_req function in do_tgs_req.c in the Key Distribution Center (KDC) in MIT Kerberos 5 (aka krb5) before 1.10.5 does not properly perform service-principal realm referral, which allows remote authenticated users to cause a denial of service (NULL pointer dereference and daemon crash) via a crafted TGS-REQ request.
Vulnerability ID: CVE-2013-1416
CWE: CWE-476
Severity score: 2.9
Project: https://github.com/krb5/krb5
Published: 2013-04-19
File: src/kdc/do_tgs_req.c
Commit message: KDC TGS-REQ null deref [CVE-2013-1416]

By sending an unusual but valid TGS-REQ, an authenticated remote
attacker can cause the KDC process to crash by dereferencing a null
pointer.

prep_reprocess_req() can cause a null pointer dereference when
processing a service principal name.  Code in this function can
inappropriately pass a null pointer to strlcpy().  Unmodified client
software can trivially trigger this vulnerability, but the attacker
must have already authenticated and received a valid Kerberos ticket.

The vulnerable code was introduced by the implementation of new
service principal realm referral functionality in krb5-1.7, but was
corrected as a side effect of the KDC refactoring in krb5-1.11.

CVSSv2 vector: AV:N/AC:L/Au:S/C:N/I:N/A:C/E:H/RL:O/RC:C

ticket: 7600 (new)
version_fixed: 1.10.5
status: resolved
Commit author: Tom Yu

Vulnerable version (before fix):
 prep_reprocess_req(krb5_kdc_req *request, krb5_principal *krbtgt_princ)             retval = ENOMEM;             goto cleanup;         }         strlcpy(comp1_str,comp1->data,comp1->length+1);          if ((krb5_princ_type(kdc_context, request->server) == KRB5_NT_SRV_HST ||              krb5_princ_type(kdc_context, request->server) == KRB5_NT_SRV_INST || prep_reprocess_req(krb5_kdc_req *request, krb5_principal *krbtgt_princ)                 retval = ENOMEM;                 goto cleanup;             }             strlcpy(temp_buf, comp2->data,comp2->length+1);             retval = krb5int_get_domain_realm_mapping(kdc_context, temp_buf, &realms);             free(temp_buf);             if (retval) {

Fixed version (after fix):
 prep_reprocess_req(krb5_kdc_req *request, krb5_principal *krbtgt_princ)             retval = ENOMEM;             goto cleanup;         }         if (comp1->data != NULL)             memcpy(comp1_str, comp1->data, comp1->length);          if ((krb5_princ_type(kdc_context, request->server) == KRB5_NT_SRV_HST ||              krb5_princ_type(kdc_context, request->server) == KRB5_NT_SRV_INST || prep_reprocess_req(krb5_kdc_req *request, krb5_principal *krbtgt_princ)                 retval = ENOMEM;                 goto cleanup;             }             if (comp2->data != NULL)                 memcpy(temp_buf, comp2->data, comp2->length);             retval = krb5int_get_domain_realm_mapping(kdc_context, temp_buf, &realms);             free(temp_buf);             if (retval) {

Patch:
patch: @@ -1141,7 +1141,8 @@ prep_reprocess_req(krb5_kdc_req *request, krb5_principal *krbtgt_princ)
             retval = ENOMEM;
             goto cleanup;
         }
-        strlcpy(comp1_str,comp1->data,comp1->length+1);
+        if (comp1->data != NULL)
+            memcpy(comp1_str, comp1->data, comp1->length);
 
         if ((krb5_princ_type(kdc_context, request->server) == KRB5_NT_SRV_HST ||
              krb5_princ_type(kdc_context, request->server) == KRB5_NT_SRV_INST ||
@@ -1164,7 +1165,8 @@ prep_reprocess_req(krb5_kdc_req *request, krb5_principal *krbtgt_princ)
                 retval = ENOMEM;
                 goto cleanup;
             }
-            strlcpy(temp_buf, comp2->data,comp2->length+1);
+            if (comp2->data != NULL)
+                memcpy(temp_buf, comp2->data, comp2->length);
             retval = krb5int_get_domain_realm_mapping(kdc_context, temp_buf, &realms);
             free(temp_buf);
             if (retval) {
path: src/kdc/do_tgs_req.c