24299872 libkrb5.so.3.3: k5_expand_path_tokens_extra causes krb5_kt_resolve to dump core
authorWill Fiveash <will.fiveash@oracle.com>
Fri, 22 Jul 2016 15:56:26 -0500
changeset 6456 d36228d1492b
parent 6455 77bad084980c
child 6457 c93341f8b028
24299872 libkrb5.so.3.3: k5_expand_path_tokens_extra causes krb5_kt_resolve to dump core
components/krb5/patches/072-client-keytab-fix.patch
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/krb5/patches/072-client-keytab-fix.patch	Fri Jul 22 15:56:26 2016 -0500
@@ -0,0 +1,135 @@
+#
+# Patch to fix the issue where the token expansion for the default client
+# keytab path could fail and cause a core dump.  Now the error is returned to
+# krb5_kt_client_default() but in order for acquire_init_cred() to function
+# properly it has to ignore the error returned by krb5_kt_client_default().
+# This in turn means that a NULL value in the client_keytab field of a cred
+# struct must be handled appropriately.
+#
+# I have submitted a pull request to MIT with these changes
+# https://github.com/krb5/krb5/pull/487
+# The final commit was
+# https://github.com/krb5/krb5/commit/bd2c2a02e22c609b3c7e9f92d6634e151d14e478
+#
+# Also note that the fix to src/lib/krb5/os/expand_path.c was handled by MIT
+# via ticket 8455 k5_expand_path_tokens_extra() always returns 0 even if
+# expand_token() fails which was integrated in MIT v1.14.3.
+#
+# Patch source: in-house
+#
+
+diff -ur krb5-1.14.2/src/include/k5-trace.h krb5-1.14.2-patched/src/include/k5-trace.h
+--- krb5-1.14.2/src/include/k5-trace.h
++++ krb5-1.14.2-patched/src/include/k5-trace.h
[email protected]@ -180,6 +180,9 @@
+ #define TRACE_GIC_PWD_MASTER(c)                         \
+     TRACE(c, "Retrying AS request with master KDC")
+ 
++#define TRACE_GSS_CLIENT_KEYTAB_FAIL(c, ret)                            \
++    TRACE(c, "Unable to resolve default client keytab: {kerr}", ret)
++
+ #define TRACE_ENCTYPE_LIST_UNKNOWN(c, profvar, name)                    \
+     TRACE(c, "Unrecognized enctype name in {str}: {str}", profvar, name)
+ 
+diff -ur krb5-1.14.2/src/lib/gssapi/krb5/acquire_cred.c krb5-1.14.2-patched/src/lib/gssapi/krb5/acquire_cred.c
+--- krb5-1.14.2/src/lib/gssapi/krb5/acquire_cred.c
++++ krb5-1.14.2-patched/src/lib/gssapi/krb5/acquire_cred.c
[email protected]@ -348,6 +348,9 @@
+     if (cred->password != NULL)
+         return TRUE;
+ 
++    if (cred->client_keytab == NULL)
++        return FALSE;
++
+     /* If we don't know the client principal yet, check for any keytab keys. */
+     if (cred->name == NULL)
+         return !krb5_kt_have_content(context, cred->client_keytab);
[email protected]@ -522,6 +525,10 @@
+     krb5_principal princ;
+ 
+     assert(cred->name == NULL);
++
++    if (cred->client_keytab == NULL)
++        return KRB5_KT_NOTFOUND;
++
+     code = k5_kt_get_principal(context, cred->client_keytab, &princ);
+     if (code)
+         return code;
[email protected]@ -601,9 +608,11 @@
+         code = krb5_get_init_creds_password(context, &creds, cred->name->princ,
+                                             cred->password, NULL, NULL, 0,
+                                             NULL, opt);
+-    } else {
++    } else if (cred->client_keytab != NULL) {
+         code = krb5_get_init_creds_keytab(context, &creds, cred->name->princ,
+                                           cred->client_keytab, 0, NULL, opt);
++    } else {
++        code = KRB5_KT_NOTFOUND;
+     }
+     if (code)
+         goto cleanup;
[email protected]@ -680,10 +689,18 @@
+             goto error;
+     }
+ 
+-    if (client_keytab != NULL)
++    if (client_keytab != NULL) {
+         code = krb5_kt_dup(context, client_keytab, &cred->client_keytab);
+-    else
++    } else {
+         code = krb5_kt_client_default(context, &cred->client_keytab);
++        if (code) {
++            /* Treat resolution failure similarly to a client keytab which
++             * resolves but doesn't exist or has no content. */
++            TRACE_GSS_CLIENT_KEYTAB_FAIL(context, code);
++            krb5_clear_error_message(context);
++            code = 0;
++        }
++    }
+     if (code)
+         goto error;
+ 
+diff -ur krb5-1.14.2/src/lib/gssapi/krb5/iakerb.c krb5-1.14.2-patched/src/lib/gssapi/krb5/iakerb.c
+--- krb5-1.14.2/src/lib/gssapi/krb5/iakerb.c
++++ krb5-1.14.2-patched/src/lib/gssapi/krb5/iakerb.c
[email protected]@ -454,9 +454,11 @@
+     if (cred->password != NULL) {
+         code = krb5_init_creds_set_password(ctx->k5c, ctx->icc,
+                                             cred->password);
+-    } else {
++    } else if (cred->client_keytab != NULL) {
+         code = krb5_init_creds_set_keytab(ctx->k5c, ctx->icc,
+                                           cred->client_keytab);
++    } else {
++        code = KRB5_KT_NOTFOUND;
+     }
+     if (code != 0)
+         goto cleanup;
+diff -ur krb5-1.14.2/src/lib/krb5/os/expand_path.c krb5-1.14.2-patched/src/lib/krb5/os/expand_path.c
+--- krb5-1.14.2/src/lib/krb5/os/expand_path.c
++++ krb5-1.14.2-patched/src/lib/krb5/os/expand_path.c
[email protected]@ -537,5 +537,5 @@
+ cleanup:
+     k5_buf_free(&buf);
+     free_extra_tokens(extra_tokens);
+-    return 0;
++    return ret;
+ }
+diff -ur krb5-1.14.2/src/tests/gssapi/t_client_keytab.py krb5-1.14.2-patched/src/tests/gssapi/t_client_keytab.py
+--- krb5-1.14.2/src/tests/gssapi/t_client_keytab.py
++++ krb5-1.14.2-patched/src/tests/gssapi/t_client_keytab.py
[email protected]@ -141,4 +141,14 @@
+     fail('Expected error not seen')
+ realm.run([kdestroy, '-A'])
+ 
++# Test 16: default client keytab cannot be resolved, but valid
++# credentials exist in ccache.
++conf = {'libdefaults': {'default_client_keytab_name': '%{'}}
++bad_cktname = realm.special_env('bad_cktname', False, krb5_conf=conf)
++del bad_cktname['KRB5_CLIENT_KTNAME']
++realm.kinit(realm.user_princ, password('user'))
++out = realm.run(['./t_ccselect', phost], env=bad_cktname)
++if realm.user_princ not in out:
++    fail('Expected principal not seen for bad client keytab name')
++
+ success('Client keytab tests')