is krb5_cc_initialize() thread safe
Ken Hornstein
kenh at cmf.nrl.navy.mil
Thu Feb 20 18:21:44 EST 2025
>I haven't been able to find in documentation whether or not
>krb5_cc_initialize() is thread safe? From a practical point of view, I
>believe it is not. But a call to "krb5_is_thread_safe() returns true".
>
>In NFS's gssd implementation, while trying to refresh credentials, the
>code tries to store creds and as part of calls into
>krb5_cc_initialize() to initial credential cache (of either FILE or
>MEMORY type). We've observed that if two threads try to update the
>same cache and thus call into krb5_cc_initialize(), one succeeds and
>the other fails with "Internal credentials cache error". Is that
>unexpected?
It sure seems like it's supposed to be thread safe. On a relatively
modern MIT Kerberos, in krb5_mcc_initialize() (the initialize function
for the MEMORY cache):
k5_cc_mutex_lock(context, &d->lock);
ret = init_mcc_cache(context, d, princ);
k5_cc_mutex_unlock(context, &d->lock);
But digging into this further, the only way init_mcc_cache() can fail
is if krb5_copy_principal() fails, and there's no way that can return
"Internal credential cache error". So if you're really getting that
from a MEMORY cache, I don't see how that's possible (it doesn't seem
like there is any code in the memory cache that returns that error).
In fcc_initialize() (the equivalent function for the FILE cache) the
whole function has a krb5_cc_mutex_lock()/krb5_cc_mutex_unlock() around
the guts of the function, and the actual cache file is locked as well.
The FILE cache code can return KRB5_FCC_INTERNAL, but only if a system
call returns a set of specific error codes, which right now are:
a
case EINVAL:
case EEXIST:
case EFAULT:
case EBADF:
#ifdef EWOULDBLOCK
case EWOULDBLOCK:
#endif
ret = KRB5_FCC_INTERNAL;
--Ken
More information about the krbdev
mailing list