From 545b5b41cedb1f76565e541c68f0562e07ec78d5 Mon Sep 17 00:00:00 2001 From: Heath Kehoe Date: Fri, 19 Feb 2016 17:20:05 -0600 Subject: [PATCH] Fix race condition with global _gsskrb5_keytab 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 --- lib/gssapi/krb5/accept_sec_context.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/lib/gssapi/krb5/accept_sec_context.c b/lib/gssapi/krb5/accept_sec_context.c index ada03f5a5..3b85dcebe 100644 --- a/lib/gssapi/krb5/accept_sec_context.c +++ b/lib/gssapi/krb5/accept_sec_context.c @@ -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; /* @@ -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; } @@ -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; } @@ -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