Code: find_alternate_tgs(kdc_realm_t *kdc_active_realm, krb5_principal princ,
                   krb5_db_entry **server_ptr, const char **status)
{
    krb5_error_code retval;
    krb5_principal *plist = NULL, *pl2;
    krb5_data tmp;
    krb5_db_entry *server = NULL;

    *server_ptr = NULL;
    assert(is_cross_tgs_principal(princ));
    if ((retval = krb5_walk_realm_tree(kdc_context,
                                       krb5_princ_realm(kdc_context, princ),
                                       krb5_princ_component(kdc_context, princ, 1),
                                       &plist, KRB5_REALM_BRANCH_CHAR))) {
        goto cleanup;
    }
    /* move to the end */
    for (pl2 = plist; *pl2; pl2++);

    /* the first entry in this array is for krbtgt/local@local, so we
       ignore it */
    while (--pl2 > plist) {
        tmp = *krb5_princ_realm(kdc_context, *pl2);
        krb5_princ_set_realm(kdc_context, *pl2,
                             krb5_princ_realm(kdc_context, tgs_server));
        retval = db_get_svc_princ(kdc_context, *pl2, 0, &server, status);
        krb5_princ_set_realm(kdc_context, *pl2, &tmp);
        if (retval == KRB5_KDB_NOENTRY)
            continue;
        else if (retval)
            goto cleanup;

        log_tgs_alt_tgt(kdc_context, server->princ);
        *server_ptr = server;
        server = NULL;
         goto cleanup;
     }
 cleanup:
     if (retval != 0)
         *status = "UNKNOWN_SERVER";
 
    krb5_free_realm_tree(kdc_context, plist);
    krb5_db_free_principal(kdc_context, server);
    return retval;
}

Vulnerability Type: DoS 
CWE ID: CWE-20
Summary: do_tgs_req.c in the Key Distribution Center (KDC) in MIT Kerberos 5 (aka krb5) 1.11 before 1.11.4, when a single-component realm name is used, allows remote authenticated users to cause a denial of service (daemon crash) via a TGS-REQ request that triggers an attempted cross-realm referral for a host-based service principal.
Commit Message: KDC null deref due to referrals [CVE-2013-1417]

An authenticated remote client can cause a KDC to crash by making a
valid TGS-REQ to a KDC serving a realm with a single-component name.
The process_tgs_req() function dereferences a null pointer because an
unusual failure condition causes a helper function to return success.

While attempting to provide cross-realm referrals for host-based
service principals, the find_referral_tgs() function could return a
TGS principal for a zero-length realm name (indicating that the
hostname in the service principal has no known realm associated with
it).

Subsequently, the find_alternate_tgs() function would attempt to
construct a path to this empty-string realm, and return success along
with a null pointer in its output parameter.  This happens because
krb5_walk_realm_tree() returns a list of length one when it attempts
to construct a transit path between a single-component realm and the
empty-string realm.  This list causes a loop in find_alternate_tgs()
to iterate over zero elements, resulting in the unexpected output of a
null pointer, which process_tgs_req() proceeds to dereference because
there is no error condition.

Add an error condition to find_referral_tgs() when
krb5_get_host_realm() returns an empty realm name.  Also add an error
condition to find_alternate_tgs() to handle the length-one output from
krb5_walk_realm_tree().

The vulnerable configuration is not likely to arise in practice.
(Realm names that have a single component are likely to be test
realms.)  Releases prior to krb5-1.11 are not vulnerable.

Thanks to Sol Jerome for reporting this problem.

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

(cherry picked from commit 3c7f1c21ffaaf6c90f1045f0f5440303c766acc0)

ticket: 7668
version_fixed: 1.11.4
status: resolved