1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-03 01:18:10 +03:00

third_party: Update uid_wrapper to version 1.3.0

This is mainly needed in order to have some interaction
with socket_wrapper 1.4.0 regarding the implementation
of syscall().

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>

Autobuild-User(master): Stefan Metzmacher <metze@samba.org>
Autobuild-Date(master): Wed Jan 18 12:47:48 UTC 2023 on sn-devel-184
This commit is contained in:
Stefan Metzmacher 2023-01-16 22:14:03 +01:00
parent 77110bc9e8
commit 25aa870fed

View File

@ -44,25 +44,6 @@
# define UWRAP_THREAD
#endif
# define UWRAP_LOCK(m) do { \
pthread_mutex_lock(&( m ## _mutex)); \
} while(0)
# define UWRAP_UNLOCK(m) do { \
pthread_mutex_unlock(&( m ## _mutex)); \
} while(0)
/* Add new global locks here please */
# 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)
#ifdef HAVE_CONSTRUCTOR_ATTRIBUTE
#define CONSTRUCTOR_ATTRIBUTE __attribute__ ((constructor))
#else
@ -142,6 +123,19 @@ enum uwrap_dbglvl_e {
UWRAP_LOG_TRACE
};
#ifndef HAVE_GETPROGNAME
static const char *getprogname(void)
{
#if defined(HAVE_PROGRAM_INVOCATION_SHORT_NAME)
return program_invocation_short_name;
#elif defined(HAVE_GETEXECNAME)
return getexecname();
#else
return NULL;
#endif /* HAVE_PROGRAM_INVOCATION_SHORT_NAME */
}
#endif /* HAVE_GETPROGNAME */
static void uwrap_log(enum uwrap_dbglvl_e dbglvl, const char *function, const char *format, ...) PRINTF_ATTRIBUTE(3, 4);
# define UWRAP_LOG(dbglvl, ...) uwrap_log((dbglvl), __func__, __VA_ARGS__)
@ -152,6 +146,7 @@ static void uwrap_log(enum uwrap_dbglvl_e dbglvl, const char *function, const ch
const char *d;
unsigned int lvl = 0;
const char *prefix = "UWRAP";
const char *progname = getprogname();
d = getenv("UID_WRAPPER_DEBUGLEVEL");
if (d != NULL) {
@ -181,9 +176,14 @@ static void uwrap_log(enum uwrap_dbglvl_e dbglvl, const char *function, const ch
break;
}
if (progname == NULL) {
progname = "<unknown>";
}
fprintf(stderr,
"%s(%d) - %s: %s\n",
"%s[%s (%u)] - %s: %s\n",
prefix,
progname,
(int)getpid(),
function,
buffer);
@ -240,6 +240,9 @@ typedef int (*__libc_getresgid)(gid_t *rgid, gid_t *egid, gid_t *sgid);
typedef gid_t (*__libc_getegid)(void);
typedef int (*__libc_getgroups)(int size, gid_t list[]);
#ifdef HAVE___GETGROUPS_CHK
typedef int (*__libc___getgroups_chk)(int size, gid_t list[], size_t listlen);
#endif
typedef int (*__libc_setgroups)(size_t size, const gid_t *list);
@ -285,6 +288,9 @@ struct uwrap_libc_symbols {
#endif
UWRAP_SYMBOL_ENTRY(getegid);
UWRAP_SYMBOL_ENTRY(getgroups);
#ifdef HAVE___GETGROUPS_CHK
UWRAP_SYMBOL_ENTRY(__getgroups_chk);
#endif
UWRAP_SYMBOL_ENTRY(setgroups);
#ifdef HAVE_SYSCALL
UWRAP_SYMBOL_ENTRY(syscall);
@ -292,6 +298,28 @@ struct uwrap_libc_symbols {
};
#undef UWRAP_SYMBOL_ENTRY
#define UWRAP_SYMBOL_ENTRY(i) \
union { \
__rtld_default_##i f; \
void *obj; \
} _rtld_default_##i
#ifdef HAVE_SYSCALL
typedef bool (*__rtld_default_socket_wrapper_syscall_valid)(long int sysno);
typedef long int (*__rtld_default_socket_wrapper_syscall_va)(long int sysno,
va_list va);
#endif
struct uwrap_rtld_default_symbols {
#ifdef HAVE_SYSCALL
UWRAP_SYMBOL_ENTRY(socket_wrapper_syscall_valid);
UWRAP_SYMBOL_ENTRY(socket_wrapper_syscall_va);
#else
uint8_t dummy;
#endif
};
#undef UWRAP_SYMBOL_ENTRY
/*****************
* LIBPTHREAD
*****************/
@ -341,6 +369,10 @@ struct uwrap {
struct uwrap_libc_symbols symbols;
} libc;
struct {
struct uwrap_rtld_default_symbols symbols;
} rtld_default;
struct {
void *handle;
struct uwrap_libpthread_symbols symbols;
@ -363,18 +395,127 @@ static UWRAP_THREAD struct uwrap_thread *uwrap_tls_id;
/* 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;
#define uwrap_init_mutex(m) _uwrap_init_mutex(m, #m)
static int _uwrap_init_mutex(pthread_mutex_t *m, const char *name)
{
pthread_mutexattr_t ma;
bool need_destroy = false;
int ret = 0;
/* The mutex for accessing the global libpthread.symbols */
static pthread_mutex_t libpthread_symbol_binding_mutex = PTHREAD_MUTEX_INITIALIZER;
#define __CHECK(cmd) \
do { \
ret = cmd; \
if (ret != 0) { \
UWRAP_LOG(UWRAP_LOG_ERROR, \
"%s: %s - failed %d", \
name, \
#cmd, \
ret); \
goto done; \
} \
} while (0)
*m = (pthread_mutex_t)PTHREAD_MUTEX_INITIALIZER;
__CHECK(pthread_mutexattr_init(&ma));
need_destroy = true;
__CHECK(pthread_mutexattr_settype(&ma, PTHREAD_MUTEX_ERRORCHECK));
__CHECK(pthread_mutex_init(m, &ma));
done:
if (need_destroy) {
pthread_mutexattr_destroy(&ma);
}
return ret;
}
#define uwrap_mutex_lock(m) _uwrap_mutex_lock(m, #m, __func__, __LINE__)
static void _uwrap_mutex_lock(pthread_mutex_t *mutex,
const char *name,
const char *caller,
unsigned line)
{
int ret;
ret = pthread_mutex_lock(mutex);
if (ret != 0) {
UWRAP_LOG(UWRAP_LOG_ERROR,
"PID(%d):PPID(%d): %s(%u): Couldn't lock pthread "
"mutex(%s) - %s",
getpid(),
getppid(),
caller,
line,
name,
strerror(ret));
abort();
}
}
#define uwrap_mutex_unlock(m) _uwrap_mutex_unlock(m, #m, __func__, __LINE__)
static void _uwrap_mutex_unlock(pthread_mutex_t *mutex,
const char *name,
const char *caller,
unsigned line)
{
int ret;
ret = pthread_mutex_unlock(mutex);
if (ret != 0) {
UWRAP_LOG(UWRAP_LOG_ERROR,
"PID(%d):PPID(%d): %s(%u): Couldn't unlock pthread "
"mutex(%s) - %s",
getpid(),
getppid(),
caller,
line,
name,
strerror(ret));
abort();
}
}
#define UWRAP_LOCK(m) \
do { \
uwrap_mutex_lock(&(m##_mutex)); \
} while (0)
#define UWRAP_UNLOCK(m) \
do { \
uwrap_mutex_unlock(&(m##_mutex)); \
} while (0)
/* Add new global locks here please */
#define UWRAP_REINIT_ALL \
do { \
int ret; \
ret = uwrap_init_mutex(&uwrap_id_mutex); \
if (ret != 0) \
exit(-1); \
} while (0)
/* Add new global locks here please */
#define UWRAP_LOCK_ALL \
do { \
UWRAP_LOCK(uwrap_id); \
} while (0)
#define UWRAP_UNLOCK_ALL \
do { \
UWRAP_UNLOCK(uwrap_id); \
} while (0)
/*********************************************************
* UWRAP PROTOTYPES
*********************************************************/
bool uid_wrapper_enabled(void);
#if ! defined(HAVE_CONSTRUCTOR_ATTRIBUTE) && defined(HAVE_PRAGMA_INIT)
/* xlC and other oldschool compilers support (only) this */
#pragma init (uwrap_constructor)
#endif
void uwrap_constructor(void) CONSTRUCTOR_ATTRIBUTE;
#if ! defined(HAVE_DESTRUCTOR_ATTRIBUTE) && defined(HAVE_PRAGMA_FINI)
#pragma fini (uwrap_destructor)
#endif
void uwrap_destructor(void) DESTRUCTOR_ATTRIBUTE;
/*********************************************************
@ -383,8 +524,6 @@ void uwrap_destructor(void) DESTRUCTOR_ATTRIBUTE;
enum uwrap_lib {
UWRAP_LIBC,
UWRAP_LIBNSL,
UWRAP_LIBSOCKET,
UWRAP_LIBPTHREAD,
};
@ -417,8 +556,6 @@ static void *uwrap_load_lib_handle(enum uwrap_lib lib)
#endif
switch (lib) {
case UWRAP_LIBNSL:
case UWRAP_LIBSOCKET:
case UWRAP_LIBC:
handle = uwrap.libc.handle;
if (handle == NULL) {
@ -445,7 +582,16 @@ static void *uwrap_load_lib_handle(enum uwrap_lib lib)
case UWRAP_LIBPTHREAD:
handle = uwrap.libpthread.handle;
if (handle == NULL) {
#ifdef RTLD_NEXT
/*
* Because thread sanatizer also overloads
* pthread_create() and pthread_exit() we need use
* RTLD_NEXT instead of libpthread.so.0
*/
handle = uwrap.libpthread.handle = RTLD_NEXT;
#else
handle = dlopen("libpthread.so.0", flags);
#endif
if (handle != NULL) {
break;
}
@ -455,7 +601,14 @@ static void *uwrap_load_lib_handle(enum uwrap_lib lib)
if (handle == NULL) {
#ifdef RTLD_NEXT
switch (lib) {
case UWRAP_LIBC:
handle = uwrap.libc.handle = RTLD_NEXT;
break;
case UWRAP_LIBPTHREAD:
handle = uwrap.libpthread.handle = RTLD_NEXT;
break;
}
#else
fprintf(stderr,
"Failed to dlopen library: %s\n",
@ -486,20 +639,74 @@ static void *_uwrap_bind_symbol(enum uwrap_lib lib, const char *fn_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(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)
}
#define uwrap_bind_symbol_rtld_default_optional(sym_name) \
if (uwrap.rtld_default.symbols._rtld_default_##sym_name.obj == NULL) { \
uwrap.rtld_default.symbols._rtld_default_##sym_name.obj = \
dlsym(RTLD_DEFAULT, #sym_name); \
}
/* 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);
uwrap_bind_symbol_rtld_default_optional(socket_wrapper_syscall_valid);
uwrap_bind_symbol_rtld_default_optional(socket_wrapper_syscall_va);
#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
@ -511,14 +718,14 @@ static void *_uwrap_bind_symbol(enum uwrap_lib lib, const char *fn_name)
*/
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();
}
@ -526,7 +733,7 @@ static uid_t libc_getuid(void)
#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);
}
@ -535,7 +742,7 @@ static int libc_seteuid(uid_t 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);
}
@ -544,7 +751,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_libc(setresuid);
uwrap_bind_symbol_all();
return uwrap.libc.symbols._libc_setresuid.f(ruid, euid, suid);
}
@ -553,7 +760,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_libc(getresuid);
uwrap_bind_symbol_all();
return uwrap.libc.symbols._libc_getresuid.f(ruid, euid, suid);
}
@ -561,21 +768,21 @@ static int libc_getresuid(uid_t *ruid, uid_t *euid, uid_t *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();
}
@ -583,7 +790,7 @@ static gid_t libc_getgid(void)
#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);
}
@ -592,7 +799,7 @@ static int libc_setegid(gid_t 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);
}
@ -601,7 +808,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_libc(setresgid);
uwrap_bind_symbol_all();
return uwrap.libc.symbols._libc_setresgid.f(rgid, egid, sgid);
}
@ -610,7 +817,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_libc(setresgid);
uwrap_bind_symbol_all();
return uwrap.libc.symbols._libc_getresgid.f(rgid, egid, sgid);
}
@ -618,21 +825,32 @@ static int libc_getresgid(gid_t *rgid, gid_t *egid, gid_t *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);
}
#ifdef HAVE___GETGROUPS_CHK
static int libc___getgroups_chk(int size, gid_t list[], size_t listlen)
{
uwrap_bind_symbol_libc(__getgroups_chk);
return uwrap.libc.symbols._libc___getgroups_chk.f(size,
list,
listlen);
}
#endif /* HAVE___GETGROUPS_CHK */
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);
}
@ -645,7 +863,7 @@ static long int libc_vsyscall(long int sysno, va_list va)
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);
@ -663,15 +881,57 @@ static long int libc_vsyscall(long int sysno, va_list va)
return rc;
}
static bool uwrap_swrap_syscall_valid(long int sysno)
{
uwrap_bind_symbol_all();
if (uwrap.rtld_default.symbols._rtld_default_socket_wrapper_syscall_valid.f == NULL) {
return false;
}
return uwrap.rtld_default.symbols._rtld_default_socket_wrapper_syscall_valid.f(
sysno);
}
DO_NOT_SANITIZE_ADDRESS_ATTRIBUTE
static long int uwrap_swrap_syscall_va(long int sysno, va_list va)
{
uwrap_bind_symbol_all();
if (uwrap.rtld_default.symbols._rtld_default_socket_wrapper_syscall_va.f == NULL) {
/*
* Fallback to libc, if socket_wrapper_vsyscall is not
* available.
*/
return libc_vsyscall(sysno, va);
}
return uwrap.rtld_default.symbols._rtld_default_socket_wrapper_syscall_va.f(
sysno,
va);
}
#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);
}
@ -711,18 +971,6 @@ void pthread_exit(void *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 *);
@ -928,6 +1176,12 @@ static void uwrap_thread_prepare(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 */
@ -964,9 +1218,10 @@ static void uwrap_thread_child(void)
struct uwrap_thread *id = uwrap_tls_id;
struct uwrap_thread *u = uwrap.ids;
UWRAP_REINIT_ALL;
/* uid_wrapper is loaded but not enabled */
if (id == NULL) {
UWRAP_UNLOCK_ALL;
return;
}
@ -993,8 +1248,6 @@ static void uwrap_thread_child(void)
uwrap_export_ids(id);
id->enabled = true;
UWRAP_UNLOCK_ALL;
}
static unsigned long uwrap_get_xid_from_env(const char *envname)
@ -2130,8 +2383,144 @@ int getgroups(int size, gid_t *list)
return uwrap_getgroups(size, list);
}
#ifdef HAVE___GETGROUPS_CHK
static int uwrap___getgroups_chk(int size, gid_t *list, size_t listlen)
{
if (size * sizeof(gid_t) > listlen) {
UWRAP_LOG(UWRAP_LOG_DEBUG, "Buffer overflow detected");
abort();
}
return uwrap_getgroups(size, list);
}
int __getgroups_chk(int size, gid_t *list, size_t listlen);
int __getgroups_chk(int size, gid_t *list, size_t listlen)
{
if (!uid_wrapper_enabled()) {
return libc___getgroups_chk(size, list, listlen);
}
uwrap_init();
return uwrap___getgroups_chk(size, list, listlen);
}
#endif /* HAVE___GETGROUPS_CHK */
#if (defined(HAVE_SYS_SYSCALL_H) || defined(HAVE_SYSCALL_H)) \
&& (defined(SYS_setreuid) || defined(SYS_setreuid32))
static bool uwrap_is_uwrap_related_syscall(long int sysno)
{
switch (sysno) {
/* gid */
#ifdef __alpha__
case SYS_getxgid:
return true;
#else
case SYS_getgid:
return true;
#endif
#ifdef HAVE_LINUX_32BIT_SYSCALLS
case SYS_getgid32:
return true;
#endif
#ifdef SYS_getegid
case SYS_getegid:
return true;
#ifdef HAVE_LINUX_32BIT_SYSCALLS
case SYS_getegid32:
return true;
#endif
#endif /* SYS_getegid */
case SYS_setgid:
return true;
#ifdef HAVE_LINUX_32BIT_SYSCALLS
case SYS_setgid32:
return true;
#endif
case SYS_setregid:
return true;
#ifdef HAVE_LINUX_32BIT_SYSCALLS
case SYS_setregid32:
return true;
#endif
#ifdef SYS_setresgid
case SYS_setresgid:
return true;
#ifdef HAVE_LINUX_32BIT_SYSCALLS
case SYS_setresgid32:
return true;
#endif
#endif /* SYS_setresgid */
#if defined(SYS_getresgid) && defined(HAVE_GETRESGID)
case SYS_getresgid:
return true;
#ifdef HAVE_LINUX_32BIT_SYSCALLS
case SYS_getresgid32:
return true;
#endif
#endif /* SYS_getresgid && HAVE_GETRESGID */
/* uid */
#ifdef __alpha__
case SYS_getxuid:
return true;
#else
case SYS_getuid:
return true;
#endif
#ifdef HAVE_LINUX_32BIT_SYSCALLS
case SYS_getuid32:
return true;
#endif
#ifdef SYS_geteuid
case SYS_geteuid:
return true;
#ifdef HAVE_LINUX_32BIT_SYSCALLS
case SYS_geteuid32:
return true;
#endif
#endif /* SYS_geteuid */
case SYS_setuid:
return true;
#ifdef HAVE_LINUX_32BIT_SYSCALLS
case SYS_setuid32:
return true;
#endif
case SYS_setreuid:
return true;
#ifdef HAVE_LINUX_32BIT_SYSCALLS
case SYS_setreuid32:
return true;
#endif
#ifdef SYS_setresuid
case SYS_setresuid:
return true;
#ifdef HAVE_LINUX_32BIT_SYSCALLS
case SYS_setresuid32:
return true;
#endif
#endif /* SYS_setresuid */
#if defined(SYS_getresuid) && defined(HAVE_GETRESUID)
case SYS_getresuid:
return true;
#ifdef HAVE_LINUX_32BIT_SYSCALLS
case SYS_getresuid32:
return true;
#endif
#endif /* SYS_getresuid && HAVE_GETRESUID*/
/* groups */
case SYS_setgroups:
return true;
#ifdef HAVE_LINUX_32BIT_SYSCALLS
case SYS_setgroups32:
return true;
#endif
default:
return false;
}
}
static long int uwrap_syscall (long int sysno, va_list vp)
{
long int rc;
@ -2295,11 +2684,8 @@ static long int uwrap_syscall (long int sysno, va_list vp)
}
break;
default:
UWRAP_LOG(UWRAP_LOG_DEBUG,
"UID_WRAPPER calling non-wrapped syscall %lu",
sysno);
rc = libc_vsyscall(sysno, vp);
rc = -1;
errno = ENOSYS;
break;
}
@ -2322,6 +2708,27 @@ long int syscall (long int sysno, ...)
va_start(va, sysno);
/*
* We need to check for uwrap related syscall numbers before calling
* uid_wrapper_enabled() otherwise we'd deadlock during the freebsd libc
* fork() which calls syscall() after invoking uwrap_thread_prepare().
*/
if (!uwrap_is_uwrap_related_syscall(sysno)) {
/*
* We need to give socket_wrapper a
* chance to take over...
*/
if (uwrap_swrap_syscall_valid(sysno)) {
rc = uwrap_swrap_syscall_va(sysno, va);
va_end(va);
return rc;
}
rc = libc_vsyscall(sysno, va);
va_end(va);
return rc;
}
if (!uid_wrapper_enabled()) {
rc = libc_vsyscall(sysno, va);
va_end(va);
@ -2334,6 +2741,39 @@ long int syscall (long int sysno, ...)
return rc;
}
/* used by socket_wrapper */
bool uid_wrapper_syscall_valid(long int sysno);
bool uid_wrapper_syscall_valid(long int sysno)
{
if (!uwrap_is_uwrap_related_syscall(sysno)) {
return false;
}
if (!uid_wrapper_enabled()) {
return false;
}
return true;
}
/* used by socket_wrapper */
long int uid_wrapper_syscall_va(long int sysno, va_list va);
long int uid_wrapper_syscall_va(long int sysno, va_list va)
{
if (!uwrap_is_uwrap_related_syscall(sysno)) {
errno = ENOSYS;
return -1;
}
if (!uid_wrapper_enabled()) {
return libc_vsyscall(sysno, va);
}
uwrap_init();
return uwrap_syscall(sysno, va);
}
#endif /* HAVE_SYSCALL */
#endif /* HAVE_SYS_SYSCALL_H || HAVE_SYSCALL_H */
@ -2364,6 +2804,8 @@ void uwrap_constructor(void)
}
glibc_malloc_lock_bug[0] = '\0';
UWRAP_REINIT_ALL;
/*
* If we hold a lock and the application forks, then the child
* is not able to unlock the mutex and we are in a deadlock.
@ -2405,11 +2847,19 @@ void uwrap_destructor(void)
}
if (uwrap.libc.handle != NULL) {
if (uwrap.libc.handle != NULL
#ifdef RTLD_NEXT
&& uwrap.libc.handle != RTLD_NEXT
#endif
) {
dlclose(uwrap.libc.handle);
}
if (uwrap.libpthread.handle != NULL) {
if (uwrap.libpthread.handle != NULL
#ifdef RTLD_NEXT
&& uwrap.libpthread.handle != RTLD_NEXT
#endif
) {
dlclose(uwrap.libpthread.handle);
}