From 0d092a739429610af4824c460171ac529601d1f5 Mon Sep 17 00:00:00 2001 From: Greg Hudson Date: Fri, 16 Oct 2020 11:35:18 -0400 Subject: Unregister thread key in SPNEGO finalization Commit d160bc733a3dbeb6d84f4e175234ff18738d9f66 (ticket 7045) added a new thread key K5_KEY_GSS_SPNEGO_STATUS and registered it in SPNEGO library initialization, but neglected to unregister it in finalization. As a result, loading, unloading, and reloading libgssapi_krb5 could throw an assertion failure if libkrb5support remained loaded. Unregister the key in SPNEGO finalization and add a test case. Reported and investigated by Adam Dabrowski. (cherry picked from commit 07ff54d0bb85109df114612bbbfa6559f4a1e0cb) ticket: 8614 tags: pullup target_version: 1.18-next target_version: 1.17-next --- .gitignore | 1 + src/lib/gssapi/spnego/spnego_mech.c | 1 + src/tests/gssapi/Makefile.in | 11 +++-- src/tests/gssapi/deps | 2 + src/tests/gssapi/reload.c | 83 +++++++++++++++++++++++++++++++++++++ 5 files changed, 94 insertions(+), 4 deletions(-) create mode 100644 src/tests/gssapi/reload.c diff --git a/.gitignore b/.gitignore index ae1c262..30da36d 100644 --- a/.gitignore +++ b/.gitignore @@ -471,6 +471,7 @@ local.properties /src/tests/gssapi/ccinit /src/tests/gssapi/ccrefresh +/src/tests/gssapi/reload /src/tests/gssapi/t_accname /src/tests/gssapi/t_add_cred /src/tests/gssapi/t_ccselect diff --git a/src/lib/gssapi/spnego/spnego_mech.c b/src/lib/gssapi/spnego/spnego_mech.c index ec0bae6..0d2a2c9 100644 --- a/src/lib/gssapi/spnego/spnego_mech.c +++ b/src/lib/gssapi/spnego/spnego_mech.c @@ -324,6 +324,7 @@ int gss_spnegoint_lib_init(void) void gss_spnegoint_lib_fini(void) { + k5_key_delete(K5_KEY_GSS_SPNEGO_STATUS); } static OM_uint32 diff --git a/src/tests/gssapi/Makefile.in b/src/tests/gssapi/Makefile.in index 5cc1e0f..22a2f94 100644 --- a/src/tests/gssapi/Makefile.in +++ b/src/tests/gssapi/Makefile.in @@ -8,7 +8,7 @@ LOCALINCLUDES = -I$(srcdir)/../../lib/gssapi/mechglue \ -I$(srcdir)/../../lib/gssapi/generic -I../../lib/gssapi/krb5 \ -I../../lib/gssapi/generic -SRCS= $(srcdir)/ccinit.c $(srcdir)/ccrefresh.c $(srcdir)/common.c \ +SRCS= $(srcdir)/ccinit.c $(srcdir)/ccrefresh.c $(srcdir)/common.c $(srcdir)/reload.c \ $(srcdir)/t_accname.c $(srcdir)/t_add_cred.c $(srcdir)/t_ccselect.c \ $(srcdir)/t_ciflags.c $(srcdir)/t_context.c $(srcdir)/t_credstore.c \ $(srcdir)/t_enctypes.c $(srcdir)/t_err.c $(srcdir)/t_export_cred.c \ @@ -21,7 +21,7 @@ SRCS= $(srcdir)/ccinit.c $(srcdir)/ccrefresh.c $(srcdir)/common.c \ $(srcdir)/t_s4u2proxy_krb5.c $(srcdir)/t_saslname.c \ $(srcdir)/t_spnego.c $(srcdir)/t_srcattrs.c -OBJS= ccinit.o ccrefresh.o common.o t_accname.o t_add_cred.o t_ccselect.o \ +OBJS= ccinit.o ccrefresh.o common.o reload.o t_accname.o t_add_cred.o t_ccselect.o \ t_ciflags.o t_context.o t_credstore.o t_enctypes.o t_err.o \ t_export_cred.o t_export_name.o t_gssexts.o t_imp_cred.o t_imp_name.o \ t_invalid.o t_inq_cred.o t_inq_ctx.o t_inq_mechs_name.o t_iov.o \ @@ -37,11 +37,12 @@ all: ccinit ccrefresh t_accname t_add_cred t_ccselect t_ciflags t_context \ t_iov t_lifetime t_namingexts t_oid t_pcontok t_prf t_s4u \ t_s4u2proxy_krb5 t_saslname t_spnego t_srcattrs -check-unix: t_oid +check-unix: t_oid reload $(RUN_TEST) ./t_invalid $(RUN_TEST) ./t_oid $(RUN_TEST) ./t_prf $(RUN_TEST) ./t_imp_name + if [ -r $(TOPLIBD)/libgssapi_krb5.so ]; then $(RUN_TEST) ./reload; fi check-pytests: ccinit ccrefresh t_accname t_add_cred t_ccselect t_ciflags \ t_context t_credstore t_enctypes t_err t_export_cred t_export_name \ @@ -60,6 +61,8 @@ ccinit: ccinit.o $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o ccinit ccinit.o $(KRB5_BASE_LIBS) ccrefresh: ccrefresh.o $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o ccrefresh ccrefresh.o $(KRB5_BASE_LIBS) +reload: reload.o + $(CC_LINK) -o $@ reload.o $(DL_LIB) t_accname: t_accname.o $(COMMON_DEPS) $(CC_LINK) -o $@ t_accname.o $(COMMON_LIBS) t_add_cred: t_add_cred.o $(COMMON_DEPS) @@ -118,7 +121,7 @@ t_srcattrs: t_srcattrs.o $(COMMON_DEPS) $(CC_LINK) -o $@ t_srcattrs.o $(COMMON_LIBS) clean: - $(RM) ccinit ccrefresh t_accname t_add_cred t_ccselect t_ciflags + $(RM) ccinit ccrefresh reload t_accname t_add_cred t_ccselect t_ciflags $(RM) t_context t_credstore t_enctypes t_err t_export_cred $(RM) t_export_name t_gssexts t_imp_cred t_imp_name t_invalid $(RM) t_inq_cred t_inq_ctx t_inq_mechs_name t_iov t_lifetime diff --git a/src/tests/gssapi/deps b/src/tests/gssapi/deps index acd0e96..55586de 100644 --- a/src/tests/gssapi/deps +++ b/src/tests/gssapi/deps @@ -25,6 +25,8 @@ $(OUTPRE)common.$(OBJEXT): $(BUILDTOP)/include/gssapi/gssapi.h \ $(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/gssapi/gssapi_krb5.h \ $(BUILDTOP)/include/krb5/krb5.h $(COM_ERR_DEPS) $(top_srcdir)/include/krb5.h \ common.c common.h +$(OUTPRE)reload.$(OBJEXT): $(BUILDTOP)/include/gssapi/gssapi.h \ + reload.c $(OUTPRE)t_accname.$(OBJEXT): $(BUILDTOP)/include/gssapi/gssapi.h \ $(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/gssapi/gssapi_krb5.h \ $(BUILDTOP)/include/krb5/krb5.h $(COM_ERR_DEPS) $(top_srcdir)/include/krb5.h \ diff --git a/src/tests/gssapi/reload.c b/src/tests/gssapi/reload.c new file mode 100644 index 0000000..4fe3565 --- /dev/null +++ b/src/tests/gssapi/reload.c @@ -0,0 +1,83 @@ +/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ +/* tests/gssapi/reload.c - test loading libgssapi_krb5 twice */ +/* + * Copyright (C) 2020 by the Massachusetts Institute of Technology. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * This is a regression test for ticket #8614. It ensures that libgssapi_krb5 + * can be loaded multiple times in the same process when libkrb5support is held + * open by another library. + */ + +#include +#include +#include +#include + +/* Load libgssapi_krb5, briefly use it (to force the initializer to run), and + * close it. */ +static void +load_gssapi(void) +{ + void *gssapi; + OM_uint32 (*indmechs)(OM_uint32 *, gss_OID_set *); + OM_uint32 (*reloidset)(OM_uint32 *, gss_OID_set *); + OM_uint32 major, minor; + gss_OID_set mechs; + + gssapi = dlopen("libgssapi_krb5.so", RTLD_NOW | RTLD_LOCAL); + assert(gssapi != NULL); + indmechs = dlsym(gssapi, "gss_indicate_mechs"); + reloidset = dlsym(gssapi, "gss_release_oid_set"); + assert(indmechs != NULL && reloidset != NULL); + major = (*indmechs)(&minor, &mechs); + assert(major == 0); + (*reloidset)(&minor, &mechs); + dlclose(gssapi); +} + +int +main() +{ + void *support; + + /* Hold open libkrb5support to ensure that thread-local state remains */ + support = dlopen("libkrb5support.so", RTLD_NOW | RTLD_LOCAL); + if (support == NULL) { + fprintf(stderr, "Error loading libkrb5support: %s\n", dlerror()); + return 1; + } + + load_gssapi(); + load_gssapi(); + + dlclose(support); + return 0; +} -- cgit v1.1