Skip to content

Commit

Permalink
Convert k5-thread macros to functions
Browse files Browse the repository at this point in the history
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]
  • Loading branch information
SaharahSarah authored and greghudson committed Aug 24, 2016
1 parent 7b2cb7e commit 1793209
Show file tree
Hide file tree
Showing 3 changed files with 117 additions and 21 deletions.
31 changes: 11 additions & 20 deletions src/include/k5-thread.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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. */
Expand All @@ -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
Expand All @@ -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

Expand All @@ -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;
Expand All @@ -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);
Expand Down
5 changes: 5 additions & 0 deletions src/util/support/libkrb5support-fixed.exports
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
102 changes: 101 additions & 1 deletion src/util/support/threads.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 *);
Expand All @@ -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;
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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)
{
Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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 */

0 comments on commit 1793209

Please sign in to comment.