2 * Copyright (c) 2009 Andrew Tridgell
3 * Copyright (c) 2011-2013 Andreas Schneider <asn@samba.org>
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
27 #include <sys/types.h>
30 #ifdef HAVE_SYS_SYSCALL_H
31 #include <sys/syscall.h>
40 #ifdef HAVE_GCC_THREAD_LOCAL_STORAGE
41 # define UWRAP_THREAD __thread
46 #ifdef HAVE_DESTRUCTOR_ATTRIBUTE
47 #define DESTRUCTOR_ATTRIBUTE __attribute__ ((destructor))
49 #define DESTRUCTOR_ATTRIBUTE
50 #endif /* HAVE_DESTRUCTOR_ATTRIBUTE */
52 /* GCC have printf type attribute check. */
53 #ifdef HAVE_FUNCTION_ATTRIBUTE_FORMAT
54 #define PRINTF_ATTRIBUTE(a,b) __attribute__ ((__format__ (__printf__, a, b)))
56 #define PRINTF_ATTRIBUTE(a,b)
57 #endif /* HAVE_FUNCTION_ATTRIBUTE_FORMAT */
59 #define UWRAP_DLIST_ADD(list,item) do { \
61 (item)->prev = NULL; \
62 (item)->next = NULL; \
65 (item)->prev = NULL; \
66 (item)->next = (list); \
67 (list)->prev = (item); \
72 #define UWRAP_DLIST_REMOVE(list,item) do { \
73 if ((list) == (item)) { \
74 (list) = (item)->next; \
76 (list)->prev = NULL; \
80 (item)->prev->next = (item)->next; \
83 (item)->next->prev = (item)->prev; \
86 (item)->prev = NULL; \
87 (item)->next = NULL; \
91 #define SAFE_FREE(x) do { if ((x) != NULL) {free(x); (x)=NULL;} } while(0)
106 # define UWRAP_LOG(...)
108 static void uwrap_log(enum uwrap_dbglvl_e dbglvl
, const char *format
, ...) PRINTF_ATTRIBUTE(2, 3);
109 # define UWRAP_LOG(dbglvl, ...) uwrap_log((dbglvl), __VA_ARGS__)
111 static void uwrap_log(enum uwrap_dbglvl_e dbglvl
, const char *format
, ...)
116 unsigned int lvl
= 0;
118 d
= getenv("UID_WRAPPER_DEBUGLEVEL");
123 va_start(va
, format
);
124 vsnprintf(buffer
, sizeof(buffer
), format
, va
);
129 case UWRAP_LOG_ERROR
:
131 "UWRAP_ERROR(%d): %s\n",
132 (int)getpid(), buffer
);
136 "UWRAP_WARN(%d): %s\n",
137 (int)getpid(), buffer
);
139 case UWRAP_LOG_DEBUG
:
141 "UWRAP_DEBUG(%d): %s\n",
142 (int)getpid(), buffer
);
144 case UWRAP_LOG_TRACE
:
146 "UWRAP_TRACE(%d): %s\n",
147 (int)getpid(), buffer
);
158 #define LIBC_NAME "libc.so"
160 struct uwrap_libc_fns
{
161 int (*_libc_setuid
)(uid_t uid
);
162 uid_t (*_libc_getuid
)(void);
165 int (*_libc_seteuid
)(uid_t euid
);
168 int (*_libc_setreuid
)(uid_t ruid
, uid_t euid
);
170 #ifdef HAVE_SETRESUID
171 int (*_libc_setresuid
)(uid_t ruid
, uid_t euid
, uid_t suid
);
173 uid_t (*_libc_geteuid
)(void);
175 int (*_libc_setgid
)(gid_t gid
);
176 gid_t (*_libc_getgid
)(void);
178 int (*_libc_setegid
)(uid_t egid
);
181 int (*_libc_setregid
)(uid_t rgid
, uid_t egid
);
183 #ifdef HAVE_SETRESGID
184 int (*_libc_setresgid
)(uid_t rgid
, uid_t egid
, uid_t sgid
);
186 gid_t (*_libc_getegid
)(void);
187 int (*_libc_getgroups
)(int size
, gid_t list
[]);
188 int (*_libc_setgroups
)(size_t size
, const gid_t
*list
);
190 long int (*_libc_syscall
)(long int sysno
, ...);
195 * We keep the virtualised euid/egid/groups information here
197 struct uwrap_thread
{
212 struct uwrap_thread
*next
;
213 struct uwrap_thread
*prev
;
219 struct uwrap_libc_fns fns
;
228 struct uwrap_thread
*ids
;
231 static struct uwrap uwrap
;
233 /* Shortcut to the list item */
234 static UWRAP_THREAD
struct uwrap_thread
*uwrap_tls_id
;
236 /* The mutex or accessing the id */
237 static pthread_mutex_t uwrap_id_mutex
= PTHREAD_MUTEX_INITIALIZER
;
239 /*********************************************************
241 *********************************************************/
243 bool uid_wrapper_enabled(void);
244 void uwrap_destructor(void) DESTRUCTOR_ATTRIBUTE
;
246 /*********************************************************
247 * UWRAP LIBC LOADER FUNCTIONS
248 *********************************************************/
256 static void *uwrap_load_lib_handle(enum uwrap_lib lib
)
258 int flags
= RTLD_LAZY
;
263 flags
|= RTLD_DEEPBIND
;
269 case UWRAP_LIBSOCKET
:
272 handle
= uwrap
.libc
.handle
;
273 if (handle
== NULL
) {
274 for (handle
= NULL
, i
= 10; handle
== NULL
&& i
>= 0; i
--) {
275 char soname
[256] = {0};
277 snprintf(soname
, sizeof(soname
), "libc.so.%d", i
);
278 handle
= dlopen(soname
, flags
);
281 uwrap
.libc
.handle
= handle
;
286 if (handle
== NULL
) {
288 handle
= uwrap
.libc
.handle
= RTLD_NEXT
;
291 "Failed to dlopen library: %s\n",
300 static void *_uwrap_load_lib_function(enum uwrap_lib lib
, const char *fn_name
)
305 handle
= uwrap_load_lib_handle(lib
);
307 func
= dlsym(handle
, fn_name
);
310 "Failed to find %s: %s\n",
318 #define uwrap_load_lib_function(lib, fn_name) \
319 if (uwrap.libc.fns._libc_##fn_name == NULL) { \
320 *(void **) (&uwrap.libc.fns._libc_##fn_name) = \
321 _uwrap_load_lib_function(lib, #fn_name); \
327 * Functions expeciall from libc need to be loaded individually, you can't load
328 * all at once or gdb will segfault at startup. The same applies to valgrind and
329 * has probably something todo with with the linker.
330 * So we need load each function at the point it is called the first time.
332 static int libc_setuid(uid_t uid
)
334 uwrap_load_lib_function(UWRAP_LIBC
, setuid
);
336 return uwrap
.libc
.fns
._libc_setuid(uid
);
339 static uid_t
libc_getuid(void)
341 uwrap_load_lib_function(UWRAP_LIBC
, getuid
);
343 return uwrap
.libc
.fns
._libc_getuid();
347 static int libc_seteuid(uid_t euid
)
349 uwrap_load_lib_function(UWRAP_LIBC
, seteuid
);
351 return uwrap
.libc
.fns
._libc_seteuid(euid
);
356 static int libc_setreuid(uid_t ruid
, uid_t euid
)
358 uwrap_load_lib_function(UWRAP_LIBC
, setreuid
);
360 return uwrap
.libc
.fns
._libc_setreuid(ruid
, euid
);
364 #ifdef HAVE_SETRESUID
365 static int libc_setresuid(uid_t ruid
, uid_t euid
, uid_t suid
)
367 uwrap_load_lib_function(UWRAP_LIBC
, setresuid
);
369 return uwrap
.libc
.fns
._libc_setresuid(ruid
, euid
, suid
);
373 static uid_t
libc_geteuid(void)
375 uwrap_load_lib_function(UWRAP_LIBC
, geteuid
);
377 return uwrap
.libc
.fns
._libc_geteuid();
380 static int libc_setgid(gid_t gid
)
382 uwrap_load_lib_function(UWRAP_LIBC
, setgid
);
384 return uwrap
.libc
.fns
._libc_setgid(gid
);
387 static gid_t
libc_getgid(void)
389 uwrap_load_lib_function(UWRAP_LIBC
, getgid
);
391 return uwrap
.libc
.fns
._libc_getgid();
395 static int libc_setegid(gid_t egid
)
397 uwrap_load_lib_function(UWRAP_LIBC
, setegid
);
399 return uwrap
.libc
.fns
._libc_setegid(egid
);
404 static int libc_setregid(gid_t rgid
, gid_t egid
)
406 uwrap_load_lib_function(UWRAP_LIBC
, setregid
);
408 return uwrap
.libc
.fns
._libc_setregid(rgid
, egid
);
412 #ifdef HAVE_SETRESGID
413 static int libc_setresgid(gid_t rgid
, gid_t egid
, gid_t sgid
)
415 uwrap_load_lib_function(UWRAP_LIBC
, setresgid
);
417 return uwrap
.libc
.fns
._libc_setresgid(rgid
, egid
, sgid
);
421 static gid_t
libc_getegid(void)
423 uwrap_load_lib_function(UWRAP_LIBC
, getegid
);
425 return uwrap
.libc
.fns
._libc_getegid();
428 static int libc_getgroups(int size
, gid_t list
[])
430 uwrap_load_lib_function(UWRAP_LIBC
, getgroups
);
432 return uwrap
.libc
.fns
._libc_getgroups(size
, list
);
435 static int libc_setgroups(size_t size
, const gid_t
*list
)
437 uwrap_load_lib_function(UWRAP_LIBC
, setgroups
);
439 return uwrap
.libc
.fns
._libc_setgroups(size
, list
);
443 static long int libc_vsyscall(long int sysno
, va_list va
)
449 uwrap_load_lib_function(UWRAP_LIBC
, syscall
);
451 for (i
= 0; i
< 8; i
++) {
452 args
[i
] = va_arg(va
, long int);
455 rc
= uwrap
.libc
.fns
._libc_syscall(sysno
,
469 /*********************************************************
471 *********************************************************/
473 static struct uwrap_thread
*find_uwrap_id(pthread_t tid
)
475 struct uwrap_thread
*id
;
477 for (id
= uwrap
.ids
; id
; id
= id
->next
) {
478 if (pthread_equal(id
->tid
, tid
)) {
486 static int uwrap_new_id(pthread_t tid
, bool do_alloc
)
488 struct uwrap_thread
*id
= uwrap_tls_id
;
491 id
= malloc(sizeof(struct uwrap_thread
));
493 UWRAP_LOG(UWRAP_LOG_ERROR
, "Unable to allocate memory");
498 id
->groups
= malloc(sizeof(gid_t
) * 1);
499 if (id
->groups
== NULL
) {
500 UWRAP_LOG(UWRAP_LOG_ERROR
, "Unable to allocate memory");
506 UWRAP_DLIST_ADD(uwrap
.ids
, id
);
513 id
->ruid
= id
->euid
= id
->suid
= uwrap
.myuid
;
514 id
->rgid
= id
->egid
= id
->sgid
= uwrap
.mygid
;
517 id
->groups
[0] = uwrap
.mygid
;
522 static void uwrap_thread_prepare(void)
524 pthread_mutex_lock(&uwrap_id_mutex
);
527 * What happens if another atfork prepare functions calls a uwrap
528 * function? So disable it in case another atfork prepare function
529 * calls a (s)uid function.
531 uwrap
.enabled
= false;
534 static void uwrap_thread_parent(void)
536 uwrap
.enabled
= true;
538 pthread_mutex_unlock(&uwrap_id_mutex
);
541 static void uwrap_thread_child(void)
543 uwrap
.enabled
= true;
545 pthread_mutex_unlock(&uwrap_id_mutex
);
548 static void uwrap_init(void)
550 const char *env
= getenv("UID_WRAPPER");
551 pthread_t tid
= pthread_self();
555 if (uwrap
.initialised
) {
556 struct uwrap_thread
*id
= uwrap_tls_id
;
563 pthread_mutex_lock(&uwrap_id_mutex
);
564 id
= find_uwrap_id(tid
);
566 rc
= uwrap_new_id(tid
, true);
571 /* We reuse an old thread id */
574 uwrap_new_id(tid
, false);
576 pthread_mutex_unlock(&uwrap_id_mutex
);
581 UWRAP_LOG(UWRAP_LOG_DEBUG
, "Initialize uid_wrapper");
584 * If we hold a lock and the application forks, then the child
585 * is not able to unlock the mutex and we are in a deadlock.
586 * This should prevent such deadlocks.
588 pthread_atfork(&uwrap_thread_prepare
,
589 &uwrap_thread_parent
,
590 &uwrap_thread_child
);
592 pthread_mutex_lock(&uwrap_id_mutex
);
594 uwrap
.initialised
= true;
595 uwrap
.enabled
= false;
597 if (env
!= NULL
&& env
[0] == '1') {
598 const char *root
= getenv("UID_WRAPPER_ROOT");
601 /* put us in one group */
602 if (root
!= NULL
&& root
[0] == '1') {
606 uwrap
.myuid
= libc_geteuid();
607 uwrap
.mygid
= libc_getegid();
610 rc
= uwrap_new_id(tid
, true);
615 uwrap
.enabled
= true;
617 UWRAP_LOG(UWRAP_LOG_DEBUG
,
618 "Enabled uid_wrapper as %s",
619 uwrap
.myuid
== 0 ? "root" : "user");
622 pthread_mutex_unlock(&uwrap_id_mutex
);
624 UWRAP_LOG(UWRAP_LOG_DEBUG
, "Succeccfully initialized uid_wrapper");
627 bool uid_wrapper_enabled(void)
631 return uwrap
.enabled
? true : false;
634 static int uwrap_setresuid_thread(uid_t ruid
, uid_t euid
, uid_t suid
)
636 struct uwrap_thread
*id
= uwrap_tls_id
;
638 if (ruid
== (uid_t
)-1 && euid
== (uid_t
)-1 && suid
== (uid_t
)-1) {
643 pthread_mutex_lock(&uwrap_id_mutex
);
644 if (ruid
!= (uid_t
)-1) {
648 if (euid
!= (uid_t
)-1) {
652 if (suid
!= (uid_t
)-1) {
655 pthread_mutex_unlock(&uwrap_id_mutex
);
660 static int uwrap_setresuid(uid_t ruid
, uid_t euid
, uid_t suid
)
662 struct uwrap_thread
*id
;
664 if (ruid
== (uid_t
)-1 && euid
== (uid_t
)-1 && suid
== (uid_t
)-1) {
669 pthread_mutex_lock(&uwrap_id_mutex
);
670 for (id
= uwrap
.ids
; id
; id
= id
->next
) {
675 if (ruid
!= (uid_t
)-1) {
679 if (euid
!= (uid_t
)-1) {
683 if (suid
!= (uid_t
)-1) {
687 pthread_mutex_unlock(&uwrap_id_mutex
);
695 int setuid(uid_t uid
)
697 if (!uid_wrapper_enabled()) {
698 return libc_setuid(uid
);
701 return uwrap_setresuid(uid
, -1, -1);
705 int seteuid(uid_t euid
)
707 if (euid
== (uid_t
)-1) {
712 if (!uid_wrapper_enabled()) {
713 return libc_seteuid(euid
);
716 return uwrap_setresuid(-1, euid
, -1);
721 int setreuid(uid_t ruid
, uid_t euid
)
723 if (ruid
== (uid_t
)-1 && euid
== (uid_t
)-1) {
728 if (!uid_wrapper_enabled()) {
729 return libc_setreuid(ruid
, euid
);
732 return uwrap_setresuid(ruid
, euid
, -1);
736 #ifdef HAVE_SETRESUID
737 int setresuid(uid_t ruid
, uid_t euid
, uid_t suid
)
739 if (!uid_wrapper_enabled()) {
740 return libc_setresuid(ruid
, euid
, suid
);
743 return uwrap_setresuid(ruid
, euid
, suid
);
750 static uid_t
uwrap_getuid(void)
752 struct uwrap_thread
*id
= uwrap_tls_id
;
755 pthread_mutex_lock(&uwrap_id_mutex
);
757 pthread_mutex_unlock(&uwrap_id_mutex
);
764 if (!uid_wrapper_enabled()) {
765 return libc_getuid();
768 return uwrap_getuid();
774 static uid_t
uwrap_geteuid(void)
776 const char *env
= getenv("UID_WRAPPER_MYUID");
777 struct uwrap_thread
*id
= uwrap_tls_id
;
780 pthread_mutex_lock(&uwrap_id_mutex
);
782 pthread_mutex_unlock(&uwrap_id_mutex
);
784 /* Disable root and return myuid */
785 if (env
!= NULL
&& env
[0] == '1') {
794 if (!uid_wrapper_enabled()) {
795 return libc_geteuid();
798 return uwrap_geteuid();
801 static int uwrap_setresgid_thread(gid_t rgid
, gid_t egid
, gid_t sgid
)
803 struct uwrap_thread
*id
= uwrap_tls_id
;
805 if (rgid
== (gid_t
)-1 && egid
== (gid_t
)-1 && sgid
== (gid_t
)-1) {
810 pthread_mutex_lock(&uwrap_id_mutex
);
811 if (rgid
!= (gid_t
)-1) {
815 if (egid
!= (gid_t
)-1) {
819 if (sgid
!= (gid_t
)-1) {
822 pthread_mutex_unlock(&uwrap_id_mutex
);
827 static int uwrap_setresgid(gid_t rgid
, gid_t egid
, gid_t sgid
)
829 struct uwrap_thread
*id
;
831 if (rgid
== (gid_t
)-1 && egid
== (gid_t
)-1 && sgid
== (gid_t
)-1) {
836 pthread_mutex_lock(&uwrap_id_mutex
);
837 for (id
= uwrap
.ids
; id
; id
= id
->next
) {
842 if (rgid
!= (gid_t
)-1) {
846 if (egid
!= (gid_t
)-1) {
850 if (sgid
!= (gid_t
)-1) {
854 pthread_mutex_unlock(&uwrap_id_mutex
);
862 int setgid(gid_t gid
)
864 if (!uid_wrapper_enabled()) {
865 return libc_setgid(gid
);
868 return uwrap_setresgid(gid
, -1, -1);
872 int setegid(gid_t egid
)
874 if (!uid_wrapper_enabled()) {
875 return libc_setegid(egid
);
878 return uwrap_setresgid(-1, egid
, -1);
883 int setregid(gid_t rgid
, gid_t egid
)
885 if (!uid_wrapper_enabled()) {
886 return libc_setregid(rgid
, egid
);
889 return uwrap_setresgid(rgid
, egid
, -1);
893 #ifdef HAVE_SETRESGID
894 int setresgid(gid_t rgid
, gid_t egid
, gid_t sgid
)
896 if (!uid_wrapper_enabled()) {
897 return libc_setresgid(rgid
, egid
, sgid
);
900 return uwrap_setresgid(rgid
, egid
, sgid
);
907 static gid_t
uwrap_getgid(void)
909 struct uwrap_thread
*id
= uwrap_tls_id
;
912 pthread_mutex_lock(&uwrap_id_mutex
);
914 pthread_mutex_unlock(&uwrap_id_mutex
);
921 if (!uid_wrapper_enabled()) {
922 return libc_getgid();
925 return uwrap_getgid();
931 static uid_t
uwrap_getegid(void)
933 struct uwrap_thread
*id
= uwrap_tls_id
;
936 pthread_mutex_lock(&uwrap_id_mutex
);
938 pthread_mutex_unlock(&uwrap_id_mutex
);
945 if (!uid_wrapper_enabled()) {
946 return libc_getegid();
949 return uwrap_getegid();
952 static int uwrap_setgroups_thread(size_t size
, const gid_t
*list
)
954 struct uwrap_thread
*id
= uwrap_tls_id
;
957 pthread_mutex_lock(&uwrap_id_mutex
);
963 } else if (size
> 0) {
966 tmp
= realloc(id
->groups
, sizeof(gid_t
) * size
);
974 memcpy(id
->groups
, list
, size
* sizeof(gid_t
));
979 pthread_mutex_unlock(&uwrap_id_mutex
);
984 static int uwrap_setgroups(size_t size
, const gid_t
*list
)
986 struct uwrap_thread
*id
;
989 pthread_mutex_lock(&uwrap_id_mutex
);
992 for (id
= uwrap
.ids
; id
; id
= id
->next
) {
997 } else if (size
> 0) {
998 for (id
= uwrap
.ids
; id
; id
= id
->next
) {
1001 tmp
= realloc(id
->groups
, sizeof(gid_t
) * size
);
1009 memcpy(id
->groups
, list
, size
* sizeof(gid_t
));
1015 pthread_mutex_unlock(&uwrap_id_mutex
);
1020 #ifdef HAVE_SETGROUPS_INT
1021 int setgroups(int size
, const gid_t
*list
)
1023 int setgroups(size_t size
, const gid_t
*list
)
1026 if (!uid_wrapper_enabled()) {
1027 return libc_setgroups(size
, list
);
1030 return uwrap_setgroups(size
, list
);
1033 static int uwrap_getgroups(int size
, gid_t
*list
)
1035 struct uwrap_thread
*id
= uwrap_tls_id
;
1038 pthread_mutex_lock(&uwrap_id_mutex
);
1039 ngroups
= id
->ngroups
;
1041 if (size
> ngroups
) {
1047 if (size
< ngroups
) {
1051 memcpy(list
, id
->groups
, size
* sizeof(gid_t
));
1054 pthread_mutex_unlock(&uwrap_id_mutex
);
1059 int getgroups(int size
, gid_t
*list
)
1061 if (!uid_wrapper_enabled()) {
1062 return libc_getgroups(size
, list
);
1065 return uwrap_getgroups(size
, list
);
1068 #if (defined(HAVE_SYS_SYSCALL_H) || defined(HAVE_SYSCALL_H)) \
1069 && (defined(SYS_setreuid) || defined(SYS_setreuid32))
1070 static long int uwrap_syscall (long int sysno
, va_list vp
)
1077 #ifdef HAVE_LINUX_32BIT_SYSCALLS
1081 rc
= uwrap_getgid();
1086 #ifdef HAVE_LINUX_32BIT_SYSCALLS
1090 rc
= uwrap_getegid();
1093 #endif /* SYS_getegid */
1095 #ifdef HAVE_LINUX_32BIT_SYSCALLS
1099 gid_t gid
= (gid_t
) va_arg(vp
, int);
1101 rc
= uwrap_setresgid_thread(gid
, -1, -1);
1105 #ifdef HAVE_LINUX_32BIT_SYSCALLS
1106 case SYS_setregid32
:
1109 uid_t rgid
= (uid_t
) va_arg(vp
, int);
1110 uid_t egid
= (uid_t
) va_arg(vp
, int);
1112 rc
= uwrap_setresgid_thread(rgid
, egid
, -1);
1115 #ifdef SYS_setresgid
1117 #ifdef HAVE_LINUX_32BIT_SYSCALLS
1118 case SYS_setresgid32
:
1121 uid_t rgid
= (uid_t
) va_arg(vp
, int);
1122 uid_t egid
= (uid_t
) va_arg(vp
, int);
1123 uid_t sgid
= (uid_t
) va_arg(vp
, int);
1125 rc
= uwrap_setresgid_thread(rgid
, egid
, sgid
);
1128 #endif /* SYS_setresgid */
1132 #ifdef HAVE_LINUX_32BIT_SYSCALLS
1136 rc
= uwrap_getuid();
1141 #ifdef HAVE_LINUX_32BIT_SYSCALLS
1145 rc
= uwrap_geteuid();
1148 #endif /* SYS_geteuid */
1150 #ifdef HAVE_LINUX_32BIT_SYSCALLS
1154 uid_t uid
= (uid_t
) va_arg(vp
, int);
1156 rc
= uwrap_setresuid_thread(uid
, -1, -1);
1160 #ifdef HAVE_LINUX_32BIT_SYSCALLS
1161 case SYS_setreuid32
:
1164 uid_t ruid
= (uid_t
) va_arg(vp
, int);
1165 uid_t euid
= (uid_t
) va_arg(vp
, int);
1167 rc
= uwrap_setresuid_thread(ruid
, euid
, -1);
1170 #ifdef SYS_setresuid
1172 #ifdef HAVE_LINUX_32BIT_SYSCALLS
1173 case SYS_setresuid32
:
1176 uid_t ruid
= (uid_t
) va_arg(vp
, int);
1177 uid_t euid
= (uid_t
) va_arg(vp
, int);
1178 uid_t suid
= (uid_t
) va_arg(vp
, int);
1180 rc
= uwrap_setresuid_thread(ruid
, euid
, suid
);
1183 #endif /* SYS_setresuid */
1187 #ifdef HAVE_LINUX_32BIT_SYSCALLS
1188 case SYS_setgroups32
:
1191 size_t size
= (size_t) va_arg(vp
, size_t);
1192 gid_t
*list
= (gid_t
*) va_arg(vp
, int *);
1194 rc
= uwrap_setgroups_thread(size
, list
);
1198 UWRAP_LOG(UWRAP_LOG_DEBUG
,
1199 "UID_WRAPPER calling non-wrapped syscall %lu\n",
1202 rc
= libc_vsyscall(sysno
, vp
);
1210 #ifdef HAVE_SYSCALL_INT
1211 int syscall (int sysno
, ...)
1213 long int syscall (long int sysno
, ...)
1216 #ifdef HAVE_SYSCALL_INT
1223 va_start(va
, sysno
);
1225 if (!uid_wrapper_enabled()) {
1226 rc
= libc_vsyscall(sysno
, va
);
1231 rc
= uwrap_syscall(sysno
, va
);
1236 #endif /* HAVE_SYSCALL */
1237 #endif /* HAVE_SYS_SYSCALL_H || HAVE_SYSCALL_H */
1239 /****************************
1241 ***************************/
1244 * This function is called when the library is unloaded and makes sure that
1245 * resources are freed.
1247 void uwrap_destructor(void)
1249 struct uwrap_thread
*u
= uwrap
.ids
;
1251 pthread_mutex_lock(&uwrap_id_mutex
);
1253 UWRAP_DLIST_REMOVE(uwrap
.ids
, u
);
1255 SAFE_FREE(u
->groups
);
1260 pthread_mutex_unlock(&uwrap_id_mutex
);
1262 if (uwrap
.libc
.handle
!= NULL
) {
1263 dlclose(uwrap
.libc
.handle
);