is krb5_cc_initialize() thread safe

Olga Kornievskaia aglo at umich.edu
Thu Feb 20 19:31:49 EST 2025


On Thu, Feb 20, 2025 at 6:21 PM Ken Hornstein <kenh at cmf.nrl.navy.mil> wrote:
>
> >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,

In my testing I've had gssd setup use the "default" ccache type which
is FILE. I haven't tried if setting it use_memory (switching to
MEMORY) works better. But regardless, gssd needs to do something
"better" for the case of FILE credential type and I'm trying to figure
out what that should be.

> 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