#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;
}
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;
}
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)) {
+ rc = libc_vsyscall(sysno, va);
+ va_end(va);
+ return rc;
+ }
+
if (!uid_wrapper_enabled()) {
rc = libc_vsyscall(sysno, va);
va_end(va);