summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorRobin Hack <hack.robin@gmail.com>2015-01-23 15:30:03 +0100
committerAndreas Schneider <asn@cryptomilk.org>2015-01-28 17:17:08 +0100
commita5b70c0e5fe70fe69e5294ddeadd8981dda9afb0 (patch)
tree5d0b5f6e5149b2cb0f7e27500456738c622784ad /lib
parent526c1d514740956c9a9f6d83f99ceeca476130a8 (diff)
downloadsamba-a5b70c0e5fe70fe69e5294ddeadd8981dda9afb0.tar.gz
samba-a5b70c0e5fe70fe69e5294ddeadd8981dda9afb0.tar.xz
samba-a5b70c0e5fe70fe69e5294ddeadd8981dda9afb0.zip
uwrap: Prepare for overload of libpthread functions.
uwrap_bind_symbol are now renamed to uwrap_bind_symbol_libc and simlilar uwrap_bind_symbol_libpthread are introduced. Signed-off-by: Robin Hack <hack.robin@gmail.com> Reviewed-by: Andreas Schneider <asn@samba.org> Reviewed-by: Stefan Metzmacher <metze@samba.org>
Diffstat (limited to 'lib')
-rw-r--r--lib/uid_wrapper/uid_wrapper.c159
1 files changed, 140 insertions, 19 deletions
diff --git a/lib/uid_wrapper/uid_wrapper.c b/lib/uid_wrapper/uid_wrapper.c
index b04e334cac..84ed83cec3 100644
--- a/lib/uid_wrapper/uid_wrapper.c
+++ b/lib/uid_wrapper/uid_wrapper.c
@@ -55,8 +55,10 @@
# define UWRAP_LOCK_ALL \
UWRAP_LOCK(uwrap_id); \
UWRAP_LOCK(libc_symbol_binding); \
+ UWRAP_LOCK(libpthread_symbol_binding)
# define UWRAP_UNLOCK_ALL \
+ UWRAP_UNLOCK(libpthread_symbol_binding); \
UWRAP_UNLOCK(libc_symbol_binding); \
UWRAP_UNLOCK(uwrap_id)
@@ -281,6 +283,29 @@ struct uwrap_libc_symbols {
UWRAP_SYMBOL_ENTRY(syscall);
#endif
};
+#undef UWRAP_SYMBOL_ENTRY
+
+/*****************
+ * LIBPTHREAD
+ *****************/
+/* Yeah... I'm pig. I overloading macro here... So what? */
+#define UWRAP_SYMBOL_ENTRY(i) \
+ union { \
+ __libpthread_##i f; \
+ void *obj; \
+ } _libpthread_##i
+
+typedef int (*__libpthread_pthread_create)(pthread_t *thread,
+ const pthread_attr_t *attr,
+ void *(*start_routine) (void *),
+ void *arg);
+typedef void (*__libpthread_pthread_exit)(void *retval);
+
+struct uwrap_libpthread_symbols {
+ UWRAP_SYMBOL_ENTRY(pthread_create);
+ UWRAP_SYMBOL_ENTRY(pthread_exit);
+};
+#undef UWRAP_SYMBOL_ENTRY
/*
* We keep the virtualised euid/egid/groups information here
@@ -312,6 +337,11 @@ struct uwrap {
struct uwrap_libc_symbols symbols;
} libc;
+ struct {
+ void *handle;
+ struct uwrap_libpthread_symbols symbols;
+ } libpthread;
+
bool initialised;
bool enabled;
@@ -344,6 +374,9 @@ 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
*********************************************************/
@@ -360,6 +393,7 @@ enum uwrap_lib {
UWRAP_LIBC,
UWRAP_LIBNSL,
UWRAP_LIBSOCKET,
+ UWRAP_LIBPTHREAD,
};
static void *uwrap_load_lib_handle(enum uwrap_lib lib)
@@ -393,6 +427,15 @@ static void *uwrap_load_lib_handle(enum uwrap_lib lib)
uwrap.libc.handle = handle;
}
break;
+ case UWRAP_LIBPTHREAD:
+ handle = uwrap.libpthread.handle;
+ if (handle == NULL) {
+ handle = dlopen("libpthread.so.0", flags);
+ if (handle != NULL) {
+ break;
+ }
+ }
+ break;
}
if (handle == NULL) {
@@ -427,14 +470,22 @@ static void *_uwrap_bind_symbol(enum uwrap_lib lib, const char *fn_name)
return func;
}
-#define uwrap_bind_symbol(lib, sym_name) \
+#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(lib, #sym_name); \
+ _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)
+
/*
* IMPORTANT
*
@@ -445,14 +496,14 @@ static void *_uwrap_bind_symbol(enum uwrap_lib lib, const char *fn_name)
*/
static int libc_setuid(uid_t uid)
{
- uwrap_bind_symbol(UWRAP_LIBC, setuid);
+ uwrap_bind_symbol_libc(setuid);
return uwrap.libc.symbols._libc_setuid.f(uid);
}
static uid_t libc_getuid(void)
{
- uwrap_bind_symbol(UWRAP_LIBC, getuid);
+ uwrap_bind_symbol_libc(getuid);
return uwrap.libc.symbols._libc_getuid.f();
}
@@ -460,7 +511,7 @@ static uid_t libc_getuid(void)
#ifdef HAVE_SETEUID
static int libc_seteuid(uid_t euid)
{
- uwrap_bind_symbol(UWRAP_LIBC, seteuid);
+ uwrap_bind_symbol_libc(seteuid);
return uwrap.libc.symbols._libc_seteuid.f(euid);
}
@@ -469,7 +520,7 @@ static int libc_seteuid(uid_t euid)
#ifdef HAVE_SETREUID
static int libc_setreuid(uid_t ruid, uid_t euid)
{
- uwrap_bind_symbol(UWRAP_LIBC, setreuid);
+ uwrap_bind_symbol_libc(setreuid);
return uwrap.libc.symbols._libc_setreuid.f(ruid, euid);
}
@@ -478,7 +529,7 @@ static int libc_setreuid(uid_t ruid, uid_t euid)
#ifdef HAVE_SETRESUID
static int libc_setresuid(uid_t ruid, uid_t euid, uid_t suid)
{
- uwrap_bind_symbol(UWRAP_LIBC, setresuid);
+ uwrap_bind_symbol_libc(setresuid);
return uwrap.libc.symbols._libc_setresuid.f(ruid, euid, suid);
}
@@ -487,7 +538,7 @@ static int libc_setresuid(uid_t ruid, uid_t euid, uid_t suid)
#ifdef HAVE_GETRESUID
static int libc_getresuid(uid_t *ruid, uid_t *euid, uid_t *suid)
{
- uwrap_bind_symbol(UWRAP_LIBC, getresuid);
+ uwrap_bind_symbol_libc(getresuid);
return uwrap.libc.symbols._libc_getresuid.f(ruid, euid, suid);
}
@@ -495,21 +546,21 @@ static int libc_getresuid(uid_t *ruid, uid_t *euid, uid_t *suid)
static uid_t libc_geteuid(void)
{
- uwrap_bind_symbol(UWRAP_LIBC, geteuid);
+ uwrap_bind_symbol_libc(geteuid);
return uwrap.libc.symbols._libc_geteuid.f();
}
static int libc_setgid(gid_t gid)
{
- uwrap_bind_symbol(UWRAP_LIBC, setgid);
+ uwrap_bind_symbol_libc(setgid);
return uwrap.libc.symbols._libc_setgid.f(gid);
}
static gid_t libc_getgid(void)
{
- uwrap_bind_symbol(UWRAP_LIBC, getgid);
+ uwrap_bind_symbol_libc(getgid);
return uwrap.libc.symbols._libc_getgid.f();
}
@@ -517,7 +568,7 @@ static gid_t libc_getgid(void)
#ifdef HAVE_SETEGID
static int libc_setegid(gid_t egid)
{
- uwrap_bind_symbol(UWRAP_LIBC, setegid);
+ uwrap_bind_symbol_libc(setegid);
return uwrap.libc.symbols._libc_setegid.f(egid);
}
@@ -526,7 +577,7 @@ static int libc_setegid(gid_t egid)
#ifdef HAVE_SETREGID
static int libc_setregid(gid_t rgid, gid_t egid)
{
- uwrap_bind_symbol(UWRAP_LIBC, setregid);
+ uwrap_bind_symbol_libc(setregid);
return uwrap.libc.symbols._libc_setregid.f(rgid, egid);
}
@@ -535,7 +586,7 @@ static int libc_setregid(gid_t rgid, gid_t egid)
#ifdef HAVE_SETRESGID
static int libc_setresgid(gid_t rgid, gid_t egid, gid_t sgid)
{
- uwrap_bind_symbol(UWRAP_LIBC, setresgid);
+ uwrap_bind_symbol_libc(setresgid);
return uwrap.libc.symbols._libc_setresgid.f(rgid, egid, sgid);
}
@@ -544,7 +595,7 @@ static int libc_setresgid(gid_t rgid, gid_t egid, gid_t sgid)
#ifdef HAVE_GETRESGID
static int libc_getresgid(gid_t *rgid, gid_t *egid, gid_t *sgid)
{
- uwrap_bind_symbol(UWRAP_LIBC, setresgid);
+ uwrap_bind_symbol_libc(setresgid);
return uwrap.libc.symbols._libc_getresgid.f(rgid, egid, sgid);
}
@@ -552,21 +603,21 @@ static int libc_getresgid(gid_t *rgid, gid_t *egid, gid_t *sgid)
static gid_t libc_getegid(void)
{
- uwrap_bind_symbol(UWRAP_LIBC, getegid);
+ uwrap_bind_symbol_libc(getegid);
return uwrap.libc.symbols._libc_getegid.f();
}
static int libc_getgroups(int size, gid_t list[])
{
- uwrap_bind_symbol(UWRAP_LIBC, getgroups);
+ uwrap_bind_symbol_libc(getgroups);
return uwrap.libc.symbols._libc_getgroups.f(size, list);
}
static int libc_setgroups(size_t size, const gid_t *list)
{
- uwrap_bind_symbol(UWRAP_LIBC, setgroups);
+ uwrap_bind_symbol_libc(setgroups);
return uwrap.libc.symbols._libc_setgroups.f(size, list);
}
@@ -579,7 +630,7 @@ static long int libc_vsyscall(long int sysno, va_list va)
long int rc;
int i;
- uwrap_bind_symbol(UWRAP_LIBC, syscall);
+ uwrap_bind_symbol_libc(syscall);
for (i = 0; i < 8; i++) {
args[i] = va_arg(va, long int);
@@ -599,6 +650,72 @@ static long int libc_vsyscall(long int sysno, va_list va)
}
#endif
+/*
+ * 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.libpthread.symbols._libpthread_pthread_exit.f(retval);
+}
+
+static void uwrap_pthread_exit(void *retval)
+{
+ libpthread_pthread_exit(retval);
+}
+
+void pthread_exit(void *retval)
+{
+ if (!uid_wrapper_enabled()) {
+ libpthread_pthread_exit(retval);
+ };
+
+ uwrap_pthread_exit(retval);
+
+ /* Calm down gcc warning. */
+ 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);
+}
+
+static int uwrap_pthread_create(pthread_t *thread,
+ const pthread_attr_t *attr,
+ void *(*start_routine) (void *),
+ void *arg)
+{
+ return libpthread_pthread_create(thread, attr, start_routine, arg);
+}
+
+int pthread_create(pthread_t *thread,
+ const pthread_attr_t *attr,
+ void *(*start_routine) (void *),
+ void *arg)
+{
+ if (!uid_wrapper_enabled()) {
+ return libpthread_pthread_create(thread,
+ attr,
+ start_routine,
+ arg);
+ };
+
+ return uwrap_pthread_create(thread,
+ attr,
+ start_routine,
+ arg);
+}
+
/*********************************************************
* UWRAP ID HANDLING
*********************************************************/
@@ -1649,5 +1766,9 @@ void uwrap_destructor(void)
dlclose(uwrap.libc.handle);
}
+ if (uwrap.libpthread.handle != NULL) {
+ dlclose(uwrap.libpthread.handle);
+ }
+
UWRAP_UNLOCK_ALL;
}