/* Add new global locks here please */
# define UWRAP_LOCK_ALL \
- UWRAP_LOCK(uwrap_id); \
- UWRAP_LOCK(libc_symbol_binding); \
- UWRAP_LOCK(libpthread_symbol_binding)
+ UWRAP_LOCK(uwrap_id)
# define UWRAP_UNLOCK_ALL \
- UWRAP_UNLOCK(libpthread_symbol_binding); \
- UWRAP_UNLOCK(libc_symbol_binding); \
UWRAP_UNLOCK(uwrap_id)
#ifdef HAVE_CONSTRUCTOR_ATTRIBUTE
/* The mutex or accessing the id */
static pthread_mutex_t uwrap_id_mutex = PTHREAD_MUTEX_INITIALIZER;
-/* The mutex for accessing the global libc.symbols */
-static pthread_mutex_t libc_symbol_binding_mutex = PTHREAD_MUTEX_INITIALIZER;
-/* The mutex for accessing the global libpthread.symbols */
-static pthread_mutex_t libpthread_symbol_binding_mutex = PTHREAD_MUTEX_INITIALIZER;
/*********************************************************
* UWRAP PROTOTYPES
}
#define uwrap_bind_symbol_libc(sym_name) \
- UWRAP_LOCK(libc_symbol_binding); \
if (uwrap.libc.symbols._libc_##sym_name.obj == NULL) { \
uwrap.libc.symbols._libc_##sym_name.obj = \
_uwrap_bind_symbol(UWRAP_LIBC, #sym_name); \
- } \
- UWRAP_UNLOCK(libc_symbol_binding)
+ }
#define uwrap_bind_symbol_libpthread(sym_name) \
- UWRAP_LOCK(libpthread_symbol_binding); \
if (uwrap.libpthread.symbols._libpthread_##sym_name.obj == NULL) { \
uwrap.libpthread.symbols._libpthread_##sym_name.obj = \
_uwrap_bind_symbol(UWRAP_LIBPTHREAD, #sym_name); \
- } \
- UWRAP_UNLOCK(libpthread_symbol_binding)
+ }
+
+/* DO NOT call this function during library initialization! */
+static void __uwrap_bind_symbol_all_once(void)
+{
+ uwrap_bind_symbol_libc(setuid);
+ uwrap_bind_symbol_libc(getuid);
+#ifdef HAVE_SETEUID
+ uwrap_bind_symbol_libc(seteuid);
+#endif
+#ifdef HAVE_SETREUID
+ uwrap_bind_symbol_libc(setreuid);
+#endif
+#ifdef HAVE_SETRESUID
+ uwrap_bind_symbol_libc(setresuid);
+#endif
+#ifdef HAVE_GETRESUID
+ uwrap_bind_symbol_libc(getresuid);
+#endif
+ uwrap_bind_symbol_libc(geteuid);
+ uwrap_bind_symbol_libc(setgid);
+ uwrap_bind_symbol_libc(getgid);
+#ifdef HAVE_SETEGID
+ uwrap_bind_symbol_libc(setegid);
+#endif
+#ifdef HAVE_SETREGID
+ uwrap_bind_symbol_libc(setregid);
+#endif
+
+#ifdef HAVE_SETRESGID
+ uwrap_bind_symbol_libc(setresgid);
+#endif
+#ifdef HAVE_GETRESGID
+ uwrap_bind_symbol_libc(setresgid);
+#endif
+ uwrap_bind_symbol_libc(getegid);
+ uwrap_bind_symbol_libc(getgroups);
+ uwrap_bind_symbol_libc(setgroups);
+#ifdef HAVE_SYSCALL
+ uwrap_bind_symbol_libc(syscall);
+#endif
+ uwrap_bind_symbol_libpthread(pthread_create);
+ uwrap_bind_symbol_libpthread(pthread_exit);
+}
+
+static void uwrap_bind_symbol_all(void)
+{
+ static pthread_once_t all_symbol_binding_once = PTHREAD_ONCE_INIT;
+
+ pthread_once(&all_symbol_binding_once, __uwrap_bind_symbol_all_once);
+}
/*
* IMPORTANT
*/
static int libc_setuid(uid_t uid)
{
- uwrap_bind_symbol_libc(setuid);
+ uwrap_bind_symbol_all();
return uwrap.libc.symbols._libc_setuid.f(uid);
}
static uid_t libc_getuid(void)
{
- uwrap_bind_symbol_libc(getuid);
+ uwrap_bind_symbol_all();
return uwrap.libc.symbols._libc_getuid.f();
}
#ifdef HAVE_SETEUID
static int libc_seteuid(uid_t euid)
{
- uwrap_bind_symbol_libc(seteuid);
+ uwrap_bind_symbol_all();
return uwrap.libc.symbols._libc_seteuid.f(euid);
}
#ifdef HAVE_SETREUID
static int libc_setreuid(uid_t ruid, uid_t euid)
{
- uwrap_bind_symbol_libc(setreuid);
+ uwrap_bind_symbol_all();
return uwrap.libc.symbols._libc_setreuid.f(ruid, euid);
}
#ifdef HAVE_SETRESUID
static int libc_setresuid(uid_t ruid, uid_t euid, uid_t suid)
{
- uwrap_bind_symbol_libc(setresuid);
+ uwrap_bind_symbol_all();
return uwrap.libc.symbols._libc_setresuid.f(ruid, euid, suid);
}
#ifdef HAVE_GETRESUID
static int libc_getresuid(uid_t *ruid, uid_t *euid, uid_t *suid)
{
- uwrap_bind_symbol_libc(getresuid);
+ uwrap_bind_symbol_all();
return uwrap.libc.symbols._libc_getresuid.f(ruid, euid, suid);
}
static uid_t libc_geteuid(void)
{
- uwrap_bind_symbol_libc(geteuid);
+ uwrap_bind_symbol_all();
return uwrap.libc.symbols._libc_geteuid.f();
}
static int libc_setgid(gid_t gid)
{
- uwrap_bind_symbol_libc(setgid);
+ uwrap_bind_symbol_all();
return uwrap.libc.symbols._libc_setgid.f(gid);
}
static gid_t libc_getgid(void)
{
- uwrap_bind_symbol_libc(getgid);
+ uwrap_bind_symbol_all();
return uwrap.libc.symbols._libc_getgid.f();
}
#ifdef HAVE_SETEGID
static int libc_setegid(gid_t egid)
{
- uwrap_bind_symbol_libc(setegid);
+ uwrap_bind_symbol_all();
return uwrap.libc.symbols._libc_setegid.f(egid);
}
#ifdef HAVE_SETREGID
static int libc_setregid(gid_t rgid, gid_t egid)
{
- uwrap_bind_symbol_libc(setregid);
+ uwrap_bind_symbol_all();
return uwrap.libc.symbols._libc_setregid.f(rgid, egid);
}
#ifdef HAVE_SETRESGID
static int libc_setresgid(gid_t rgid, gid_t egid, gid_t sgid)
{
- uwrap_bind_symbol_libc(setresgid);
+ uwrap_bind_symbol_all();
return uwrap.libc.symbols._libc_setresgid.f(rgid, egid, sgid);
}
#ifdef HAVE_GETRESGID
static int libc_getresgid(gid_t *rgid, gid_t *egid, gid_t *sgid)
{
- uwrap_bind_symbol_libc(setresgid);
+ uwrap_bind_symbol_all();
return uwrap.libc.symbols._libc_getresgid.f(rgid, egid, sgid);
}
static gid_t libc_getegid(void)
{
- uwrap_bind_symbol_libc(getegid);
+ uwrap_bind_symbol_all();
return uwrap.libc.symbols._libc_getegid.f();
}
static int libc_getgroups(int size, gid_t list[])
{
- uwrap_bind_symbol_libc(getgroups);
+ uwrap_bind_symbol_all();
return uwrap.libc.symbols._libc_getgroups.f(size, list);
}
static int libc_setgroups(size_t size, const gid_t *list)
{
- uwrap_bind_symbol_libc(setgroups);
+ uwrap_bind_symbol_all();
return uwrap.libc.symbols._libc_setgroups.f(size, list);
}
long int rc;
int i;
- uwrap_bind_symbol_libc(syscall);
+ uwrap_bind_symbol_all();
for (i = 0; i < 8; i++) {
args[i] = va_arg(va, long int);
}
#endif
+static int libpthread_pthread_create(pthread_t *thread,
+ const pthread_attr_t *attr,
+ void *(*start_routine) (void *),
+ void *arg)
+{
+ uwrap_bind_symbol_all();
+ return uwrap.libpthread.symbols._libpthread_pthread_create.f(thread,
+ attr,
+ start_routine,
+ arg);
+}
+
/*
* This part is "optimistic".
* Thread can ends without pthread_exit call.
*/
static void libpthread_pthread_exit(void *retval)
{
- uwrap_bind_symbol_libpthread(pthread_exit);
+ uwrap_bind_symbol_all();
uwrap.libpthread.symbols._libpthread_pthread_exit.f(retval);
}
exit(666);
}
-static int libpthread_pthread_create(pthread_t *thread,
- const pthread_attr_t *attr,
- void *(*start_routine) (void *),
- void *arg)
-{
- uwrap_bind_symbol_libpthread(pthread_create);
- return uwrap.libpthread.symbols._libpthread_pthread_create.f(thread,
- attr,
- start_routine,
- arg);
-}
-
struct uwrap_pthread_create_args {
struct uwrap_thread *id;
void *(*start_routine) (void *);
{
struct uwrap_thread *id = uwrap_tls_id;
+ /*
+ * We bind all symbols to avoid deadlocks of the fork is interrupted by
+ * a signal handler using a symbol of this library.
+ */
+ uwrap_bind_symbol_all();
+
UWRAP_LOCK_ALL;
/* uid_wrapper is loaded but not enabled */