Skip to content

Commit

Permalink
Fix race condition with global _gsskrb5_keytab
Browse files Browse the repository at this point in the history
gsskrb5_acceptor_start() was making a copy of the global pointer
_gsskrb5_keytab to use later. This invites a race condition where
another thread could call gsskrb5_register_acceptor_identity()
(thus invalidating the target of the copied pointer) before it is
used by gsskrb5_acceptor_start().

So instead, clone the keytab to a new one while protected by the
mutex lock (similar to get_keytab() in acquire_cred.c).

Signed-off-by: Nicolas Williams <nico@twosigma.com>
  • Loading branch information
yaheath authored and nicowilliams committed Nov 11, 2016
1 parent ab65f51 commit 545b5b4
Showing 1 changed file with 19 additions and 2 deletions.
21 changes: 19 additions & 2 deletions lib/gssapi/krb5/accept_sec_context.c
Expand Up @@ -364,6 +364,7 @@ gsskrb5_acceptor_start(OM_uint32 * minor_status,
krb5_flags ap_options;
krb5_keytab keytab = NULL;
int is_cfx = 0;
int close_kt = 0;
const gsskrb5_cred acceptor_cred = (gsskrb5_cred)acceptor_cred_handle;

/*
Expand All @@ -385,8 +386,20 @@ gsskrb5_acceptor_start(OM_uint32 * minor_status,
* We need to get our keytab
*/
if (acceptor_cred == NULL) {
if (_gsskrb5_keytab != NULL)
keytab = _gsskrb5_keytab;
HEIMDAL_MUTEX_lock(&gssapi_keytab_mutex);
if (_gsskrb5_keytab != NULL) {
char *name = NULL;
kret = krb5_kt_get_full_name(context, _gsskrb5_keytab, &name);
if (kret == 0) {
kret = krb5_kt_resolve(context, name, &keytab);
krb5_xfree(name);
}
if (kret == 0)
close_kt = 1;
else
keytab = NULL;
}
HEIMDAL_MUTEX_unlock(&gssapi_keytab_mutex);
} else if (acceptor_cred->keytab != NULL) {
keytab = acceptor_cred->keytab;
}
Expand All @@ -409,6 +422,8 @@ gsskrb5_acceptor_start(OM_uint32 * minor_status,
if (kret) {
if (in)
krb5_rd_req_in_ctx_free(context, in);
if (close_kt)
krb5_kt_close(context, keytab);
*minor_status = kret;
return GSS_S_FAILURE;
}
Expand All @@ -419,6 +434,8 @@ gsskrb5_acceptor_start(OM_uint32 * minor_status,
server,
in, &out);
krb5_rd_req_in_ctx_free(context, in);
if (close_kt)
krb5_kt_close(context, keytab);
if (kret == KRB5KRB_AP_ERR_SKEW || kret == KRB5KRB_AP_ERR_TKT_NYV) {
/*
* No reply in non-MUTUAL mode, but we don't know that its
Expand Down

0 comments on commit 545b5b4

Please sign in to comment.