From: Sarah Day Date: Mon, 8 Aug 2016 20:40:17 +0000 (-0400) Subject: Convert k5-thread macros to functions X-Git-Tag: krb5-1.15-beta1~72 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=17932091cc0d5981c5a78d389ffa4a5c7b532bd6;p=thirdparty%2Fkrb5.git Convert k5-thread macros to functions k5-thread.h has several pthread support calls defined as macros which conditionally call pthread functions. If a program is linked with libkrb5support and uses these macros, and the program isn't compiled with -fPIC, then it can crash if the pthread functions are linked at runtime (via LD_PRELOAD, for instance) but not at compile time. Convert the conditional macros to functions, so that libkrb5support is responsible for determining whether pthreads is loaded and for calling the pthreads functions if it is. [ghudson@mit.edu: clarified commit message, adjusted whitespace] --- diff --git a/src/include/k5-thread.h b/src/include/k5-thread.h index 0f0b8d57c0..b2e2e43289 100644 --- a/src/include/k5-thread.h +++ b/src/include/k5-thread.h @@ -241,12 +241,7 @@ typedef k5_os_nothread_mutex k5_os_mutex; If we find a platform with non-functional stubs and no weak references, we may have to resort to some hack like dlsym on the symbol tables of the current process. */ -extern int krb5int_pthread_loaded(void) -#ifdef __GNUC__ -/* We should always get the same answer for the life of the process. */ - __attribute__((const)) -#endif - ; + #if defined(HAVE_PRAGMA_WEAK_REF) && !defined(NO_WEAK_PTHREADS) # pragma weak pthread_once # pragma weak pthread_mutex_lock @@ -255,7 +250,6 @@ extern int krb5int_pthread_loaded(void) # pragma weak pthread_mutex_init # pragma weak pthread_self # pragma weak pthread_equal -# define K5_PTHREADS_LOADED (krb5int_pthread_loaded()) # define USE_PTHREAD_LOCK_ONLY_IF_LOADED /* Can't rely on useful stubs -- see above regarding Solaris. */ @@ -264,14 +258,11 @@ typedef struct { k5_os_nothread_once_t n; } k5_once_t; # define K5_ONCE_INIT { PTHREAD_ONCE_INIT, K5_OS_NOTHREAD_ONCE_INIT } -# define k5_once(O,F) (K5_PTHREADS_LOADED \ - ? pthread_once(&(O)->o,F) \ - : k5_os_nothread_once(&(O)->n,F)) +int k5_once(k5_once_t *once, void (*fn)(void)); #else /* no pragma weak support */ -# define K5_PTHREADS_LOADED (1) typedef pthread_once_t k5_once_t; # define K5_ONCE_INIT PTHREAD_ONCE_INIT @@ -295,15 +286,12 @@ typedef pthread_mutex_t k5_os_mutex; #ifdef USE_PTHREAD_LOCK_ONLY_IF_LOADED +# define USE_PTHREAD_LOADED_MUTEX_FUNCTIONS # define k5_os_mutex_finish_init(M) (0) -# define k5_os_mutex_init(M) \ - (K5_PTHREADS_LOADED ? pthread_mutex_init((M), 0) : 0) -# define k5_os_mutex_destroy(M) \ - (K5_PTHREADS_LOADED ? pthread_mutex_destroy((M)) : 0) -# define k5_os_mutex_lock(M) \ - (K5_PTHREADS_LOADED ? pthread_mutex_lock(M) : 0) -# define k5_os_mutex_unlock(M) \ - (K5_PTHREADS_LOADED ? pthread_mutex_unlock(M) : 0) +int k5_os_mutex_init(k5_os_mutex *m); +int k5_os_mutex_destroy(k5_os_mutex *m); +int k5_os_mutex_lock(k5_os_mutex *m); +int k5_os_mutex_unlock(k5_os_mutex *m); #else @@ -317,6 +305,8 @@ static inline int k5_os_mutex_finish_init(k5_os_mutex *m) { return 0; } #elif defined _WIN32 +# define k5_once_t k5_os_nothread_once_t + typedef struct { HANDLE h; int is_locked; @@ -332,8 +322,9 @@ typedef struct { ((M)->h = CreateMutex(NULL, FALSE, NULL)) ? 0 : GetLastError()) # define k5_os_mutex_destroy(M) \ (CloseHandle((M)->h) ? ((M)->h = 0, 0) : GetLastError()) +# define k5_os_mutex_lock k5_win_mutex_lock -static inline int k5_os_mutex_lock(k5_os_mutex *m) +static inline int k5_win_mutex_lock(k5_os_mutex *m) { DWORD res; res = WaitForSingleObject(m->h, INFINITE); diff --git a/src/util/support/libkrb5support-fixed.exports b/src/util/support/libkrb5support-fixed.exports index 1aa242803d..d5d4177b72 100644 --- a/src/util/support/libkrb5support-fixed.exports +++ b/src/util/support/libkrb5support-fixed.exports @@ -43,6 +43,11 @@ k5_json_string_create_base64 k5_json_string_create_len k5_json_string_unbase64 k5_json_string_utf8 +k5_os_mutex_init +k5_os_mutex_destroy +k5_os_mutex_lock +k5_os_mutex_unlock +k5_once k5_path_isabs k5_path_join k5_path_split diff --git a/src/util/support/threads.c b/src/util/support/threads.c index 3fd86ea8c2..d1170b11ef 100644 --- a/src/util/support/threads.c +++ b/src/util/support/threads.c @@ -32,6 +32,8 @@ MAKE_INIT_FUNCTION(krb5int_thread_support_init); MAKE_FINI_FUNCTION(krb5int_thread_support_fini); +#undef k5_once + #ifndef ENABLE_THREADS /* no thread support */ static void (*destructors[K5_KEY_MAX])(void *); @@ -44,6 +46,12 @@ int krb5int_pthread_loaded (void) return 0; } +int +k5_once(k5_once_t *once, void (*fn)(void)) +{ + return k5_os_nothread_once(once, fn); +} + #elif defined(_WIN32) static DWORD tls_idx; @@ -77,11 +85,16 @@ void krb5int_thread_detach_hook (void) } } -/* Stub function not used on Windows. */ +/* Stub functions not used on Windows. */ int krb5int_pthread_loaded (void) { return 0; } +int +k5_once(k5_once_t *once, void (*fn)(void)) +{ + return 0; +} #else /* POSIX threads */ /* Must support register/delete/register sequence, e.g., if krb5 is @@ -114,6 +127,7 @@ struct tsd_block { # pragma weak pthread_key_delete # pragma weak pthread_create # pragma weak pthread_join +# define K5_PTHREADS_LOADED (krb5int_pthread_loaded()) static volatile int flag_pthread_loaded = -1; static void loaded_test_aux(void) { @@ -162,13 +176,30 @@ int krb5int_pthread_loaded (void) of any system with non-functional stubs for those. */ return flag_pthread_loaded; } + +int +k5_once(k5_once_t *once, void (*fn)(void)) +{ + if (krb5int_pthread_loaded()) + return pthread_once(&once->o, fn); + else + return k5_os_nothread_once(&once->n, fn); +} + static struct tsd_block tsd_if_single; # define GET_NO_PTHREAD_TSD() (&tsd_if_single) #else +# define K5_PTHREADS_LOADED (1) int krb5int_pthread_loaded (void) { return 1; } + +int +k5_once(k5_once_t *once, void (*fn)(void)) +{ + return pthread_once(once, fn); +} # define GET_NO_PTHREAD_TSD() (abort(),(struct tsd_block *)0) #endif @@ -507,3 +538,72 @@ krb5int_mutex_unlock (k5_mutex_t *m) { k5_mutex_unlock (m); } + +#ifdef USE_PTHREAD_LOADED_MUTEX_FUNCTIONS + +int +k5_os_mutex_init(k5_os_mutex *m) +{ + if (krb5int_pthread_loaded()) + return pthread_mutex_init(m, 0); + else + return 0; +} + +int +k5_os_mutex_destroy(k5_os_mutex *m) +{ + if (krb5int_pthread_loaded()) + return pthread_mutex_destroy(m); + else + return 0; +} + +int +k5_os_mutex_lock(k5_os_mutex *m) +{ + if (krb5int_pthread_loaded()) + return pthread_mutex_lock(m); + else + return 0; +} + +int +k5_os_mutex_unlock(k5_os_mutex *m) +{ + if (krb5int_pthread_loaded()) + return pthread_mutex_unlock(m); + else + return 0; +} + +#else /* USE_PTHREAD_LOADED_MUTEX_FUNCTIONS */ + +#undef k5_os_mutex_init +#undef k5_os_mutex_destroy +#undef k5_os_mutex_lock +#undef k5_os_mutex_unlock + +/* Stub functions */ +int +k5_os_mutex_init(k5_os_mutex *m) +{ + return 0; +} +int +k5_os_mutex_destroy(k5_os_mutex *m) +{ + return 0; +} +int +k5_os_mutex_lock(k5_os_mutex *m) +{ + return 0; +} +int +k5_os_mutex_unlock(k5_os_mutex *m) +{ + return 0; +} + +#endif /* USE_PTHREAD_LOADED_MUTEX_FUNCTIONS */